Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Anchor peer API and other refractoring #120

Merged
merged 3 commits into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hlf.java.rest.client.controller;

import hlf.java.rest.client.model.AnchorPeerParamsDTO;
import hlf.java.rest.client.model.ClientResponseModel;
import hlf.java.rest.client.model.CommitChannelParamsDTO;
import hlf.java.rest.client.model.NewOrgParamsDTO;
Expand Down Expand Up @@ -105,7 +106,6 @@ public ResponseEntity<ClientResponseModel> addOrgToChannel(
@RequestBody @Validated NewOrgParamsDTO organizationDetails) {
return networkStatus.addOrgToChannel(channelName, organizationDetails);
}

/**
* Use to decode an base64 encoded json file, with options to also decode the interior elements
* and/or print the output in a cleaner format
Expand All @@ -126,4 +126,21 @@ public ResponseEntity<ClientResponseModel> getDeserializedJson(
@RequestParam(name = "prettyPrint", required = true) boolean prettyPrint) {
return serializationUtil.decodeContents(encodedJson, decodeInterior, prettyPrint);
}

/**
* Add anchor peer(s) of an organization to a channel. Anchor peer addition should be done once
* the peer nodes of the organization have joined the channel.
*
* @param channelName - the name of the channel for which you wish to add the anchor peer nodes
* to.
* @param anchorPeerParamsDTO - contains the details for the organization peers you wish to be
* added to the channel as anchor peer.
* @return ResponseEntity<ClientResponseModel> - contains the result of the operation.
*/
@PostMapping(value = "/channel/{channelName}/add_anchor_peer")
public ResponseEntity<ClientResponseModel> addAnchorPeersToChannel(
nidhi-singh02 marked this conversation as resolved.
Show resolved Hide resolved
@PathVariable @Validated String channelName,
@RequestBody @Validated AnchorPeerParamsDTO anchorPeerParamsDTO) {
return networkStatus.addAnchorPeersToChannel(channelName, anchorPeerParamsDTO);
}
}
10 changes: 10 additions & 0 deletions src/main/java/hlf/java/rest/client/model/AnchorPeerParamsDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package hlf.java.rest.client.model;

import java.util.List;
import lombok.Data;

