Skip to content

Commit 5858fbb

Browse files
author
Luis Sanchez
committed
[FAB-3273] java cc get state by range
- Introduced KeyValue type that maps to KV proto. - New QueryResultsIterator. - Re-arranged packages to keep public vs. internal code as separate as possible. * org.hyperledger.fabric.shim (public shim API) * org.hyperledger.fabric.impl (implementations) * org.hyperledger.fabric.shim.ledger (public ledger interfaces) - ChaincodeStub: * QueryResultsIterator<KeyValue> getStateForRange(start, end) * QueryResultsIterator<KeyValue> getStateForPartialCompositeKey(key) - Handler * QueryResponse handleGetStateForRange() * QueryResponse queryStateNext() * void queryStateClose() * Reduce the visibily of members in order to minimize the public API as much as possible. Change-Id: Iea75e426e55ff2e482e0a751b2dbd540bdae6a03 Signed-off-by: Luis Sanchez <[email protected]>
1 parent 708c3aa commit 5858fbb

File tree

11 files changed

+499
-124
lines changed

11 files changed

+499
-124
lines changed

core/chaincode/shim/java/src/main/java/org/hyperledger/fabric/shim/ChaincodeBase.java

+9-7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
import org.hyperledger.fabric.protos.peer.ChaincodeSupportGrpc;
3232
import org.hyperledger.fabric.protos.peer.ChaincodeSupportGrpc.ChaincodeSupportStub;
3333
import org.hyperledger.fabric.protos.peer.ProposalResponsePackage.Response;
34+
import org.hyperledger.fabric.shim.impl.Handler;
35+
import org.hyperledger.fabric.shim.impl.NextStateInfo;
3436

