Skip to content

Commit

Permalink
Update java chaincode to be compatible with doc and other implementat…
Browse files Browse the repository at this point in the history
…ions (#149)

* Use numbers without leading zeroes for key

Signed-off-by: Stefan Obermeier <scray@stefan-obermeier.de>

* Update chaincode to be compatible with doc.

E.g. Return key of the queried record

Signed-off-by: Stefan Obermeier <scray@stefan-obermeier.de>

* Clean up

Use always whitespaces to indent the start of the line
Remove unnecessary whitespaces

Signed-off-by: Stefan Obermeier <scray@stefan-obermeier.de>
  • Loading branch information
obermeier committed Apr 7, 2020
1 parent c572c51 commit 5e5d2c8
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 43 deletions.
Original file line number Diff line number Diff line change
@@ -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 + "}\"}";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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<Car> cars = new ArrayList<Car>();
List<CarQueryResult> queryResults = new ArrayList<CarQueryResult>();

QueryResultsIterator<KeyValue> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,15 +63,15 @@ private final class MockCarResultsIterator implements QueryResultsIterator<KeyVa

carList = new ArrayList<KeyValue>();

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\"}"));
}

Expand Down Expand Up @@ -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"));
}
Expand All @@ -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());
}
}
Expand All @@ -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\"}");
}

Expand All @@ -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());
}

Expand All @@ -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"));
}
Expand All @@ -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<Car> expectedCars = new ArrayList<Car>();
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<CarQueryResult> expectedCars = new ArrayList<CarQueryResult>();
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);
}
Expand All @@ -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
Expand All @@ -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());
}
}
Expand Down

0 comments on commit 5e5d2c8

Please sign in to comment.