@Data
public class AnchorPeerParamsDTO {
nidhi-singh02 marked this conversation as resolved.
Show resolved Hide resolved
private String organizationMspId;
private List<AnchorPeerDTO> anchorPeerDTOs;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package hlf.java.rest.client.service;

import hlf.java.rest.client.exception.ServiceException;
import hlf.java.rest.client.model.AnchorPeerParamsDTO;
import org.hyperledger.fabric.protos.common.Configtx.ConfigGroup;

public interface AddAnchorPeerToChannelWriteSetBuilder {
nidhi-singh02 marked this conversation as resolved.
Show resolved Hide resolved

ConfigGroup buildWriteSetForAnchorPeers(
ConfigGroup readset, AnchorPeerParamsDTO anchorPeerParamsDTO) throws ServiceException;
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package hlf.java.rest.client.service;

import hlf.java.rest.client.model.AnchorPeerParamsDTO;
import hlf.java.rest.client.model.ClientResponseModel;
import hlf.java.rest.client.model.CommitChannelParamsDTO;
import hlf.java.rest.client.model.NewOrgParamsDTO;
Expand All @@ -20,4 +21,7 @@ ResponseEntity<ClientResponseModel> commitChannelConfigTransaction(

ResponseEntity<ClientResponseModel> addOrgToChannel(
String channelName, NewOrgParamsDTO organizationDetails);

ResponseEntity<ClientResponseModel> addAnchorPeersToChannel(
String channelName, AnchorPeerParamsDTO anchorPeerParamsDTO);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package hlf.java.rest.client.service.impl;

import hlf.java.rest.client.exception.ServiceException;
import hlf.java.rest.client.model.AnchorPeerDTO;
import hlf.java.rest.client.model.AnchorPeerParamsDTO;
import hlf.java.rest.client.service.AddAnchorPeerToChannelWriteSetBuilder;
import hlf.java.rest.client.util.FabricChannelUtil;
import hlf.java.rest.client.util.FabricClientConstants;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hyperledger.fabric.protos.common.Configtx.ConfigGroup;
import org.hyperledger.fabric.protos.common.Configtx.ConfigValue;
import org.hyperledger.fabric.protos.peer.Configuration.AnchorPeer;
import org.hyperledger.fabric.protos.peer.Configuration.AnchorPeers;
import org.springframework.stereotype.Service;

@Service
nidhi-singh02 marked this conversation as resolved.
Show resolved Hide resolved
public class AddAnchorPeerToChannelWriteSetBuilderImpl
implements AddAnchorPeerToChannelWriteSetBuilder {

private AnchorPeerParamsDTO anchorPeerParamsDTO;

@Override
public ConfigGroup buildWriteSetForAnchorPeers(
ConfigGroup readset, AnchorPeerParamsDTO anchorPeerParamsDTO) throws ServiceException {
this.anchorPeerParamsDTO = anchorPeerParamsDTO;
String orgMspId = anchorPeerParamsDTO.getOrganizationMspId();
Map<String, ConfigGroup> existingOrganizations =
FabricChannelUtil.getExistingOrgsFromReadset(readset);
// The "Application" group
ConfigGroup applicationGroup =
ConfigGroup.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.putAllPolicies(FabricChannelUtil.setApplicationPolicies(readset))
.putGroups(orgMspId, setAnchorPeerInGroup(orgMspId, readset))
// putAllGroups excludes new organization
.putAllGroups(existingOrganizations)
// Application group version
.setVersion(
FabricChannelUtil.retrieveMSPGroupVersionFromReadset(
readset, FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION)
+ 1) // will be tied to current version + 1 for this level
.build();
// the "/Channel" group
return ConfigGroup.newBuilder()
.putGroups(FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION, applicationGroup)
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
// Channel group version
.setVersion(readset.getVersion())
.build();
}

private ConfigGroup setAnchorPeerInGroup(String orgMspId, ConfigGroup readSet) {
Map<String, ConfigValue> valueMap = new HashMap<>();
if (anchorPeerParamsDTO.getAnchorPeerDTOs() != null) {
valueMap.put(
FabricClientConstants.CHANNEL_CONFIG_GROUP_VALUE_ANCHORPEERS, setNewOrgAnchorPeerValue());
}
return ConfigGroup.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.putAllPolicies(FabricChannelUtil.getDefaultRolePolicy(orgMspId))
.putAllValues(valueMap)
.setVersion(
FabricChannelUtil.retrieveMSPGroupVersionFromReadset(
readSet, FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION)
+ 1)
.build();
}

private ConfigValue setNewOrgAnchorPeerValue() {
return ConfigValue.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.setValue(setAnchorPeers().toByteString())
.setVersion(0)
.build();
}

private AnchorPeers setAnchorPeers() {
List<AnchorPeer> anchorPeerList = new ArrayList<>();
for (AnchorPeerDTO anchorPeerDTO : anchorPeerParamsDTO.getAnchorPeerDTOs()) {
anchorPeerList.add(
AnchorPeer.newBuilder()
.setHost(anchorPeerDTO.getHostname())
.setPort(anchorPeerDTO.getPort())
.build());
}
return AnchorPeers.newBuilder().addAllAnchorPeers(anchorPeerList).build();
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package hlf.java.rest.client.service.impl;

import com.google.protobuf.ByteString;
import hlf.java.rest.client.exception.ErrorCode;
import hlf.java.rest.client.exception.ServiceException;
import hlf.java.rest.client.model.AnchorPeerDTO;
import hlf.java.rest.client.model.NewOrgParamsDTO;
Expand All @@ -12,9 +11,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.hyperledger.fabric.protos.common.Configtx.ConfigGroup;
import org.hyperledger.fabric.protos.common.Configtx.ConfigPolicy;
import org.hyperledger.fabric.protos.common.Configtx.ConfigValue;
import org.hyperledger.fabric.protos.msp.MspConfigPackage.FabricCryptoConfig;
import org.hyperledger.fabric.protos.msp.MspConfigPackage.FabricMSPConfig;
Expand All @@ -29,48 +26,28 @@
public class AddOrgToChannelWriteSetBuilderImpl implements AddOrgToChannelWriteSetBuilder {

private NewOrgParamsDTO organizationDetails;
private static final int DEFAULT_VERSION = 0;

@Override
public ConfigGroup buildWriteset(ConfigGroup readset, NewOrgParamsDTO organizationDetails)
throws ServiceException {
this.organizationDetails = organizationDetails;
String newOrgMspId = organizationDetails.getOrganizationMspId();
// Get existing organizations in the channel and set with as objects and their
// version to prevent deletion or modification
// Omitting existing groups results in their deletion.
Map<String, ConfigGroup> existingOrganizations = new HashMap<>();
ConfigGroup applicationConfigGroup =
readset.getGroupsOrThrow(FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION);
applicationConfigGroup
.getGroupsMap()
.forEach(
(k, v) ->
existingOrganizations.put(
k,
setEmptyGroup(retrieveMSPGroupVersionFromReadset(applicationConfigGroup, k))));
Map<String, ConfigGroup> existingOrganizations =
FabricChannelUtil.getExistingOrgsFromReadset(readset);

// The "Application" group
ConfigGroup applicationGroup =
ConfigGroup.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.putAllPolicies(setApplicationPolicies(readset))
.putAllPolicies(FabricChannelUtil.setApplicationPolicies(readset))
.putGroups(newOrgMspId, setNewOrgGroup(newOrgMspId))
// putAllGroups excludes new organization
.putAllGroups(existingOrganizations)
// Application group version
.setVersion(
retrieveMSPGroupVersionFromReadset(
FabricChannelUtil.retrieveMSPGroupVersionFromReadset(
readset, FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION)
+ 1) // will
// be
// tied
// to
// current
// version
// + 1
// for
// this
// level
+ 1) // will be tied to current version + 1 for this level
.build();
// the "/Channel" group
return ConfigGroup.newBuilder()
Expand All @@ -81,89 +58,6 @@ public ConfigGroup buildWriteset(ConfigGroup readset, NewOrgParamsDTO organizati
.build();
}

private long retrieveMSPGroupVersionFromReadset(ConfigGroup readset, String mspId)
throws ServiceException {
long versionLong = DEFAULT_VERSION;
try {
ConfigGroup group = readset.getGroupsOrThrow(mspId);
versionLong = group.getVersion();
} catch (IllegalArgumentException e) {
throw new ServiceException(
ErrorCode.NOT_FOUND,
"WriteBuilder version iteration error: ConfigGroup with name - \""
+ mspId
+ "\" - not found in Readset",
e);
}
return versionLong;
}

private Map<String, Long> retrievePolicyVersionFromReadset(ConfigGroup readset, String groupName)
throws ServiceException {
Map<String, Long> map = new HashMap<>();
try {
ConfigGroup group = readset.getGroupsOrThrow(groupName);
for (Entry<String, ConfigPolicy> entry : group.getPoliciesMap().entrySet()) {
map.put(entry.getKey(), entry.getValue().getVersion());
}
} catch (IllegalArgumentException e) {
throw new ServiceException(
ErrorCode.NOT_FOUND,
"WriteBuilder version iteration error: ConfigGroup with name - \""
+ groupName
+ "\" - not found in Readset",
e);
}
return map;
}

private Map<String, ConfigPolicy> setApplicationPolicies(ConfigGroup readset) {
Map<String, Long> map =
retrievePolicyVersionFromReadset(
readset, FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION);
ConfigPolicy adminPolicy =
ConfigPolicy.newBuilder()
.setModPolicy("")
.setVersion(map.get(FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS))
.build();
ConfigPolicy endorsementPolicy =
ConfigPolicy.newBuilder()
.setModPolicy("")
.setVersion(map.get(FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT))
.build();
ConfigPolicy lifeCycleEndorsementPolicy =
ConfigPolicy.newBuilder()
.setModPolicy("")
.setVersion(
map.get(FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_LIFECYCLE_ENDORSEMENT))
.build();
ConfigPolicy readerPolicy =
ConfigPolicy.newBuilder()
.setModPolicy("")
.setVersion(map.get(FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS))
.build();
ConfigPolicy writerPolicy =
ConfigPolicy.newBuilder()
.setModPolicy("")
.setVersion(map.get(FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS))
.build();
Map<String, ConfigPolicy> applicationPoliciesMap = new HashMap<>();
// add Admins, Readers, Writers, Endorsement and LifeCycle Endorsement policies at the channel
// level
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS, adminPolicy);
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT, endorsementPolicy);
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_LIFECYCLE_ENDORSEMENT,
lifeCycleEndorsementPolicy);
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS, readerPolicy);
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS, writerPolicy);
return applicationPoliciesMap;
}

private ConfigGroup setNewOrgGroup(String newOrgMspId) {
Map<String, ConfigValue> valueMap = new HashMap<>();
valueMap.put(
Expand All @@ -181,10 +75,6 @@ private ConfigGroup setNewOrgGroup(String newOrgMspId) {
.build();
}

private ConfigGroup setEmptyGroup(long version) {
return ConfigGroup.newBuilder().setModPolicy("").setVersion(version).build();
}

private ConfigValue setNewOrgMspValue(String newOrgMspId) {
return ConfigValue.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,9 @@ private Common.Envelope getChannelCreationTransaction(
*/
private Configtx.ConfigUpdate newConfigUpdate(ChannelOperationRequest channelOperationRequest) {
Map<String, MSPDTO> mspMap = new HashMap<>();
channelOperationRequest.getPeers().forEach(p -> mspMap.putIfAbsent(p.getMspid(), p.getMspDTO()));
channelOperationRequest
.getPeers()
.forEach(p -> mspMap.putIfAbsent(p.getMspid(), p.getMspDTO()));
return Configtx.ConfigUpdate.newBuilder()
.setChannelId(channelOperationRequest.getChannelName())
.setReadSet(newChannelGroup(channelOperationRequest.getConsortiumName(), mspMap, false))
Expand Down
Loading
Loading