From 5e5d2c8e01728dad15b11fd83126a1d29b961be1 Mon Sep 17 00:00:00 2001 From: Stefan Obermeier Date: Tue, 7 Apr 2020 09:09:10 +0200 Subject: [PATCH] Update java chaincode to be compatible with doc and other implementations (#149) * Use numbers without leading zeroes for key Signed-off-by: Stefan Obermeier * Update chaincode to be compatible with doc. E.g. Return key of the queried record Signed-off-by: Stefan Obermeier * Clean up Use always whitespaces to indent the start of the line Remove unnecessary whitespaces Signed-off-by: Stefan Obermeier --- .../fabric/samples/fabcar/CarQueryResult.java | 67 ++++++++++++++++ .../fabric/samples/fabcar/FabCar.java | 10 +-- .../fabric/samples/fabcar/FabCarTest.java | 76 +++++++++---------- 3 files changed, 110 insertions(+), 43 deletions(-) create mode 100644 chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/CarQueryResult.java diff --git a/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/CarQueryResult.java b/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/CarQueryResult.java new file mode 100644 index 0000000000..74cb6944f7 --- /dev/null +++ b/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/CarQueryResult.java @@ -0,0 +1,67 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +package org.hyperledger.fabric.samples.fabcar; + +import java.util.Objects; + +import org.hyperledger.fabric.contract.annotation.DataType; +import org.hyperledger.fabric.contract.annotation.Property; + +import com.owlike.genson.annotation.JsonProperty; + +/** + * CarQueryResult structure used for handling result of query + * + */ +@DataType() +public final class CarQueryResult { + @Property() + private final String key; + + @Property() + private final Car record; + + public CarQueryResult(@JsonProperty("Key") final String key, @JsonProperty("Record") final Car record) { + this.key = key; + this.record = record; + } + + public String getKey() { + return key; + } + + public Car getRecord() { + return record; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + + if ((obj == null) || (getClass() != obj.getClass())) { + return false; + } + + CarQueryResult other = (CarQueryResult) obj; + + Boolean recordsAreEquals = this.getRecord().equals(other.getRecord()); + Boolean keysAreEquals = this.getKey().equals(other.getKey()); + + return recordsAreEquals && keysAreEquals; + } + + @Override + public int hashCode() { + return Objects.hash(this.getKey(), this.getRecord()); + } + + @Override + public String toString() { + return "{\"Key\":\"" + key + "\"" + "\"Record\":{\"" + record + "}\"}"; + } + +} diff --git a/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/FabCar.java b/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/FabCar.java index a4e8b35394..b267d8012e 100644 --- a/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/FabCar.java +++ b/chaincode/fabcar/java/src/main/java/org/hyperledger/fabric/samples/fabcar/FabCar.java @@ -95,7 +95,7 @@ public void initLedger(final Context ctx) { }; for (int i = 0; i < carData.length; i++) { - String key = String.format("CAR%03d", i); + String key = String.format("CAR%d", i); Car car = genson.deserialize(carData[i], Car.class); String carState = genson.serialize(car); @@ -140,21 +140,21 @@ public Car createCar(final Context ctx, final String key, final String make, fin * @return array of Cars found on the ledger */ @Transaction() - public Car[] queryAllCars(final Context ctx) { + public CarQueryResult[] queryAllCars(final Context ctx) { ChaincodeStub stub = ctx.getStub(); final String startKey = "CAR0"; final String endKey = "CAR999"; - List cars = new ArrayList(); + List queryResults = new ArrayList(); QueryResultsIterator results = stub.getStateByRange(startKey, endKey); for (KeyValue result: results) { Car car = genson.deserialize(result.getStringValue(), Car.class); - cars.add(car); + queryResults.add(new CarQueryResult(result.getKey(), car)); } - Car[] response = cars.toArray(new Car[cars.size()]); + CarQueryResult[] response = queryResults.toArray(new CarQueryResult[queryResults.size()]); return response; } diff --git a/chaincode/fabcar/java/src/test/java/org/hyperledger/fabric/samples/fabcar/FabCarTest.java b/chaincode/fabcar/java/src/test/java/org/hyperledger/fabric/samples/fabcar/FabCarTest.java index 0579a5380c..b52465e737 100644 --- a/chaincode/fabcar/java/src/test/java/org/hyperledger/fabric/samples/fabcar/FabCarTest.java +++ b/chaincode/fabcar/java/src/test/java/org/hyperledger/fabric/samples/fabcar/FabCarTest.java @@ -63,15 +63,15 @@ private final class MockCarResultsIterator implements QueryResultsIterator(); - carList.add(new MockKeyValue("CAR000", + carList.add(new MockKeyValue("CAR0", "{\"color\":\"blue\",\"make\":\"Toyota\",\"model\":\"Prius\",\"owner\":\"Tomoko\"}")); - carList.add(new MockKeyValue("CAR001", + carList.add(new MockKeyValue("CAR1", "{\"color\":\"red\",\"make\":\"Ford\",\"model\":\"Mustang\",\"owner\":\"Brad\"}")); - carList.add(new MockKeyValue("CAR002", + carList.add(new MockKeyValue("CAR2", "{\"color\":\"green\",\"make\":\"Hyundai\",\"model\":\"Tucson\",\"owner\":\"Jin Soo\"}")); - carList.add(new MockKeyValue("CAR007", + carList.add(new MockKeyValue("CAR7", "{\"color\":\"violet\",\"make\":\"Fiat\",\"model\":\"Punto\",\"owner\":\"Pari\"}")); - carList.add(new MockKeyValue("CAR009", + carList.add(new MockKeyValue("CAR9", "{\"color\":\"brown\",\"make\":\"Holden\",\"model\":\"Barina\",\"owner\":\"Shotaro\"}")); } @@ -112,10 +112,10 @@ public void whenCarExists() { Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("CAR000")) + when(stub.getStringState("CAR0")) .thenReturn("{\"color\":\"blue\",\"make\":\"Toyota\",\"model\":\"Prius\",\"owner\":\"Tomoko\"}"); - Car car = contract.queryCar(ctx, "CAR000"); + Car car = contract.queryCar(ctx, "CAR0"); assertThat(car).isEqualTo(new Car("Toyota", "Prius", "blue", "Tomoko")); } @@ -126,14 +126,14 @@ public void whenCarDoesNotExist() { Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("CAR000")).thenReturn(""); + when(stub.getStringState("CAR0")).thenReturn(""); Throwable thrown = catchThrowable(() -> { - contract.queryCar(ctx, "CAR000"); + contract.queryCar(ctx, "CAR0"); }); assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Car CAR000 does not exist"); + .hasMessage("Car CAR0 does not exist"); assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("CAR_NOT_FOUND".getBytes()); } } @@ -148,25 +148,25 @@ void invokeInitLedgerTransaction() { contract.initLedger(ctx); InOrder inOrder = inOrder(stub); - inOrder.verify(stub).putStringState("CAR000", + inOrder.verify(stub).putStringState("CAR0", "{\"color\":\"blue\",\"make\":\"Toyota\",\"model\":\"Prius\",\"owner\":\"Tomoko\"}"); - inOrder.verify(stub).putStringState("CAR001", + inOrder.verify(stub).putStringState("CAR1", "{\"color\":\"red\",\"make\":\"Ford\",\"model\":\"Mustang\",\"owner\":\"Brad\"}"); - inOrder.verify(stub).putStringState("CAR002", + inOrder.verify(stub).putStringState("CAR2", "{\"color\":\"green\",\"make\":\"Hyundai\",\"model\":\"Tucson\",\"owner\":\"Jin Soo\"}"); - inOrder.verify(stub).putStringState("CAR003", + inOrder.verify(stub).putStringState("CAR3", "{\"color\":\"yellow\",\"make\":\"Volkswagen\",\"model\":\"Passat\",\"owner\":\"Max\"}"); - inOrder.verify(stub).putStringState("CAR004", + inOrder.verify(stub).putStringState("CAR4", "{\"color\":\"black\",\"make\":\"Tesla\",\"model\":\"S\",\"owner\":\"Adrian\"}"); - inOrder.verify(stub).putStringState("CAR005", + inOrder.verify(stub).putStringState("CAR5", "{\"color\":\"purple\",\"make\":\"Peugeot\",\"model\":\"205\",\"owner\":\"Michel\"}"); - inOrder.verify(stub).putStringState("CAR006", + inOrder.verify(stub).putStringState("CAR6", "{\"color\":\"white\",\"make\":\"Chery\",\"model\":\"S22L\",\"owner\":\"Aarav\"}"); - inOrder.verify(stub).putStringState("CAR007", + inOrder.verify(stub).putStringState("CAR7", "{\"color\":\"violet\",\"make\":\"Fiat\",\"model\":\"Punto\",\"owner\":\"Pari\"}"); - inOrder.verify(stub).putStringState("CAR008", + inOrder.verify(stub).putStringState("CAR8", "{\"color\":\"indigo\",\"make\":\"Tata\",\"model\":\"nano\",\"owner\":\"Valeria\"}"); - inOrder.verify(stub).putStringState("CAR009", + inOrder.verify(stub).putStringState("CAR9", "{\"color\":\"brown\",\"make\":\"Holden\",\"model\":\"Barina\",\"owner\":\"Shotaro\"}"); } @@ -179,15 +179,15 @@ public void whenCarExists() { Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("CAR000")) + when(stub.getStringState("CAR0")) .thenReturn("{\"color\":\"blue\",\"make\":\"Toyota\",\"model\":\"Prius\",\"owner\":\"Tomoko\"}"); Throwable thrown = catchThrowable(() -> { - contract.createCar(ctx, "CAR000", "Nissan", "Leaf", "green", "Siobhán"); + contract.createCar(ctx, "CAR0", "Nissan", "Leaf", "green", "Siobhán"); }); assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Car CAR000 already exists"); + .hasMessage("Car CAR0 already exists"); assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("CAR_ALREADY_EXISTS".getBytes()); } @@ -197,9 +197,9 @@ public void whenCarDoesNotExist() { Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("CAR000")).thenReturn(""); + when(stub.getStringState("CAR0")).thenReturn(""); - Car car = contract.createCar(ctx, "CAR000", "Nissan", "Leaf", "green", "Siobhán"); + Car car = contract.createCar(ctx, "CAR0", "Nissan", "Leaf", "green", "Siobhán"); assertThat(car).isEqualTo(new Car("Nissan", "Leaf", "green", "Siobhán")); } @@ -213,14 +213,14 @@ void invokeQueryAllCarsTransaction() { when(ctx.getStub()).thenReturn(stub); when(stub.getStateByRange("CAR0", "CAR999")).thenReturn(new MockCarResultsIterator()); - Car[] cars = contract.queryAllCars(ctx); + CarQueryResult[] cars = contract.queryAllCars(ctx); - final List expectedCars = new ArrayList(); - expectedCars.add(new Car("Toyota", "Prius", "blue", "Tomoko")); - expectedCars.add(new Car("Ford", "Mustang", "red", "Brad")); - expectedCars.add(new Car("Hyundai", "Tucson", "green", "Jin Soo")); - expectedCars.add(new Car("Fiat", "Punto", "violet", "Pari")); - expectedCars.add(new Car("Holden", "Barina", "brown", "Shotaro")); + final List expectedCars = new ArrayList(); + expectedCars.add(new CarQueryResult("CAR0", new Car("Toyota", "Prius", "blue", "Tomoko"))); + expectedCars.add(new CarQueryResult("CAR1", new Car("Ford", "Mustang", "red", "Brad"))); + expectedCars.add(new CarQueryResult("CAR2", new Car("Hyundai", "Tucson", "green", "Jin Soo"))); + expectedCars.add(new CarQueryResult("CAR7", new Car("Fiat", "Punto", "violet", "Pari"))); + expectedCars.add(new CarQueryResult("CAR9", new Car("Holden", "Barina", "brown", "Shotaro"))); assertThat(cars).containsExactlyElementsOf(expectedCars); } @@ -234,12 +234,12 @@ public void whenCarExists() { Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("CAR000")) + when(stub.getStringState("CAR0")) .thenReturn("{\"color\":\"blue\",\"make\":\"Toyota\",\"model\":\"Prius\",\"owner\":\"Tomoko\"}"); - Car car = contract.changeCarOwner(ctx, "CAR000", "Dr Evil"); + Car car = contract.changeCarOwner(ctx, "CAR0", "Dr Evil"); - assertThat(car).isEqualTo(new Car("Toyota", "Prius", "blue", "Dr Evil")); + assertThat(car).isEqualTo(new CarQueryResult("CAR0", new Car("Toyota", "Prius", "blue", "Dr Evil"))); } @Test @@ -248,14 +248,14 @@ public void whenCarDoesNotExist() { Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState("CAR000")).thenReturn(""); + when(stub.getStringState("CAR0")).thenReturn(""); Throwable thrown = catchThrowable(() -> { - contract.changeCarOwner(ctx, "CAR000", "Dr Evil"); + contract.changeCarOwner(ctx, "CAR0", "Dr Evil"); }); assertThat(thrown).isInstanceOf(ChaincodeException.class).hasNoCause() - .hasMessage("Car CAR000 does not exist"); + .hasMessage("Car CAR0 does not exist"); assertThat(((ChaincodeException) thrown).getPayload()).isEqualTo("CAR_NOT_FOUND".getBytes()); } }