diff --git a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java index 4c88c2374..159669c23 100644 --- a/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java +++ b/fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/shim/ledger/CompositeKey.java @@ -76,8 +76,11 @@ public static CompositeKey parseCompositeKey(final String compositeKey) { throw CompositeKeyFormatException.forInputString(compositeKey, compositeKey, 0); } // relying on the fact that NAMESPACE == DELIMETER - final String[] segments = compositeKey.split(DELIMITER, 0); - return new CompositeKey(segments[1], Arrays.stream(segments).skip(2).toArray(String[]::new)); + // keep empty segments so that empty attributes are preserved + final String[] segments = compositeKey.split(DELIMITER, -1); + // the final delimiter terminates the last attribute, so the empty segment after it is not an attribute + final int end = compositeKey.endsWith(DELIMITER) ? segments.length - 1 : segments.length; + return new CompositeKey(segments[1], Arrays.copyOfRange(segments, 2, Math.max(2, end))); } /** diff --git a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ledger/CompositeKeyTest.java b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ledger/CompositeKeyTest.java index 21293a01a..fd7679086 100644 --- a/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ledger/CompositeKeyTest.java +++ b/fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/shim/ledger/CompositeKeyTest.java @@ -105,6 +105,22 @@ void testParseCompositeKey() { assertThat(key.toString(), is(equalTo("\u0000abc\u0000def\u0000ghi\u0000jkl\u0000mno\u0000"))); } + @Test + void testParseCompositeKeyWithEmptyAttributes() { + final CompositeKey key = CompositeKey.parseCompositeKey("\u0000abc\u0000\u0000def\u0000\u0000\u0000"); + assertThat(key.getObjectType(), is(equalTo("abc"))); + assertThat(key.getAttributes(), contains("", "def", "", "")); + assertThat(key.toString(), is(equalTo("\u0000abc\u0000\u0000def\u0000\u0000\u0000"))); + } + + @Test + void testParseCompositeKeyWithEmptyObjectType() { + final CompositeKey key = CompositeKey.parseCompositeKey("\u0000\u0000"); + assertThat(key.getObjectType(), is(equalTo(""))); + assertThat(key.getAttributes(), hasSize(0)); + assertThat(key.toString(), is(equalTo("\u0000\u0000"))); + } + @Test void testParseCompositeKeyInvalidObjectType() { assertThatThrownBy(() ->