Browse Source

Completed feature that setting roles in ledger's initialization configuration;

tags/1.1.0
huanghaiquan 5 years ago
parent
commit
13bacf9f5a
9 changed files with 390 additions and 69 deletions
  1. +22
    -27
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermission.java
  2. +3
    -3
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/SecurityInitData.java
  3. +12
    -0
      source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/SecurityInitDataTest.java
  4. +0
    -2
      source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeTest.java
  5. +141
    -12
      source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java
  6. +81
    -8
      source/tools/tools-initializer/src/test/java/test/com/jd/blockchain/tools/initializer/LedgerInitPropertiesTest.java
  7. +60
    -1
      source/tools/tools-initializer/src/test/resources/ledger.init
  8. +4
    -0
      source/utils/utils-common/src/main/java/com/jd/blockchain/utils/PropertiesUtils.java
  9. +67
    -16
      source/utils/utils-common/src/main/java/com/jd/blockchain/utils/StringUtils.java

+ 22
- 27
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/LedgerPermission.java View File

@@ -36,34 +36,26 @@ public enum LedgerPermission {
REGISTER_PARTICIPANT((byte) 0x04),

/**
* 设置参与方的权限;<br>
* 注册用户;<br>
*
* 如果不具备此项权限,则无法设置参与方的“提交交易”、“参与共识”的权限
* 如果不具备此项权限,则无法注册用户
*/
SET_PARTICIPANT_PERMISSION((byte) 0x05),
REGISTER_USER((byte) 0x05),

/**
* 参与方核准交易;<br>
*
* 如果不具备此项权限,则无法作为节点签署由终端提交的交易;
* <p>
* 只对交易请求的节点签名列表{@link TransactionRequest#getNodeSignatures()}的用户产生影响;
* 注册数据账户;<br>
*/
APPROVE_TX((byte) 0x06),
REGISTER_DATA_ACCOUNT((byte) 0x06),

/**
* 参与方共识交易;<br>
*
* 如果不具备此项权限,则无法作为共识节点接入并对交易进行共识;
* 注册合约;<br>
*/
CONSENSUS_TX((byte) 0x07),
REGISTER_CONTRACT((byte) 0x07),

/**
* 注册用户;<br>
*
* 如果不具备此项权限,则无法注册用户;
* 升级合约
*/
REGISTER_USER((byte) 0x08),
UPGRADE_CONTRACT((byte) 0x08),

/**
* 设置用户属性;<br>
@@ -71,24 +63,27 @@ public enum LedgerPermission {
SET_USER_ATTRIBUTES((byte) 0x09),

/**
* 注册数据账户;<br>
*/
REGISTER_DATA_ACCOUNT((byte) 0x0A),

/**
* 写入数据账户;<br>
*/
WRITE_DATA_ACCOUNT((byte) 0x0B),
WRITE_DATA_ACCOUNT((byte) 0x0A),

/**
* 注册合约;<br>
* 参与方核准交易;<br>
*
* 如果不具备此项权限,则无法作为节点签署由终端提交的交易;
* <p>
* 只对交易请求的节点签名列表{@link TransactionRequest#getNodeSignatures()}的用户产生影响;
*/
REGISTER_CONTRACT((byte) 0x0C),
APPROVE_TX((byte) 0x0B),

/**
* 升级合约
* 参与方共识交易;<br>
*
* 如果不具备此项权限,则无法作为共识节点接入并对交易进行共识;
*/
UPGRADE_CONTRACT((byte) 0x0D);
CONSENSUS_TX((byte) 0x0C);

@EnumField(type = PrimitiveType.INT8)
public final byte CODE;


+ 3
- 3
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/SecurityInitData.java View File

@@ -5,7 +5,7 @@ import java.util.List;

public class SecurityInitData implements SecurityInitSettings {

private List<RoleInitSettings> roles = new ArrayList<RoleInitSettings>();
private List<RoleInitData> roles = new ArrayList<RoleInitData>();

@Override
public RoleInitData[] getRoles() {
@@ -13,8 +13,8 @@ public class SecurityInitData implements SecurityInitSettings {
}

public void setRoles(RoleInitData[] roles) {
List<RoleInitSettings> list = new ArrayList<RoleInitSettings>();
for (RoleInitSettings r : roles) {
List<RoleInitData> list = new ArrayList<RoleInitData>();
for (RoleInitData r : roles) {
list.add(r);
}
this.roles = list;


+ 12
- 0
source/ledger/ledger-model/src/test/java/test/com/jd/blockchain/ledger/SecurityInitDataTest.java View File

@@ -29,6 +29,18 @@ public class SecurityInitDataTest {
assertEquals(LedgerPermission.REGISTER_USER, permissions2[0]);
assertEquals(LedgerPermission.REGISTER_DATA_ACCOUNT, permissions2[1]);
LedgerPermission[] allLedgerPermissions = LedgerPermission.values();
String jsonLedgerPersioms = JSONSerializeUtils.serializeToJSON(allLedgerPermissions);
TransactionPermission[] allTransactionPermissions = TransactionPermission.values();
String jsonTransactionPersioms = JSONSerializeUtils.serializeToJSON(allTransactionPermissions);
System.out.println("----------- Ledger Permissions JSON ------------");
System.out.println(jsonLedgerPersioms);
System.out.println("-----------------------");
System.out.println("----------- Transaction Permissions JSON ------------");
System.out.println(jsonTransactionPersioms);
System.out.println("-----------------------");
}

@Test


+ 0
- 2
source/test/test-integration/src/test/java/test/com/jd/blockchain/intgr/initializer/LedgerInitializeTest.java View File

@@ -13,8 +13,6 @@ import org.junit.Test;
import org.springframework.core.io.ClassPathResource;

import com.jd.blockchain.binaryproto.DataContractRegistry;
import com.jd.blockchain.consensus.ConsensusProvider;
import com.jd.blockchain.consensus.ConsensusSettings;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.AsymmetricKeypair;
import com.jd.blockchain.crypto.Crypto;


+ 141
- 12
source/tools/tools-initializer/src/main/java/com/jd/blockchain/tools/initializer/LedgerInitProperties.java View File

@@ -7,15 +7,23 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;

import com.jd.blockchain.consts.Global;
import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.ParticipantNode;
import com.jd.blockchain.ledger.RoleInitData;
import com.jd.blockchain.ledger.RoleInitSettings;
import com.jd.blockchain.ledger.RolesPolicy;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.tools.keygen.KeyGenCommand;
import com.jd.blockchain.utils.Bytes;
import com.jd.blockchain.utils.PropertiesUtils;
import com.jd.blockchain.utils.StringUtils;
import com.jd.blockchain.utils.codec.HexUtils;
import com.jd.blockchain.utils.io.FileUtils;
import com.jd.blockchain.utils.net.NetworkAddress;
@@ -33,6 +41,13 @@ public class LedgerInitProperties {
// 创建时间的格式;
public static final String CREATED_TIME_FORMAT = Global.DEFAULT_TIME_FORMAT;

// 角色清单;
public static final String ROLES = "security.roles";
// 角色的账本权限;用角色名称替代占位符;
public static final String ROLE_LEDGER_PRIVILEGES_PATTERN = "security.role.%s.ledger-privileges";
// 角色的交易权限;用角色名称替代占位符;
public static final String ROLE_TX_PRIVILEGES_PATTERN = "security.role.%s.tx-privileges";

// 共识参与方的个数,后续以 part.id 分别标识每一个参与方的配置;
public static final String PART_COUNT = "cons_parti.count";
// 共识参与方的名称的模式;
@@ -43,6 +58,10 @@ public class LedgerInitProperties {
public static final String PART_PUBKEY_PATH = "pubkey-path";
// 参与方的公钥文件路径;
public static final String PART_PUBKEY = "pubkey";
// 参与方的角色清单;
public static final String PART_ROLES = "roles";
// 参与方的角色权限策略;
public static final String PART_ROLES_POLICY = "roles-policy";

// 共识参与方的账本初始服务的主机;
public static final String PART_INITIALIZER_HOST = "initializer.host";
@@ -66,6 +85,8 @@ public class LedgerInitProperties {

private String ledgerName;

private RoleInitData[] roles;

private List<ConsensusParticipantConfig> consensusParticipants = new ArrayList<>();

private String consensusProvider;
@@ -143,7 +164,7 @@ public class LedgerInitProperties {
consensusParticipants.add(participant);
}

private static String getKeyOfCsParti(int partId, String partPropKey) {
private static String getKeyOfParticipant(int partId, String partPropKey) {
String partAddrStr = String.format(PART_ID_PATTERN, partId);
return String.format("%s.%s", partAddrStr, partPropKey);
}
@@ -162,12 +183,20 @@ public class LedgerInitProperties {
public static LedgerInitProperties resolve(Properties props) {
return resolve(null, props);
}
public static LedgerInitProperties resolve(String dir, Properties props) {

/**
* 从属性表解析账本初始化参数;
*
* @param baseDirectory 基础路径;属性中涉及文件位置的相对路径以此参数指定的目录为父目录;
* @param props 要解析的属性表;
* @return
*/
public static LedgerInitProperties resolve(String baseDirectory, Properties props) {
String hexLedgerSeed = PropertiesUtils.getRequiredProperty(props, LEDGER_SEED).replace("-", "");
byte[] ledgerSeed = HexUtils.decode(hexLedgerSeed);
LedgerInitProperties initProps = new LedgerInitProperties(ledgerSeed);

// 解析账本信息;
// 账本名称
String ledgerName = PropertiesUtils.getRequiredProperty(props, LEDGER_NAME);
initProps.ledgerName = ledgerName;
@@ -180,11 +209,35 @@ public class LedgerInitProperties {
throw new IllegalArgumentException(ex.getMessage(), ex);
}

// 解析角色清单;
String strRoleNames = PropertiesUtils.getOptionalProperty(props, ROLES);
String[] roles = StringUtils.splitToArray(strRoleNames, ",");

Map<String, RoleInitData> rolesInitSettingMap = new TreeMap<String, RoleInitData>();
// 解析角色权限表;
for (String role : roles) {
String ledgerPrivilegeKey = getKeyOfRoleLedgerPrivilege(role);
String strLedgerPermissions = PropertiesUtils.getOptionalProperty(props, ledgerPrivilegeKey);
LedgerPermission[] ledgerPermissions = resolveLedgerPermissions(strLedgerPermissions);

String txPrivilegeKey = getKeyOfRoleTxPrivilege(role);
String strTxPermissions = PropertiesUtils.getOptionalProperty(props, txPrivilegeKey);
TransactionPermission[] txPermissions = resolveTransactionPermissions(strTxPermissions);

if (ledgerPermissions.length > 0 || txPermissions.length > 0) {
RoleInitData rolesSettings = new RoleInitData(role, ledgerPermissions, txPermissions);
rolesInitSettingMap.put(role, rolesSettings);
}
}
RoleInitData[] rolesInitDatas = rolesInitSettingMap.values()
.toArray(new RoleInitData[rolesInitSettingMap.size()]);
initProps.setRoles(rolesInitDatas);
// 解析共识相关的属性;
initProps.consensusProvider = PropertiesUtils.getRequiredProperty(props, CONSENSUS_SERVICE_PROVIDER);
String consensusConfigFilePath = PropertiesUtils.getRequiredProperty(props, CONSENSUS_CONFIG);
try {
File consensusConfigFile = FileUtils.getFile(dir, consensusConfigFilePath);
File consensusConfigFile = FileUtils.getFile(baseDirectory, consensusConfigFilePath);
initProps.consensusConfig = FileUtils.readProperties(consensusConfigFile);
} catch (FileNotFoundException e) {
throw new IllegalArgumentException(
@@ -212,13 +265,13 @@ public class LedgerInitProperties {

parti.setId(i);

String nameKey = getKeyOfCsParti(i, PART_NAME);
String nameKey = getKeyOfParticipant(i, PART_NAME);
parti.setName(PropertiesUtils.getRequiredProperty(props, nameKey));

String pubkeyPathKey = getKeyOfCsParti(i, PART_PUBKEY_PATH);
String pubkeyPathKey = getKeyOfParticipant(i, PART_PUBKEY_PATH);
String pubkeyPath = PropertiesUtils.getProperty(props, pubkeyPathKey, false);

String pubkeyKey = getKeyOfCsParti(i, PART_PUBKEY);
String pubkeyKey = getKeyOfParticipant(i, PART_PUBKEY);
String base58PubKey = PropertiesUtils.getProperty(props, pubkeyKey, false);
if (base58PubKey != null) {
PubKey pubKey = KeyGenCommand.decodePubKey(base58PubKey);
@@ -231,13 +284,27 @@ public class LedgerInitProperties {
String.format("Property[%s] and property[%s] are all empty!", pubkeyKey, pubkeyPathKey));
}

String initializerHostKey = getKeyOfCsParti(i, PART_INITIALIZER_HOST);
// 解析参与方的角色权限配置;
String partiRolesKey = getKeyOfParticipant(i, PART_ROLES);
String strPartiRoles = PropertiesUtils.getOptionalProperty(props, partiRolesKey);
String[] partiRoles = StringUtils.splitToArray(strPartiRoles, ",");
parti.setRoles(partiRoles);

String partiRolePolicyKey = getKeyOfParticipant(i, PART_ROLES_POLICY);
String strPartiPolicy = PropertiesUtils.getOptionalProperty(props, partiRolePolicyKey);
RolesPolicy policy = strPartiPolicy == null ? RolesPolicy.UNION
: RolesPolicy.valueOf(strPartiPolicy.trim());
policy = policy == null ? RolesPolicy.UNION : policy;
parti.setRolesPolicy(policy);

// 解析参与方的网络配置参数;
String initializerHostKey = getKeyOfParticipant(i, PART_INITIALIZER_HOST);
String initializerHost = PropertiesUtils.getRequiredProperty(props, initializerHostKey);

String initializerPortKey = getKeyOfCsParti(i, PART_INITIALIZER_PORT);
String initializerPortKey = getKeyOfParticipant(i, PART_INITIALIZER_PORT);
int initializerPort = getInt(PropertiesUtils.getRequiredProperty(props, initializerPortKey));

String initializerSecureKey = getKeyOfCsParti(i, PART_INITIALIZER_SECURE);
String initializerSecureKey = getKeyOfParticipant(i, PART_INITIALIZER_SECURE);
boolean initializerSecure = Boolean
.parseBoolean(PropertiesUtils.getRequiredProperty(props, initializerSecureKey));
NetworkAddress initializerAddress = new NetworkAddress(initializerHost, initializerPort, initializerSecure);
@@ -249,10 +316,54 @@ public class LedgerInitProperties {
return initProps;
}

private static TransactionPermission[] resolveTransactionPermissions(String strTxPermissions) {
String[] strPermissions = StringUtils.splitToArray(strTxPermissions, ",");
List<TransactionPermission> permissions = new ArrayList<TransactionPermission>();
if (strPermissions != null) {
for (String pm : strPermissions) {
TransactionPermission permission = TransactionPermission.valueOf(pm);
if (permission != null) {
permissions.add(permission);
}
}
}
return permissions.toArray(new TransactionPermission[permissions.size()]);
}

private static LedgerPermission[] resolveLedgerPermissions(String strLedgerPermissions) {
String[] strPermissions = StringUtils.splitToArray(strLedgerPermissions, ",");
List<LedgerPermission> permissions = new ArrayList<LedgerPermission>();
if (strPermissions != null) {
for (String pm : strPermissions) {
LedgerPermission permission = LedgerPermission.valueOf(pm);
if (permission != null) {
permissions.add(permission);
}
}
}
return permissions.toArray(new LedgerPermission[permissions.size()]);
}

private static String getKeyOfRoleLedgerPrivilege(String role) {
return String.format(ROLE_LEDGER_PRIVILEGES_PATTERN, role);
}

private static String getKeyOfRoleTxPrivilege(String role) {
return String.format(ROLE_TX_PRIVILEGES_PATTERN, role);
}

private static int getInt(String strInt) {
return Integer.parseInt(strInt.trim());
}

public RoleInitData[] getRoles() {
return roles;
}

public void setRoles(RoleInitData[] roles) {
this.roles = roles;
}

/**
* 参与方配置信息;
*
@@ -267,10 +378,12 @@ public class LedgerInitProperties {

private String name;

// private String pubKeyPath;

private PubKey pubKey;

private String[] roles;

private RolesPolicy rolesPolicy;

// private NetworkAddress consensusAddress;

private NetworkAddress initializerAddress;
@@ -321,6 +434,22 @@ public class LedgerInitProperties {
this.address = AddressEncoding.generateAddress(pubKey);
}

public String[] getRoles() {
return roles;
}

public void setRoles(String[] roles) {
this.roles = roles;
}

public RolesPolicy getRolesPolicy() {
return rolesPolicy;
}

public void setRolesPolicy(RolesPolicy rolesPolicy) {
this.rolesPolicy = rolesPolicy;
}

}

}

+ 81
- 8
source/tools/tools-initializer/src/test/java/test/com/jd/blockchain/tools/initializer/LedgerInitPropertiesTest.java View File

@@ -1,12 +1,18 @@
package test.com.jd.blockchain.tools.initializer;

import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;

import org.junit.Test;
@@ -14,6 +20,10 @@ import org.springframework.core.io.ClassPathResource;

import com.jd.blockchain.crypto.AddressEncoding;
import com.jd.blockchain.crypto.PubKey;
import com.jd.blockchain.ledger.LedgerPermission;
import com.jd.blockchain.ledger.RoleInitData;
import com.jd.blockchain.ledger.RolesPolicy;
import com.jd.blockchain.ledger.TransactionPermission;
import com.jd.blockchain.tools.initializer.LedgerInitProperties;
import com.jd.blockchain.tools.initializer.LedgerInitProperties.ConsensusParticipantConfig;
import com.jd.blockchain.tools.keygen.KeyGenCommand;
@@ -22,19 +32,20 @@ import com.jd.blockchain.utils.codec.HexUtils;
public class LedgerInitPropertiesTest {

private static String expectedCreatedTimeStr = "2019-08-01 14:26:58.069+0800";
private static String expectedCreatedTimeStr1 = "2019-08-01 13:26:58.069+0700";
@Test
public void testTimeFormat() throws ParseException {
SimpleDateFormat timeFormat = new SimpleDateFormat(LedgerInitProperties.CREATED_TIME_FORMAT);
// timeFormat.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
TimeZone.setDefault(TimeZone.getTimeZone("GMT+08:00"));
timeFormat.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
// 或者设置全局的默认时区;
// TimeZone.setDefault(TimeZone.getTimeZone("GMT+08:00"));

Date time = timeFormat.parse(expectedCreatedTimeStr);
String actualTimeStr = timeFormat.format(time);
assertEquals(expectedCreatedTimeStr, actualTimeStr);
Date time1 = timeFormat.parse(expectedCreatedTimeStr1);
String actualTimeStr1 = timeFormat.format(time1);
assertEquals(expectedCreatedTimeStr, actualTimeStr1);
@@ -42,11 +53,13 @@ public class LedgerInitPropertiesTest {

@Test
public void testProperties() throws IOException, ParseException {
// 加载用于测试的账本初始化配置;
ClassPathResource ledgerInitSettingResource = new ClassPathResource("ledger.init");
InputStream in = ledgerInitSettingResource.getInputStream();
try {
LedgerInitProperties initProps = LedgerInitProperties.resolve(in);
assertEquals(4, initProps.getConsensusParticipantCount());

// 验证账本信息;
String expectedLedgerSeed = "932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323ffe"
.replace("-", "");
String actualLedgerSeed = HexUtils.encode(initProps.getLedgerSeed());
@@ -56,10 +69,54 @@ public class LedgerInitPropertiesTest {
timeFormat.setTimeZone(TimeZone.getTimeZone("GMT+08:00"));
long expectedTs = timeFormat.parse(expectedCreatedTimeStr).getTime();
assertEquals(expectedTs, initProps.getCreatedTime());
String createdTimeStr = timeFormat.format(new Date(initProps.getCreatedTime()));
assertEquals(expectedCreatedTimeStr, createdTimeStr);

// 验证角色配置;
RoleInitData[] roles = initProps.getRoles();
assertEquals(4, roles.length);
Map<String, RoleInitData> rolesInitDatas = new HashMap<String, RoleInitData>();
for (RoleInitData r : roles) {
rolesInitDatas.put(r.getRoleName(), r);
}
// 初始化配置的角色最终也是有序排列的,按照角色名称的自然顺序;
String[] expectedRolesNames = { "DEFAULT", "ADMIN", "MANAGER", "GUEST" };
Arrays.sort(expectedRolesNames);
assertEquals(expectedRolesNames[0], roles[0].getRoleName());
assertEquals(expectedRolesNames[1], roles[1].getRoleName());
assertEquals(expectedRolesNames[2], roles[2].getRoleName());
assertEquals(expectedRolesNames[3], roles[3].getRoleName());

RoleInitData roleDefault = rolesInitDatas.get("DEFAULT");
assertArrayEquals(
new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT },
roleDefault.getLedgerPermissions());
assertArrayEquals(new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION,
TransactionPermission.CONTRACT_OPERATION }, roleDefault.getTransactionPermissions());

RoleInitData roleAdmin = rolesInitDatas.get("ADMIN");
assertArrayEquals(new LedgerPermission[] { LedgerPermission.AUTHORIZE_ROLES, LedgerPermission.SET_CONSENSUS,
LedgerPermission.SET_CRYPTO, LedgerPermission.REGISTER_PARTICIPANT,
LedgerPermission.REGISTER_USER }, roleAdmin.getLedgerPermissions());
assertArrayEquals(new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION },
roleAdmin.getTransactionPermissions());

RoleInitData roleManager = rolesInitDatas.get("MANAGER");
assertArrayEquals(
new LedgerPermission[] { LedgerPermission.REGISTER_USER, LedgerPermission.REGISTER_DATA_ACCOUNT,
LedgerPermission.REGISTER_CONTRACT, LedgerPermission.UPGRADE_CONTRACT,
LedgerPermission.SET_USER_ATTRIBUTES, LedgerPermission.WRITE_DATA_ACCOUNT },
roleManager.getLedgerPermissions());
assertArrayEquals(new TransactionPermission[] { TransactionPermission.DIRECT_OPERATION,
TransactionPermission.CONTRACT_OPERATION }, roleManager.getTransactionPermissions());

RoleInitData roleGuest = rolesInitDatas.get("GUEST");
assertTrue(roleGuest.getLedgerPermissions() == null || roleGuest.getLedgerPermissions().length == 0);
assertArrayEquals(new TransactionPermission[] { TransactionPermission.CONTRACT_OPERATION },
roleGuest.getTransactionPermissions());

// 验证共识和密码配置;
assertEquals("com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider",
initProps.getConsensusProvider());

@@ -68,6 +125,9 @@ public class LedgerInitPropertiesTest {
assertEquals("com.jd.blockchain.crypto.service.classic.ClassicCryptoService", cryptoProviders[0]);
assertEquals("com.jd.blockchain.crypto.service.sm.SMCryptoService", cryptoProviders[1]);

// 验证参与方信息;
assertEquals(4, initProps.getConsensusParticipantCount());
ConsensusParticipantConfig part0 = initProps.getConsensusParticipant(0);
assertEquals("jd.com", part0.getName());
PubKey pubKey0 = KeyGenCommand.decodePubKey("3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9");
@@ -75,14 +135,27 @@ public class LedgerInitPropertiesTest {
assertEquals("127.0.0.1", part0.getInitializerAddress().getHost());
assertEquals(8800, part0.getInitializerAddress().getPort());
assertEquals(true, part0.getInitializerAddress().isSecure());
assertArrayEquals(new String[] {"ADMIN", "MANAGER"}, part0.getRoles());
assertEquals(RolesPolicy.UNION, part0.getRolesPolicy());

ConsensusParticipantConfig part1 = initProps.getConsensusParticipant(1);
assertEquals(false, part1.getInitializerAddress().isSecure());
PubKey pubKey1 = KeyGenCommand.decodePubKey("3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX");
assertEquals(pubKey1, part1.getPubKey());
assertArrayEquals(new String[] { "MANAGER"}, part1.getRoles());
assertEquals(RolesPolicy.UNION, part1.getRolesPolicy());

ConsensusParticipantConfig part2 = initProps.getConsensusParticipant(2);
assertEquals("7VeRAr3dSbi1xatq11ZcF7sEPkaMmtZhV9shonGJWk9T4pLe", part2.getPubKey().toBase58());
assertArrayEquals(new String[] { "MANAGER"}, part2.getRoles());
assertEquals(RolesPolicy.UNION, part2.getRolesPolicy());
ConsensusParticipantConfig part3 = initProps.getConsensusParticipant(3);
PubKey pubKey3 = KeyGenCommand.decodePubKey("3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk");
assertEquals(pubKey3, part3.getPubKey());
assertArrayEquals(new String[] { "GUEST"}, part3.getRoles());
assertEquals(RolesPolicy.INTERSECT, part3.getRolesPolicy());

} finally {
in.close();


+ 60
- 1
source/tools/tools-initializer/src/test/resources/ledger.init View File

@@ -5,9 +5,52 @@ ledger.seed=932dfe23-fe23232f-283f32fa-dd32aa76-8322ca2f-56236cda-7136b322-cb323
#账本的描述名称;此属性不参与共识,仅仅在当前参与方的本地节点用于描述用途;
ledger.name=test

#声明账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区
#声明账本创建时间;格式为 “yyyy-MM-dd HH:mm:ss.SSSZ”,表示”年-月-日 时:分:秒:毫秒时区“;例如:“2019-08-01 14:26:58.069+0800”,其中,+0800 表示时区是东8区
created-time=2019-08-01 14:26:58.069+0800


#-----------------------------------------------
# 初始的角色名称列表;可选项;
# 角色名称不区分大小写,最长不超过20个字符;多个角色名称之间用半角的逗点“,”分隔;
# 系统会预置一个默认角色“DEFAULT”,所有未指定角色的用户都以赋予该角色的权限;若初始化时未配置默认角色的权限,则为默认角色分配所有权限;
#
# 注:如果声明了角色,但未声明角色对应的权限清单,这会忽略该角色的初始化;
#
security.roles=DEFAULT, ADMIN, MANAGER, GUEST

# 赋予角色的账本权限清单;可选项;
# 可选的权限如下;
# AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT,
# REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT,
# SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT,
# APPROVE_TX, CONSENSUS_TX
# 多项权限之间用逗点“,”分隔;
#
security.role.DEFAULT.ledger-privileges=REGISTER_USER, REGISTER_DATA_ACCOUNT

# 赋予角色的交易权限清单;可选项;
# 可选的权限如下;
# DIRECT_OPERATION, CONTRACT_OPERATION
# 多项权限之间用逗点“,”分隔;
#
security.role.DEFAULT.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION

# 其它角色的配置示例;
# 系统管理员角色:只能操作全局性的参数配置和用户注册,只能执行直接操作指令;
security.role.ADMIN.ledger-privileges=AUTHORIZE_ROLES, SET_CONSENSUS, SET_CRYPTO, REGISTER_PARTICIPANT, REGISTER_USER
security.role.ADMIN.tx-privileges=DIRECT_OPERATION

# 业务主管角色:只能够执行账本数据相关的操作,包括注册用户、注册数据账户、注册合约、升级合约、写入数据等;能够执行直接操作指令和调用合约;
security.role.MANAGER.ledger-privileges=REGISTER_USER, REGISTER_DATA_ACCOUNT, REGISTER_CONTRACT, UPGRADE_CONTRACT, SET_USER_ATTRIBUTES, WRITE_DATA_ACCOUNT,
security.role.MANAGER.tx-privileges=DIRECT_OPERATION, CONTRACT_OPERATION

# 访客角色:不具备任何的账本权限,只有数据读取的操作;也只能够通过调用合约来读取数据;
security.role.GUEST.ledger-privileges=
security.role.GUEST.tx-privileges=CONTRACT_OPERATION



#-----------------------------------------------
#共识服务提供者;必须;
consensus.service-provider=com.jd.blockchain.consensus.bftsmart.BftsmartConsensusProvider

@@ -28,6 +71,10 @@ cons_parti.0.name=jd.com
cons_parti.0.pubkey-path=keys/jd-com.pub
#第0个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.0.pubkey=3snPdw7i7PjVKiTH2VnXZu5H8QmNaSXpnk4ei533jFpuifyjS5zzH9
#第0个参与方的角色清单;可选项;
cons_parti.0.roles=ADMIN, MANAGER
#第0个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.0.roles-policy=UNION
#第0个参与方的共识服务的主机地址;
cons_parti.0.consensus.host=127.0.0.1
#第0个参与方的共识服务的端口;
@@ -47,6 +94,10 @@ cons_parti.1.name=at.com
cons_parti.1.pubkey-path=keys/at-com.pub
#第1个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.1.pubkey=3snPdw7i7PajLB35tEau1kmixc6ZrjLXgxwKbkv5bHhP7nT5dhD9eX
#第1个参与方的角色清单;可选项;
cons_parti.1.roles=MANAGER
#第1个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.1.roles-policy=UNION
#第1个参与方的共识服务的主机地址;
cons_parti.1.consensus.host=127.0.0.1
#第1个参与方的共识服务的端口;
@@ -66,6 +117,10 @@ cons_parti.2.name=bt.com
cons_parti.2.pubkey-path=classpath:keys/parti2.pub
#第2个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.2.pubkey=
#第2个参与方的角色清单;可选项;
cons_parti.2.roles=MANAGER
#第2个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.2.roles-policy=UNION
#第2个参与方的共识服务的主机地址;
cons_parti.2.consensus.host=127.0.0.1
#第2个参与方的共识服务的端口;
@@ -85,6 +140,10 @@ cons_parti.3.name=xt.com
cons_parti.3.pubkey-path=keys/xt-com.pub
#第3个参与方的公钥内容(由keygen工具生成);此参数优先于 pubkey-path 参数;
cons_parti.3.pubkey=3snPdw7i7PifPuRX7fu3jBjsb3rJRfDe9GtbDfvFJaJ4V4hHXQfhwk
#第3个参与方的角色清单;可选项;
cons_parti.3.roles=GUEST
#第3个参与方的角色权限策略,可选值有:UNION(并集),INTERSECT(交集);可选项;
cons_parti.3.roles-policy=INTERSECT
#第3个参与方的共识服务的主机地址;
cons_parti.3.consensus.host=127.0.0.1
#第3个参与方的共识服务的端口;


+ 4
- 0
source/utils/utils-common/src/main/java/com/jd/blockchain/utils/PropertiesUtils.java View File

@@ -263,6 +263,10 @@ public abstract class PropertiesUtils {
public static String getRequiredProperty(Properties props, String key) {
return getProperty(props, key, true);
}
public static String getOptionalProperty(Properties props, String key) {
return getProperty(props, key, false);
}
/**
* 返回指定的属性; <br>


+ 67
- 16
source/utils/utils-common/src/main/java/com/jd/blockchain/utils/StringUtils.java View File

@@ -1,24 +1,75 @@
package com.jd.blockchain.utils;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

/**
* @Author zhaogw
* date 2018/11/26 20:46
* @Author zhaogw date 2018/11/26 20:46
*/
public class StringUtils {
public static boolean isEmpty(Object str) {
return str == null || "".equals(str);
}

/*
* 判断是否为整数
* @param str 传入的字符串
* @return 是整数返回true,否则返回false
*/

public static boolean isNumber(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(str).matches();
}

public static final String[] EMPTY_ARRAY = {};

public static boolean isEmpty(Object str) {
return str == null || "".equals(str);
}

/*
* 判断是否为整数
*
* @param str 传入的字符串
*
* @return 是整数返回true,否则返回false
*/

public static boolean isNumber(String str) {
Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
return pattern.matcher(str).matches();
}

/**
* 按照指定的分隔符把字符串分解为字符数组,同时截掉每一个元素两端的空白字符,并忽略掉空字符元素;
*
* @param str 要被截断的字符串;
* @param delimiter 分隔符;
* @return
*/
public static String[] splitToArray(String str, String delimiter) {
return splitToArray(str, delimiter, true, true);
}

/**
* 按照指定的分隔符把字符串分解为字符数组
*
* @param str 要被截断的字符串;
* @param delimiter 分隔符;
* @param trimElement 是否截断元素两端的空白字符;
* @param ignoreEmptyElement 是否忽略空字符元素;
* @return
*/
public static String[] splitToArray(String str, String delimiter, boolean trimElement, boolean ignoreEmptyElement) {
if (str == null) {
return null;
}
if (trimElement) {
str = str.trim();
}
if (str.length() == 0) {
return EMPTY_ARRAY;
}
StringTokenizer tokenizer = new StringTokenizer(str, delimiter);
List<String> tokens = new ArrayList<>();
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (trimElement) {
token = token.trim();
}
if ((!ignoreEmptyElement) || token.length() > 0) {
tokens.add(token);
}
}
return tokens.toArray(new String[tokens.size()]);
}
}

Loading…
Cancel
Save