3537
import com.google.protobuf.InvalidProtocolBufferException;
3638
import com.google.protobuf.util.JsonFormat;
@@ -49,15 +51,15 @@ public abstract class ChaincodeBase implements Chaincode {
4951
*/
5052
@Override
5153
public abstract Response init(ChaincodeStub stub);
52-
54+
5355
/* (non-Javadoc)
5456
* @see org.hyperledger.fabric.shim.Chaincode#invoke(org.hyperledger.fabric.shim.ChaincodeStub)
5557
*/
5658
@Override
5759
public abstract Response invoke(ChaincodeStub stub);
58-
60+
5961
private static Log logger = LogFactory.getLog(ChaincodeBase.class);
60-
62+
6163
public static final String DEFAULT_HOST = "127.0.0.1";
6264
public static final int DEFAULT_PORT = 7051;
6365

@@ -181,8 +183,8 @@ public void chatWithPeer(ManagedChannel connection) {
181183
public void onNext(ChaincodeMessage message) {
182184
logger.debug("Got message from peer: " + toJsonString(message));
183185
try {
184-
logger.debug(String.format("[%s]Received message %s from org.hyperledger.fabric.shim",
185-
Handler.shortID(message.getTxid()), message.getType()));
186+
logger.debug(String.format("[%-8s]Received message %s from org.hyperledger.fabric.shim",
187+
message.getTxid(), message.getType()));
186188
handler.handleMessage(message);
187189
} catch (Exception e) {
188190
e.printStackTrace();
@@ -233,8 +235,8 @@ public void onCompleted() {
233235
if (message.getType() == Type.KEEPALIVE) {
234236
logger.info("Sending KEEPALIVE response");
235237
} else {
236-
logger.info(
237-
"[" + Handler.shortID(message.getTxid()) + "]Send state message " + message.getType());
238+
logger.info(String.format(
239+
"[%-8s]Send state message %s", message.getTxid(), message.getType()));
238240
}
239241
handler.serialSend(message);
240242
}

core/chaincode/shim/java/src/main/java/org/hyperledger/fabric/shim/ChaincodeStub.java

+65-23
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import org.hyperledger.fabric.protos.peer.ChaincodeEventPackage.ChaincodeEvent;
2525
import org.hyperledger.fabric.protos.peer.ProposalResponsePackage.Response;
2626
import org.hyperledger.fabric.shim.ledger.CompositeKey;
27+
import org.hyperledger.fabric.shim.ledger.KeyValue;
28+
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
2729

2830
public interface ChaincodeStub {
2931

@@ -49,7 +51,7 @@ public interface ChaincodeStub {
4951
* A convenience method that returns the first argument of the chaincode
5052
* invocation for use as a function name.
5153
*
52-
* The bytes of the first argument are decoded as a UTF-8 string.
54+
* The bytes of the first argument are decoded as a UTF-8 string.
5355
*
5456
* @return the function name
5557
*/
@@ -77,9 +79,12 @@ public interface ChaincodeStub {
7779
/**
7880
* Invoke another chaincode using the same transaction context.
7981
*
80-
* @param chaincodeName Name of chaincode to be invoked.
81-
* @param args Arguments to pass on to the called chaincode.
82-
* @param channel If not specified, the caller's channel is assumed.
82+
* @param chaincodeName
83+
* Name of chaincode to be invoked.
84+
* @param args
85+
* Arguments to pass on to the called chaincode.
86+
* @param channel
87+
* If not specified, the caller's channel is assumed.
8388
* @return
8489
*/
8590
Response invokeChaincode(String chaincodeName, List<byte[]> args, String channel);
@@ -89,8 +94,7 @@ public interface ChaincodeStub {
8994
*
9095
* @param key
9196
* name of the value
92-
* @return value
93-
* the value read from the ledger
97+
* @return value the value read from the ledger
9498
*/
9599
byte[] getState(String key);
96100

@@ -112,20 +116,48 @@ public interface ChaincodeStub {
112116
*/
113117
void delState(String key);
114118

119+
/**
120+
* Returns all existing keys, and their values, that are lexicographically
121+
* between <code>startkey</code> (inclusive) and the <code>endKey</code>
122+
* (exclusive).
123+
*
124+
* @param startKey
125+
* @param endKey
126+
* @return an {@link Iterable} of {@link KeyValue}
127+
*/
128+
QueryResultsIterator<KeyValue> getStateByRange(String startKey, String endKey);
129+
130+
/**
131+
* Returns all existing keys, and their values, that are prefixed by the
132+
* specified partial {@link CompositeKey}.
133+
*
134+
* If a full composite key is specified, it will not match itself, resulting
135+
* in no keys being returned.
136+
*
137+
* @param compositeKey
138+
* partial composite key
139+
* @return an {@link Iterable} of {@link KeyValue}
140+
*/
141+
QueryResultsIterator<KeyValue> getStateByPartialCompositeKey(String compositeKey);
142+
115143
/**
116144
* Given a set of attributes, this method combines these attributes to
117145
* return a composite key.
118146
*
119147
* @param objectType
120148
* @param attributes
121149
* @return a composite key
150+
* @throws CompositeKeyFormatException
151+
* if any parameter contains either a U+000000 or U+10FFFF code
152+
* point.
122153
*/
123154
CompositeKey createCompositeKey(String objectType, String... attributes);
124155

125156
/**
126157
* Parses a composite key from a string.
127158
*
128-
* @param compositeKey a composite key string
159+
* @param compositeKey
160+
* a composite key string
129161
* @return a composite key
130162
*/
131163
CompositeKey splitCompositeKey(String compositeKey);
@@ -144,8 +176,10 @@ public interface ChaincodeStub {
144176
/**
145177
* Invoke another chaincode using the same transaction context.
146178
*
147-
* @param chaincodeName Name of chaincode to be invoked.
148-
* @param args Arguments to pass on to the called chaincode.
179+
* @param chaincodeName
180+
* Name of chaincode to be invoked.
181+
* @param args
182+
* Arguments to pass on to the called chaincode.
149183
* @return
150184
*/
151185
default Response invokeChaincode(String chaincodeName, List<byte[]> args) {
@@ -155,27 +189,33 @@ default Response invokeChaincode(String chaincodeName, List<byte[]> args) {
155189
/**
156190
* Invoke another chaincode using the same transaction context.
157191
*
158-
* This is a convenience version of {@link #invokeChaincode(String, List, String)}.
159-
* The string args will be encoded into as UTF-8 bytes.
192+
* This is a convenience version of
193+
* {@link #invokeChaincode(String, List, String)}. The string args will be
194+
* encoded into as UTF-8 bytes.
160195
*
161-
* @param chaincodeName Name of chaincode to be invoked.
162-
* @param args Arguments to pass on to the called chaincode.
163-
* @param channel If not specified, the caller's channel is assumed.
196+
* @param chaincodeName
197+
* Name of chaincode to be invoked.
198+
* @param args
199+
* Arguments to pass on to the called chaincode.
200+
* @param channel
201+
* If not specified, the caller's channel is assumed.
164202
* @return
165203
*/
166204
default Response invokeChaincodeWithStringArgs(String chaincodeName, List<String> args, String channel) {
167-
return invokeChaincode(chaincodeName, args.stream().map(x->x.getBytes(UTF_8)).collect(toList()), channel);
205+
return invokeChaincode(chaincodeName, args.stream().map(x -> x.getBytes(UTF_8)).collect(toList()), channel);
168206
}
169207

170208
/**
171209
* Invoke another chaincode using the same transaction context.
172210
*
173211
* This is a convenience version of {@link #invokeChaincode(String, List)}.
174-
* The string args will be encoded into as UTF-8 bytes.
212+
* The string args will be encoded into as UTF-8 bytes.
175213
*
176214
*
177-
* @param chaincodeName Name of chaincode to be invoked.
178-
* @param args Arguments to pass on to the called chaincode.
215+
* @param chaincodeName
216+
* Name of chaincode to be invoked.
217+
* @param args
218+
* Arguments to pass on to the called chaincode.
179219
* @return
180220
*/
181221
default Response invokeChaincodeWithStringArgs(String chaincodeName, List<String> args) {
@@ -186,11 +226,13 @@ default Response invokeChaincodeWithStringArgs(String chaincodeName, List<String
186226
* Invoke another chaincode using the same transaction context.
187227
*
188228
* This is a convenience version of {@link #invokeChaincode(String, List)}.
189-
* The string args will be encoded into as UTF-8 bytes.
229+
* The string args will be encoded into as UTF-8 bytes.
190230
*
191231
*
192-
* @param chaincodeName Name of chaincode to be invoked.
193-
* @param args Arguments to pass on to the called chaincode.
232+
* @param chaincodeName
233+
* Name of chaincode to be invoked.
234+
* @param args
235+
* Arguments to pass on to the called chaincode.
194236
* @return
195237
*/
196238
default Response invokeChaincodeWithStringArgs(final String chaincodeName, final String... args) {
@@ -203,8 +245,7 @@ default Response invokeChaincodeWithStringArgs(final String chaincodeName, final
203245
*
204246
* @param key
205247
* name of the value
206-
* @return value
207-
* the value read from the ledger
248+
* @return value the value read from the ledger
208249
*/
209250
default String getStringState(String key) {
210251
return new String(getState(key), UTF_8);
@@ -225,6 +266,7 @@ default void putStringState(String key, String value) {
225266
/**
226267
* Returns the CHAINCODE type event that will be posted to interested
227268
* clients when the chaincode's result is committed to the ledger.
269+
*
228270
* @return the chaincode event or null
229271
*/
230272
ChaincodeEvent getEvent();

core/chaincode/shim/java/src/main/java/org/hyperledger/fabric/shim/ChaincodeStubImpl.java core/chaincode/shim/java/src/main/java/org/hyperledger/fabric/shim/impl/ChaincodeStubImpl.java

+38-2
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,28 @@
1414
limitations under the License.
1515
*/
1616

17-
package org.hyperledger.fabric.shim;
17+
package org.hyperledger.fabric.shim.impl;
1818

1919
import static java.util.stream.Collectors.toList;
2020

2121
import java.util.Collections;
2222
import java.util.List;
23+
import java.util.function.Function;
2324
import java.util.stream.Collectors;
2425

2526
import org.apache.commons.logging.Log;
2627
import org.apache.commons.logging.LogFactory;
28+
import org.hyperledger.fabric.protos.ledger.queryresult.KvQueryResult.KV;
2729
import org.hyperledger.fabric.protos.peer.ChaincodeEventPackage.ChaincodeEvent;
30+
import org.hyperledger.fabric.protos.peer.ChaincodeShim.QueryResultBytes;
2831
import org.hyperledger.fabric.protos.peer.ProposalResponsePackage.Response;
32+
import org.hyperledger.fabric.shim.ChaincodeStub;
2933
import org.hyperledger.fabric.shim.ledger.CompositeKey;
34+
import org.hyperledger.fabric.shim.ledger.KeyValue;
35+
import org.hyperledger.fabric.shim.ledger.QueryResultsIterator;
3036

3137
import com.google.protobuf.ByteString;
38+
import com.google.protobuf.InvalidProtocolBufferException;
3239

3340
class ChaincodeStubImpl implements ChaincodeStub {
3441

@@ -39,7 +46,7 @@ class ChaincodeStubImpl implements ChaincodeStub {
3946
private final List<ByteString> args;
4047
private ChaincodeEvent event;
4148

42-
public ChaincodeStubImpl(String uuid, Handler handler, List<ByteString> args) {
49+
ChaincodeStubImpl(String uuid, Handler handler, List<ByteString> args) {
4350
this.txid = uuid;
4451
this.handler = handler;
4552
this.args = Collections.unmodifiableList(args);
@@ -135,6 +142,35 @@ public void delState(String key) {
135142
handler.handleDeleteState(key, txid);
136143
}
137144

145+
/* (non-Javadoc)
146+
* @see org.hyperledger.fabric.shim.ChaincodeStub#getStateByRange(java.lang.String, java.lang.String)
147+
*/
148+
@Override
149+
public QueryResultsIterator<KeyValue> getStateByRange(String startKey, String endKey) {
150+
return new QueryResultsIteratorImpl<KeyValue>(this.handler, getTxId(),
151+
handler.handleGetStateByRange(getTxId(), startKey, endKey),
152+
queryResultBytesToKv.andThen(KeyValueImpl::new)
153+
);
154+
}
155+
156+
private Function<QueryResultBytes, KV> queryResultBytesToKv = new Function<QueryResultBytes, KV>() {
157+
public KV apply(QueryResultBytes queryResultBytes) {
158+
try {
159+
return KV.parseFrom(queryResultBytes.getResultBytes());
160+
} catch (InvalidProtocolBufferException e) {
161+
throw new RuntimeException(e);
162+
}
163+
};
164+
};
165+
166+
/* (non-Javadoc)
167+
* @see org.hyperledger.fabric.shim.ChaincodeStub#getStateByPartialCompositeKey(java.lang.String)
168+
*/
169+
@Override
170+
public QueryResultsIterator<KeyValue> getStateByPartialCompositeKey(String compositeKey) {
171+
return getStateByRange(compositeKey, compositeKey + "\udbff\udfff");
172+
}
173+
138174
/* (non-Javadoc)
139175
* @see org.hyperledger.fabric.shim.ChaincodeStub#createCompositeKey(java.lang.String, java.lang.String[])
140176
*/

0 commit comments

Comments
 (0)