From fc2db32f1b54b50362180783a84f2acaf2782988 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 19 Aug 2020 11:34:44 +0200 Subject: [PATCH 01/32] Adjust chaincode to use private data collections MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein Co-authored-by: Anemone Kampkötter --- chaincode/collections_config.json | 10 ++++++++ .../chaincode/MatriculationDataChaincode.java | 24 ++++++++++--------- 2 files changed, 23 insertions(+), 11 deletions(-) create mode 100644 chaincode/collections_config.json diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json new file mode 100644 index 00000000..c2b6fc75 --- /dev/null +++ b/chaincode/collections_config.json @@ -0,0 +1,10 @@ +[ + { + "name": "TestCollection", + "policy": "OR('SampleOrg.member')", + "requiredPeerCount": 0, + "maxPeerCount": 3, + "blockToLive": 0, + "memberOnlyRead": true + } +] \ No newline at end of file diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 24019d0b..4281148f 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -8,6 +8,7 @@ import org.hyperledger.fabric.contract.annotation.Contract; import org.hyperledger.fabric.contract.annotation.Default; import org.hyperledger.fabric.contract.annotation.Transaction; +import org.hyperledger.fabric.shim.Chaincode; import org.hyperledger.fabric.shim.ChaincodeStub; import java.util.ArrayList; @@ -21,6 +22,7 @@ @Default public class MatriculationDataChaincode implements ContractInterface { + private final String collectionName = "TestCollection"; private static Log _logger = LogFactory.getLog(MatriculationDataChaincode.class); // setup gson (de-)serializer capable of (de-)serializing dates private static final GsonWrapper gson = new GsonWrapper(); @@ -51,7 +53,7 @@ public String addMatriculationData(final Context ctx, final String jsonMatricula .title("The given parameter does not conform to the specified format.")); } - String result = stub.getStringState(matriculationData.getMatriculationId()); + String result = stub.getPrivateDataUTF8(collectionName, matriculationData.getMatriculationId()); if (result != null && !result.equals("")) { return gson.toJson(new GenericError() .type("hl: conflict") @@ -67,7 +69,7 @@ public String addMatriculationData(final Context ctx, final String jsonMatricula .invalidParams(invalidParams)); } - stub.putStringState(matriculationData.getMatriculationId(),gson.toJson(matriculationData)); + stub.putPrivateData(collectionName, matriculationData.getMatriculationId(),gson.toJson(matriculationData)); return ""; } @@ -93,15 +95,15 @@ public String updateMatriculationData(final Context ctx, final String jsonMatric .title("The following fields in the given parameters do not conform to the specified format.") .invalidParams(invalidParams)); - String MatriculationDataOnLedger = stub.getStringState(updatedMatriculationData.getMatriculationId()); + String MatriculationDataOnLedger = stub.getPrivateDataUTF8(collectionName, updatedMatriculationData.getMatriculationId()); if(MatriculationDataOnLedger == null || MatriculationDataOnLedger.equals("")) return gson.toJson(new GenericError() .type("hl: not found") .title("There is no MatriculationData for the given matriculationId.")); - stub.delState(updatedMatriculationData.getMatriculationId()); - stub.putStringState(updatedMatriculationData.getMatriculationId(), gson.toJson(updatedMatriculationData)); + stub.delPrivateData(collectionName, updatedMatriculationData.getMatriculationId()); + stub.putPrivateData(collectionName, updatedMatriculationData.getMatriculationId(), gson.toJson(updatedMatriculationData)); return ""; } @@ -112,7 +114,7 @@ public String getMatriculationData(final Context ctx, final String matriculation MatriculationData matriculationData; try { - matriculationData = gson.fromJson(stub.getStringState(matriculationId), MatriculationData.class); + matriculationData = gson.fromJson(stub.getPrivateDataUTF8(collectionName, matriculationId), MatriculationData.class); } catch(Exception e) { return gson.toJson(new GenericError() .type("hl: unprocessable ledger state") @@ -154,7 +156,7 @@ public String addEntryToMatriculationData ( ChaincodeStub stub = ctx.getStub(); - String jsonMatriculationData = stub.getStringState(matriculationId); + String jsonMatriculationData = stub.getPrivateDataUTF8(collectionName, matriculationId); if(jsonMatriculationData == null || jsonMatriculationData.equals("")) return gson.toJson(new GenericError() @@ -178,8 +180,8 @@ public String addEntryToMatriculationData ( return ""; } item.addsemestersItem(semester); - stub.delState(matriculationData.getMatriculationId()); - stub.putStringState(matriculationData.getMatriculationId(), gson.toJson(matriculationData)); + stub.delPrivateData(collectionName, matriculationData.getMatriculationId()); + stub.putPrivateData(collectionName, matriculationData.getMatriculationId(), gson.toJson(matriculationData)); return ""; } } @@ -190,8 +192,8 @@ public String addEntryToMatriculationData ( {{add(semester);}}) ); - stub.delState(matriculationData.getMatriculationId()); - stub.putStringState(matriculationData.getMatriculationId(), gson.toJson(matriculationData)); + stub.delPrivateData(collectionName, matriculationData.getMatriculationId()); + stub.putPrivateData(collectionName, matriculationData.getMatriculationId(), gson.toJson(matriculationData)); return ""; } From b2f2744fabab49ec16a420b9dbbef7132d313947 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 19 Aug 2020 11:58:13 +0200 Subject: [PATCH 02/32] Adjust organization name to work with production network MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niklas Doppelstein Co-authored-by: Anemone Kampkötter Co-authored-by: Marie-Christin Oczko --- chaincode/collections_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index c2b6fc75..5c0bcf66 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('SampleOrg.member')", + "policy": "OR('org0.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, From 992a306febac3cf2e410a49c9aa8efb65b7f5b9e Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 19 Aug 2020 12:10:11 +0200 Subject: [PATCH 03/32] Change to organization, which is actually part of the channel MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein Co-authored-by: Anemone Kampkötter --- chaincode/collections_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index 5c0bcf66..5e79953a 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('org0.member')", + "policy": "OR('org1.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, From a59e3a5808146eb17e136f47156298505f6122a5 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 19 Aug 2020 12:13:19 +0200 Subject: [PATCH 04/32] Reference the organizations id rather than the name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Niklas Doppelstein Co-authored-by: Anemone Kampkötter Co-authored-by: Marie-Christin Oczko --- chaincode/collections_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index 5e79953a..01c9b23d 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('org1.member')", + "policy": "OR('org1MSP.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, From 96b7f42f508e20ad408cda82fc99f3c4bcb81e30 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 19 Aug 2020 16:21:14 +0200 Subject: [PATCH 05/32] Add org2 to collection_config policy, such that both orgs store the private data Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- chaincode/collections_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index 01c9b23d..583599a6 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('org1MSP.member')", + "policy": "OR('org1MSP.member','org2MSP.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, From 87178fecbba754de3c5c8b5af5075c0ff529a47e Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Fri, 21 Aug 2020 12:48:43 +0200 Subject: [PATCH 06/32] Try to remove private data collection transaction args from ledger by moving them to transient data field Co-authored-by: Marie-Christin Oczko --- .../de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 4281148f..21e39a93 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -35,16 +35,17 @@ public void initLedger(final Context ctx) { /** * Adds MatriculationData to the ledger. * @param ctx - * @param jsonMatriculationData json-representation of a MatriculationData to be added + * TODO jsonMatriculationData json-representation of a MatriculationData to be added * @return Empty string on success, serialized error on failure */ @Transaction() - public String addMatriculationData(final Context ctx, final String jsonMatriculationData) { + public String addMatriculationData(final Context ctx) {//, final String jsonMatriculationData) { TODO _logger.info("immatriculateMatriculationData"); ChaincodeStub stub = ctx.getStub(); MatriculationData matriculationData; + String jsonMatriculationData = stub.getTransient().get("0").toString(); try { matriculationData = gson.fromJson(jsonMatriculationData, MatriculationData.class); } catch(Exception e) { From 25fe579c5f9c4261f1c2da5cce3ae6f0883f3989 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Fri, 21 Aug 2020 14:54:08 +0200 Subject: [PATCH 07/32] Attempt to fix conversion from byte array to string Co-authored-by: Marie-Christin Oczko --- .../de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 21e39a93..4162f6b8 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -45,7 +45,7 @@ public String addMatriculationData(final Context ctx) {//, final String jsonMatr ChaincodeStub stub = ctx.getStub(); MatriculationData matriculationData; - String jsonMatriculationData = stub.getTransient().get("0").toString(); + String jsonMatriculationData = new String(stub.getTransient().get("0")); try { matriculationData = gson.fromJson(jsonMatriculationData, MatriculationData.class); } catch(Exception e) { From a8fb7bb8453d6ec64ff0e327ef5b3ff3ec49445d Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 24 Aug 2020 16:07:18 +0200 Subject: [PATCH 08/32] Add tests for adding/updating multiple fields of study at once --- .../AddMatriculationDataTestIO.json | 52 +++++++++++++++ .../UpdateMatriculationDataTestIO.json | 66 +++++++++++++++++++ 2 files changed, 118 insertions(+) diff --git a/chaincode/test_configs/AddMatriculationDataTestIO.json b/chaincode/test_configs/AddMatriculationDataTestIO.json index e8ec0859..d68e3c96 100644 --- a/chaincode/test_configs/AddMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddMatriculationDataTestIO.json @@ -39,6 +39,58 @@ + { + "name": "addNonExistingMultiFieldOfStudyMatriculationData", + "type": "addMatriculationData_SUCCESS", + "setup": [], + "input": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "WS2018/19" + ] + } + ] + } + ], + "compare": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "WS2018/19" + ] + } + ] + } + ] + }, + + + { "name": "addExistingMatriculationData", "type": "addMatriculationData_FAILURE", diff --git a/chaincode/test_configs/UpdateMatriculationDataTestIO.json b/chaincode/test_configs/UpdateMatriculationDataTestIO.json index 83f31243..f4c0f258 100644 --- a/chaincode/test_configs/UpdateMatriculationDataTestIO.json +++ b/chaincode/test_configs/UpdateMatriculationDataTestIO.json @@ -53,6 +53,72 @@ ] }, + { + "name": "updateMultiFieldOfStudyMatriculationData", + "type": "updateMatriculationData_SUCCESS", + "setup": [ + "0000001", + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19", "SS2020" + ] + } + ] + } + ], + "input": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19", "WS2020/21" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "WS2018/19", "WS2020/21" + ] + } + ] + } + ], + "compare": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19", "WS2020/21" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "WS2018/19", "WS2020/21" + ] + } + ] + } + ] + }, + { "name": "updateNonExistingMatriculationData", "type": "updateMatriculationData_FAILURE", From b9ac037cdd00bd5fcf8ade54a2d98b329af3be16 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Fri, 28 Aug 2020 10:57:19 +0200 Subject: [PATCH 09/32] Add index of invalid list entry to name of invalidParam. Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko --- .../chaincode/MatriculationDataChaincode.java | 30 +++++++++------ .../AddMatriculationDataTestIO.json | 8 ++-- .../UpdateMatriculationDataTestIO.json | 38 ++++++++++++------- 3 files changed, 47 insertions(+), 29 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 54e04ecb..0e478d41 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -262,49 +262,55 @@ private ArrayList getErrorForMatriculationData(MatriculationDa ArrayList existingFields = new ArrayList<>(); - for (SubjectMatriculation subMat: matriculationStatus) { + for (int subMatIndex=0; subMatIndex semesters = subMat.getSemesters(); + if (semesters == null || semesters.isEmpty()) { addAbsent(list, new InvalidParameter() - .name("subjectMatriculation.semesters") + .name("matriculationStatus["+subMatIndex+"].semesters") .reason("Semesters must not be empty.")); } + ArrayList existingSemesters = new ArrayList<>(); + for (int semesterIndex=0; semesterIndex Date: Mon, 31 Aug 2020 13:45:57 +0200 Subject: [PATCH 10/32] Adjust transactions to utilize private data collection and transient data field. Adept tests to private data collection and transient data field. Co-authored-by: Marie-Christin Oczko Co-authored-by: Steffen Luis Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 15 +++- .../MatriculationDataChaincodeTest.java | 71 +++++++++++----- .../uc4/chaincode/mock/MockChaincodeStub.java | 80 ++++++++++++++----- .../cs/uc4/chaincode/mock/MockKeyValue.java | 12 +-- .../AddMatriculationDataTestIO.json | 4 +- 5 files changed, 127 insertions(+), 55 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 4162f6b8..a69384a9 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -27,6 +27,10 @@ public class MatriculationDataChaincode implements ContractInterface { // setup gson (de-)serializer capable of (de-)serializing dates private static final GsonWrapper gson = new GsonWrapper(); + public String getCollectionName() { + return collectionName; + } + @Transaction() public void initLedger(final Context ctx) { @@ -39,13 +43,15 @@ public void initLedger(final Context ctx) { * @return Empty string on success, serialized error on failure */ @Transaction() - public String addMatriculationData(final Context ctx) {//, final String jsonMatriculationData) { TODO + public String addMatriculationData(final Context ctx) { _logger.info("immatriculateMatriculationData"); ChaincodeStub stub = ctx.getStub(); - MatriculationData matriculationData; + // read transient args String jsonMatriculationData = new String(stub.getTransient().get("0")); + + MatriculationData matriculationData; try { matriculationData = gson.fromJson(jsonMatriculationData, MatriculationData.class); } catch(Exception e) { @@ -75,10 +81,13 @@ public String addMatriculationData(final Context ctx) {//, final String jsonMatr } @Transaction() - public String updateMatriculationData(final Context ctx, final String jsonMatriculationData) { + public String updateMatriculationData(final Context ctx) { ChaincodeStub stub = ctx.getStub(); + // read transient args + String jsonMatriculationData = new String(stub.getTransient().get("0")); + MatriculationData updatedMatriculationData; try { updatedMatriculationData = gson.fromJson(jsonMatriculationData, MatriculationData.class); diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java index 84c8cdbb..161be224 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java @@ -17,10 +17,11 @@ import java.io.FileNotFoundException; import java.io.FileReader; import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.contentOf; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -114,7 +115,7 @@ static Executable getMatriculationDataTest( ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); if (!setup.isEmpty()) - when(stub.getStringState(setup.get(0).getContent())) + when(stub.getPrivateDataUTF8(contract.getCollectionName(), setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); MatriculationData matriculationData = gson.fromJson( contract.getMatriculationData(ctx, input.get(0).getContent()), @@ -138,13 +139,20 @@ private Executable addMatriculationDataSuccessTest( MockChaincodeStub stub = new MockChaincodeStub(); when(ctx.getStub()).thenReturn(stub); if (!setup.isEmpty()) { - stub.putStringState(setup.get(0).getContent(), setup.get(1).getContent()); + stub.putPrivateData(contract.getCollectionName(), setup.get(0).getContent(), setup.get(1).getContent()); } - contract.addMatriculationData(ctx, input.get(0).getContent()); + stub.setTransient( + input.stream().collect( + Collectors.toMap( + entry -> String.valueOf(input.indexOf(entry)), + entry -> entry.getContent().getBytes()))); + contract.addMatriculationData(ctx); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); - assertThat(stub.putStates.get(0)).isEqualTo(new MockKeyValue( - matriculationData.getMatriculationId(), - compare.get(0).getContent())); + assertThat( + new String(stub.getPrivateData( + contract.getCollectionName(), + matriculationData.getMatriculationId()))) + .isEqualTo(compare.get(0).getContent()); }; } @@ -159,10 +167,15 @@ private Executable addMatriculationDataFailureTest( ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); if (!setup.isEmpty()) { - when(stub.getStringState(setup.get(0).getContent())) + when(stub.getPrivateDataUTF8(contract.getCollectionName(), setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); } - String result = contract.addMatriculationData(ctx, input.get(0).getContent()); + when(stub.getTransient()).thenReturn( + input.stream().collect( + Collectors.toMap( + entry -> String.valueOf(input.indexOf(entry)), + entry -> entry.getContent().getBytes()))); + String result = contract.addMatriculationData(ctx); assertThat(result).isEqualTo(compare.get(0).getContent()); }; } @@ -178,12 +191,19 @@ private Executable updateMatriculationDataSuccessTest( Context ctx = mock(Context.class); MockChaincodeStub stub = new MockChaincodeStub(); when(ctx.getStub()).thenReturn(stub); - stub.putStringState(setup.get(0).getContent(),setup.get(1).getContent()); - contract.updateMatriculationData(ctx, input.get(0).getContent()); + stub.putPrivateData(contract.getCollectionName(), setup.get(0).getContent(), setup.get(1).getContent()); + stub.setTransient( + input.stream().collect( + Collectors.toMap( + entry -> String.valueOf(input.indexOf(entry)), + entry -> entry.getContent().getBytes()))); + contract.updateMatriculationData(ctx); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); - assertThat(stub.putStates.get(0)).isEqualTo(new MockKeyValue( - matriculationData.getMatriculationId(), - compare.get(0).getContent())); + assertThat( + new String(stub.getPrivateData( + contract.getCollectionName(), + matriculationData.getMatriculationId()))) + .isEqualTo(compare.get(0).getContent()); }; } @@ -198,8 +218,13 @@ private Executable updateMatriculationDataFailureTest( Context ctx = mock(Context.class); MockChaincodeStub stub = new MockChaincodeStub(); when(ctx.getStub()).thenReturn(stub); - stub.putStringState(setup.get(0).getContent(),setup.get(1).getContent()); - String result = contract.updateMatriculationData(ctx, input.get(0).getContent()); + stub.putPrivateData(contract.getCollectionName(), setup.get(0).getContent(), setup.get(1).getContent()); + stub.setTransient( + input.stream().collect( + Collectors.toMap( + entry -> String.valueOf(input.indexOf(entry)), + entry -> entry.getContent().getBytes()))); + String result = contract.updateMatriculationData(ctx); assertThat(result).isEqualTo(compare.get(0).getContent()); }; @@ -217,7 +242,7 @@ private Executable addEntryToMatriculationDataSuccessTest( MockChaincodeStub stub = new MockChaincodeStub(); when(ctx.getStub()).thenReturn(stub); if (!setup.isEmpty()) { - stub.putStringState(setup.get(0).getContent(), setup.get(1).getContent()); + stub.putPrivateData(contract.getCollectionName(), setup.get(0).getContent(), setup.get(1).getContent()); } contract.addEntryToMatriculationData( ctx, @@ -225,9 +250,11 @@ private Executable addEntryToMatriculationDataSuccessTest( input.get(1).getContent(), input.get(2).getContent()); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); - assertThat(stub.putStates.get(0)).isEqualTo(new MockKeyValue( - matriculationData.getMatriculationId(), - compare.get(0).getContent())); + assertThat( + new String(stub.getPrivateData( + contract.getCollectionName(), + matriculationData.getMatriculationId()))) + .isEqualTo(compare.get(0).getContent()); }; } @@ -242,7 +269,7 @@ private Executable addEntryToMatriculationDataFailureTest( ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); if (!setup.isEmpty()) { - when(stub.getStringState(setup.get(0).getContent())) + when(stub.getPrivateDataUTF8(contract.getCollectionName(), setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); } String result = contract.addEntryToMatriculationData( diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockChaincodeStub.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockChaincodeStub.java index 974fe4dc..ccb3b71e 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockChaincodeStub.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockChaincodeStub.java @@ -8,30 +8,72 @@ import java.time.Instant; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; public final class MockChaincodeStub implements ChaincodeStub { - public List putStates; - private int index = 0; + private Map> dataCollections; + private String defaultCollection = "default"; + private Map transientMap; public MockChaincodeStub() { - putStates = new ArrayList<>(); + dataCollections = new HashMap<>(); + } + + public void setTransient(Map transientMap) { + this.transientMap = transientMap; + } + + private void putByteState(String collection, String key, byte[] value) { + if (!dataCollections.containsKey(collection)) { + dataCollections.put(collection, new ArrayList<>()); + } + dataCollections.get(collection).add(new MockKeyValue(key, value)); + } + + private void putByteState(String key, byte[] value) { + putByteState(defaultCollection, key, value); + } + + private byte[] getByteState(String collection, String key) { + if (!dataCollections.containsKey(collection)) + return new byte[0]; + for (MockKeyValue keyValue : dataCollections.get(collection)) { + if (keyValue.getKey().equals(key)) + return keyValue.getValue(); + } + return new byte[0]; + } + + private byte[] getByteState(String key) { + return getByteState(defaultCollection, key); + } + + private void delByteState(String collection, String key) { + if (!dataCollections.containsKey(collection)) + return; + for (MockKeyValue keyValue : dataCollections.get(collection)) { + if (keyValue.getKey().equals(key)) { + dataCollections.get(collection).remove(keyValue); + return; + } + } + } + + private void delByteState(String key) { + delByteState(defaultCollection, key); } @Override public void putStringState(String key, String value) { - putStates.add(index++, new MockKeyValue(key, value)); + putByteState(key, value.getBytes()); } @Override public String getStringState(String key) { - for (MockKeyValue keyValue : putStates) { - if (keyValue.getKey().equals(key)) - return keyValue.getStringValue(); - } - return ""; + return getByteState(key).toString(); } @Override @@ -71,7 +113,7 @@ public Chaincode.Response invokeChaincode(String chaincodeName, List arg @Override public byte[] getState(String key) { - return new byte[0]; + return getByteState(key); } @Override @@ -81,7 +123,7 @@ public byte[] getStateValidationParameter(String key) { @Override public void putState(String key, byte[] value) { - + putByteState(key, value); } @Override @@ -91,13 +133,7 @@ public void setStateValidationParameter(String key, byte[] value) { @Override public void delState(String key) { - for (MockKeyValue keyValue : putStates) { - if (keyValue.getKey().equals(key)) { - putStates.remove(keyValue); - index--; - break; - } - } + delByteState(key); } @Override @@ -157,7 +193,7 @@ public QueryResultsIterator getHistoryForKey(String key) { @Override public byte[] getPrivateData(String collection, String key) { - return new byte[0]; + return getByteState(collection, key); } @Override @@ -172,7 +208,7 @@ public byte[] getPrivateDataValidationParameter(String collection, String key) { @Override public void putPrivateData(String collection, String key, byte[] value) { - + putByteState(collection, key, value); } @Override @@ -182,7 +218,7 @@ public void setPrivateDataValidationParameter(String collection, String key, byt @Override public void delPrivateData(String collection, String key) { - + delByteState(collection, key); } @Override @@ -237,7 +273,7 @@ public byte[] getCreator() { @Override public Map getTransient() { - return null; + return transientMap; } @Override diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockKeyValue.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockKeyValue.java index 64524cd0..15446ee0 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockKeyValue.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/mock/MockKeyValue.java @@ -9,9 +9,9 @@ final public class MockKeyValue implements KeyValue { private final String key; - private final String value; + private final byte[] value; - public MockKeyValue(final String key, final String value) { + public MockKeyValue(final String key, final byte[] value) { super(); this.key = key; this.value = value; @@ -24,12 +24,12 @@ public String getKey() { @Override public String getStringValue() { - return this.value; + return this.value.toString(); } @Override public byte[] getValue() { - return this.value.getBytes(); + return this.value; } @Override @@ -44,7 +44,7 @@ public boolean equals(Object o) { GsonWrapper gson = new GsonWrapper(); return Objects.equals(this.key, other.key) && Objects.equals( - gson.fromJson(this.value, MatriculationData.class), - gson.fromJson(other.value, MatriculationData.class)); + gson.fromJson(this.value.toString(), MatriculationData.class), + gson.fromJson(other.value.toString(), MatriculationData.class)); } } \ No newline at end of file diff --git a/chaincode/test_configs/AddMatriculationDataTestIO.json b/chaincode/test_configs/AddMatriculationDataTestIO.json index e8ec0859..8adec2ce 100644 --- a/chaincode/test_configs/AddMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddMatriculationDataTestIO.json @@ -366,7 +366,7 @@ "input": [ { "matriculationId": "0000001", - "firstName": "firstName1

alert(\\\"XSS\\\");

\",\n", + "firstName": "firstName1

alert(\\\"XSS\\\");

\",", "lastName": "lastName1", "birthDate": "2000-07-21", "matriculationStatus": [ @@ -382,7 +382,7 @@ "compare": [ { "matriculationId": "0000001", - "firstName": "firstName1alert(\\\"XSS\\\");\",\n", + "firstName": "firstName1alert(\\\"XSS\\\");\",", "lastName": "lastName1", "birthDate": "2000-07-21", "matriculationStatus": [ From f471cf532ef14d59b29e06a439c727d48f3877b4 Mon Sep 17 00:00:00 2001 From: Niko Bergemann Date: Mon, 31 Aug 2020 18:22:26 +0200 Subject: [PATCH 11/32] Add SampleOrg-Member to collections-config for private datat channel - allow Access for Dev-Network Co-authored-by: Matthias Geuchen --- chaincode/collections_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index 583599a6..7e53cd2e 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('org1MSP.member','org2MSP.member')", + "policy": "OR('org1MSP.member','org2MSP.member','SampleOrg.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, From 60b9974a1faf5187db1e94235c68513ebd5d374c Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 31 Aug 2020 19:01:53 +0200 Subject: [PATCH 12/32] Adjust addEntryToMatriculationData to take list as input (WIP) --- .../de/upb/cs/uc4/chaincode/GsonWrapper.java | 6 + .../chaincode/MatriculationDataChaincode.java | 110 ++++++++++-------- .../MatriculationDataChaincodeTest.java | 6 +- .../AddEntryToMatriculationDataTestIO.json | 68 ++++++++--- 4 files changed, 121 insertions(+), 69 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java index 5b185140..9bb2e343 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java @@ -3,6 +3,7 @@ import com.google.gson.*; import com.google.gson.stream.JsonReader; import de.upb.cs.uc4.chaincode.model.Dummy; +import de.upb.cs.uc4.chaincode.model.SubjectMatriculation; import org.jsoup.Jsoup; import org.jsoup.safety.Whitelist; import org.threeten.bp.LocalDate; @@ -12,6 +13,7 @@ import java.io.FileReader; import java.io.Reader; import java.lang.reflect.Type; +import java.util.ArrayList; public class GsonWrapper { @@ -113,4 +115,8 @@ public T fromJson(Reader reader, Class t) { public T fromJson(Reader reader, Type type) { return gson.fromJson(reader, type); } + + public T fromJson(String json, Type type) { + return gson.fromJson(json, type); + } } diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 0e478d41..12a440bb 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -1,5 +1,6 @@ package de.upb.cs.uc4.chaincode; +import com.google.gson.reflect.TypeToken; import de.upb.cs.uc4.chaincode.model.*; import org.hyperledger.fabric.contract.Context; import org.hyperledger.fabric.contract.ContractInterface; @@ -8,6 +9,7 @@ import org.hyperledger.fabric.contract.annotation.Transaction; import org.hyperledger.fabric.shim.ChaincodeStub; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -140,40 +142,14 @@ public String getMatriculationData(final Context ctx, final String matriculation /** * Adds a semester entry to a fieldOfStudy of MatriculationData on the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. - * @param matriculationId matriculationId of the MatriculationData to add the entry to - * @param fieldOfStudy fieldOfStudy within the MatriculationData to add the entry to - * (must not necessarily already exist when calling this transaction) - * @param semester the semester entry to add to the fieldOfStudy within the MatriculationData + * TODO add param * @return Empty string on success, serialized error on failure */ @Transaction() public String addEntryToMatriculationData ( final Context ctx, final String matriculationId, - final String fieldOfStudy, - final String semester) { - - ArrayList invalidParams = new ArrayList<>(); - SubjectMatriculation.FieldOfStudyEnum fieldOfStudyValue = SubjectMatriculation.FieldOfStudyEnum.fromValue(fieldOfStudy); - - if (fieldOfStudyValue == null) { - invalidParams.add(new InvalidParameter() - .name("fieldOfStudy") - .reason("The given value is not accepted.")); - } - - if (!semesterFormatValid(semester)) { - invalidParams.add(new InvalidParameter() - .name("semester") - .reason("Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"")); - } - - if (!invalidParams.isEmpty()) { - return GSON.toJson(new DetailedError() - .type("hl: unprocessable field") - .title("The following fields in the given parameters do not conform to the specified format.") - .invalidParams(invalidParams)); - } + final String jsonSubjectMatriculation) { ChaincodeStub stub = ctx.getStub(); @@ -195,25 +171,40 @@ public String addEntryToMatriculationData ( .title("The state on the ledger does not conform to the specified format.")); } - for (SubjectMatriculation item: matriculationData.getMatriculationStatus()) { - if (item.getFieldOfStudy() == fieldOfStudyValue) { - for (String existingSemester: item.getSemesters()) { - if (existingSemester.equals(semester)) - return ""; + Type listType = new TypeToken>(){}.getType(); + ArrayList matriculationStatus = GSON.fromJson(jsonSubjectMatriculation, listType); + + ArrayList invalidParams = getErrorForSubjectMatriculationList(matriculationStatus); + + if (!invalidParams.isEmpty()) { + return GSON.toJson(new DetailedError() + .type("hl: unprocessable field") + .title("The following fields in the given parameters do not conform to the specified format.") + .invalidParams(invalidParams)); + } + + // TODO move test for existence into SubjectMatriculation.addSemestersItem + for (SubjectMatriculation newItem: matriculationStatus) { + boolean exists = false; + for (SubjectMatriculation item : matriculationData.getMatriculationStatus()) { + if (item.getFieldOfStudy() == newItem.getFieldOfStudy()) { + exists = true; + for (String newSemester : newItem.getSemesters()) { + if (item.getSemesters().contains(newSemester)) + continue; + item.addsemestersItem(newSemester); + } + } + } + if (!exists) { + SubjectMatriculation item = new SubjectMatriculation().fieldOfStudy(newItem.getFieldOfStudy()); + matriculationData.getMatriculationStatus().add(item); + for (String newSemester : newItem.getSemesters()) { + item.addsemestersItem(newSemester); } - item.addsemestersItem(semester); - stub.delState(matriculationData.getMatriculationId()); - stub.putStringState(matriculationData.getMatriculationId(), GSON.toJson(matriculationData)); - return ""; } } - matriculationData.addMatriculationStatusItem(new SubjectMatriculation() - .fieldOfStudy(fieldOfStudyValue) - .semesters(new ArrayList() - {{add(semester);}}) - ); - stub.delState(matriculationData.getMatriculationId()); stub.putStringState(matriculationData.getMatriculationId(), GSON.toJson(matriculationData)); return ""; @@ -253,10 +244,28 @@ private ArrayList getErrorForMatriculationData(MatriculationDa } List matriculationStatus = matriculationData.getMatriculationStatus(); + list.addAll(getErrorForSubjectMatriculationList( + matriculationStatus, + matriculationData, + "matriculationStatus")); + return list; + } + + private ArrayList getErrorForSubjectMatriculationList( + List matriculationStatus) { + return getErrorForSubjectMatriculationList(matriculationStatus, null, ""); + } + + private ArrayList getErrorForSubjectMatriculationList( + List matriculationStatus, + MatriculationData matriculationData, + String prefix) { // TODO prefix param + + ArrayList list = new ArrayList<>(); if (matriculationStatus == null || matriculationStatus.isEmpty()) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus") + .name(prefix) .reason("Matriculation status must not be empty")); } else { @@ -268,12 +277,12 @@ private ArrayList getErrorForMatriculationData(MatriculationDa if (subMat.getFieldOfStudy() == null) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus["+subMatIndex+"].fieldOfStudy") + .name(prefix+"["+subMatIndex+"].fieldOfStudy") .reason("Field of study must be one of the specified values.")); } else { if (existingFields.contains(subMat.getFieldOfStudy())) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus["+subMatIndex+"].fieldOfStudy") + .name(prefix+"["+subMatIndex+"].fieldOfStudy") .reason("Each field of study must only appear in one matriculationStatus.")); } else existingFields.add(subMat.getFieldOfStudy()); @@ -282,7 +291,7 @@ private ArrayList getErrorForMatriculationData(MatriculationDa List semesters = subMat.getSemesters(); if (semesters == null || semesters.isEmpty()) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus["+subMatIndex+"].semesters") + .name(prefix+"["+subMatIndex+"].semesters") .reason("Semesters must not be empty.")); } @@ -296,13 +305,13 @@ private ArrayList getErrorForMatriculationData(MatriculationDa int semesterYear = Integer.parseInt(semester.substring(2, 6)); if (semesterYear < matriculationData.getBirthDate().getYear()) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus["+subMatIndex+"].semesters["+semesterIndex+"]") + .name(prefix+"["+subMatIndex+"].semesters["+semesterIndex+"]") .reason("Semester must not be earlier than birth date.")); } if (existingSemesters.contains(semester)) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus["+subMatIndex+"].semesters["+semesterIndex+"]") + .name(prefix+"["+subMatIndex+"].semesters["+semesterIndex+"]") .reason("Each semester must only appear once in matriculationStatus.semesters.")); } else existingSemesters.add(semester); @@ -310,13 +319,12 @@ private ArrayList getErrorForMatriculationData(MatriculationDa if (!semesterFormatValid(semester)) { addAbsent(list, new InvalidParameter() - .name("matriculationStatus["+subMatIndex+"].semesters["+semesterIndex+"]") + .name(prefix+"["+subMatIndex+"].semesters["+semesterIndex+"]") .reason("Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"")); } } } } - return list; } diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java index bc675380..f59dedcc 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java @@ -226,8 +226,7 @@ private Executable addEntryToMatriculationDataSuccessTest( contract.addEntryToMatriculationData( ctx, input.get(0).getContent(), - input.get(1).getContent(), - input.get(2).getContent()); + input.get(1).getContent()); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); assertThat(stub.putStates.get(0)).isEqualTo(new MockKeyValue( matriculationData.getMatriculationId(), @@ -254,8 +253,7 @@ private Executable addEntryToMatriculationDataFailureTest( String result = contract.addEntryToMatriculationData( ctx, input.get(0).getContent(), - input.get(1).getContent(), - input.get(2).getContent()); + input.get(1).getContent()); assertThat(result).isEqualTo(compare.get(0).getContent()); }; } diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index 2f8f19c9..b6457dc9 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -21,8 +21,14 @@ ], "input": [ "0000001", - "Computer Science", - "SS2019" + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "SS2019" + ] + } + ] ], "compare": [ { @@ -67,8 +73,14 @@ ], "input": [ "0000001", - "Philosophy", - "SS2019" + [ + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019" + ] + } + ] ], "compare": [ { @@ -118,8 +130,14 @@ ], "input": [ "0000001", - "Computer Science", - "WS2018/19" + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] ], "compare": [ { @@ -163,8 +181,14 @@ ], "input": [ "0000001", - "something invalid", - "WS2018/19" + [ + { + "fieldOfStudy": "something invalid", + "semesters": [ + "WS2018/19" + ] + } + ] ], "compare": [ { @@ -204,8 +228,14 @@ ], "input": [ "0000001", - "Computer Science", - "WS2018/17" + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/17" + ] + } + ] ], "compare": [ { @@ -245,8 +275,14 @@ ], "input": [ "0000002", - "Computer Science", - "WS2018/19" + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] ], "compare": [ { @@ -267,8 +303,12 @@ ], "input": [ "0000001", - "Computer Science", - "WS2018/19" + [ + { + "fieldOfStudy": "Computer Science", + "semesters": "WS2018/19" + } + ] ], "compare": [ { From 6dafbb50a80f7af7172e3773339d53c87c44423a Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Tue, 1 Sep 2020 14:45:08 +0200 Subject: [PATCH 13/32] Fix failing tests Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 43 +++++++++++++------ .../MatriculationDataChaincodeTest.java | 4 +- .../AddEntryToMatriculationDataTestIO.json | 6 +-- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 12a440bb..da9fb385 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -8,6 +8,7 @@ import org.hyperledger.fabric.contract.annotation.Default; import org.hyperledger.fabric.contract.annotation.Transaction; import org.hyperledger.fabric.shim.ChaincodeStub; +import org.threeten.bp.LocalDate; import java.lang.reflect.Type; import java.util.ArrayList; @@ -142,14 +143,15 @@ public String getMatriculationData(final Context ctx, final String matriculation /** * Adds a semester entry to a fieldOfStudy of MatriculationData on the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. - * TODO add param + * @param matriculationId matriculationId to add the matriculations to + * @param listOfSubjectMatriculation list of matriculations * @return Empty string on success, serialized error on failure */ @Transaction() - public String addEntryToMatriculationData ( + public String addEntriesToMatriculationData ( final Context ctx, final String matriculationId, - final String jsonSubjectMatriculation) { + final String listOfSubjectMatriculation) { ChaincodeStub stub = ctx.getStub(); @@ -171,10 +173,23 @@ public String addEntryToMatriculationData ( .title("The state on the ledger does not conform to the specified format.")); } - Type listType = new TypeToken>(){}.getType(); - ArrayList matriculationStatus = GSON.fromJson(jsonSubjectMatriculation, listType); + Type listType = new TypeToken>(){}.getType(); + ArrayList matriculationStatus; + try { + matriculationStatus = GSON.fromJson(listOfSubjectMatriculation, listType); + } catch(Exception e) { + return GSON.toJson(new DetailedError() + .type("hl: unprocessable field") + .title("The following fields in the given parameters do not conform to the specified format.") + .invalidParams(new ArrayList() {{ + add(new InvalidParameter() + .name("listOfSubjectMatriculation") + .reason("The given parameter cannot be parsed from json.")); + }})); + } - ArrayList invalidParams = getErrorForSubjectMatriculationList(matriculationStatus); + ArrayList invalidParams = getErrorForSubjectMatriculationList( + matriculationStatus, matriculationData.getBirthDate(), "listOfSubjectMatriculation"); if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() @@ -183,7 +198,6 @@ public String addEntryToMatriculationData ( .invalidParams(invalidParams)); } - // TODO move test for existence into SubjectMatriculation.addSemestersItem for (SubjectMatriculation newItem: matriculationStatus) { boolean exists = false; for (SubjectMatriculation item : matriculationData.getMatriculationStatus()) { @@ -246,20 +260,21 @@ private ArrayList getErrorForMatriculationData(MatriculationDa List matriculationStatus = matriculationData.getMatriculationStatus(); list.addAll(getErrorForSubjectMatriculationList( matriculationStatus, - matriculationData, + matriculationData.getBirthDate(), "matriculationStatus")); return list; } private ArrayList getErrorForSubjectMatriculationList( - List matriculationStatus) { - return getErrorForSubjectMatriculationList(matriculationStatus, null, ""); + List matriculationStatus, + LocalDate birthDate) { + return getErrorForSubjectMatriculationList(matriculationStatus, birthDate, ""); } private ArrayList getErrorForSubjectMatriculationList( List matriculationStatus, - MatriculationData matriculationData, - String prefix) { // TODO prefix param + LocalDate birthDate, + String prefix) { ArrayList list = new ArrayList<>(); @@ -300,10 +315,10 @@ private ArrayList getErrorForSubjectMatriculationList( String semester = semesters.get(semesterIndex); - if (semesterFormatValid(semester) && matriculationData.getBirthDate() != null) { + if (semesterFormatValid(semester) && birthDate != null) { int semesterYear = Integer.parseInt(semester.substring(2, 6)); - if (semesterYear < matriculationData.getBirthDate().getYear()) { + if (semesterYear < birthDate.getYear()) { addAbsent(list, new InvalidParameter() .name(prefix+"["+subMatIndex+"].semesters["+semesterIndex+"]") .reason("Semester must not be earlier than birth date.")); diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java index f59dedcc..ae01eb64 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java @@ -223,7 +223,7 @@ private Executable addEntryToMatriculationDataSuccessTest( if (!setup.isEmpty()) { stub.putStringState(setup.get(0).getContent(), setup.get(1).getContent()); } - contract.addEntryToMatriculationData( + contract.addEntriesToMatriculationData( ctx, input.get(0).getContent(), input.get(1).getContent()); @@ -250,7 +250,7 @@ private Executable addEntryToMatriculationDataFailureTest( when(stub.getStringState(setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); } - String result = contract.addEntryToMatriculationData( + String result = contract.addEntriesToMatriculationData( ctx, input.get(0).getContent(), input.get(1).getContent()); diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index b6457dc9..20278f76 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -196,8 +196,8 @@ "title": "The following fields in the given parameters do not conform to the specified format.", "invalidParams": [ { - "name": "fieldOfStudy", - "reason": "The given value is not accepted." + "name": "listOfSubjectMatriculation[0].fieldOfStudy", + "reason": "Field of study must be one of the specified values." } ] } @@ -243,7 +243,7 @@ "title": "The following fields in the given parameters do not conform to the specified format.", "invalidParams": [ { - "name": "semester", + "name": "listOfSubjectMatriculation[0].semesters[0]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" } ] From d32ad9d2a316d8afcceee98449c1cd4f4f822a04 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Tue, 1 Sep 2020 15:22:08 +0200 Subject: [PATCH 14/32] Replace *hl: unprocessable entity* without invalid params and *hl: unprocessable fields* with invalid params by *hl: unprocessable entity* with invalid params for refactored api Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 86 +++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index da9fb385..5a686ba2 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -33,29 +33,35 @@ public void initLedger(final Context ctx) { /** * Adds MatriculationData to the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. - * @param jsonMatriculationData json-representation of a MatriculationData to be added + * @param newMatriculationData json-representation of a MatriculationData to be added * @return Empty string on success, serialized error on failure */ @Transaction() - public String addMatriculationData(final Context ctx, final String jsonMatriculationData) { + public String addMatriculationData(final Context ctx, final String newMatriculationData) { ChaincodeStub stub = ctx.getStub(); MatriculationData matriculationData; try { - matriculationData = GSON.fromJson(jsonMatriculationData, MatriculationData.class); + matriculationData = GSON.fromJson(newMatriculationData, MatriculationData.class); } catch(Exception e) { - return GSON.toJson(new GenericError() + return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") - .title("The given parameter does not conform to the specified format.")); + .title("The following parameters do not conform to the specified format.") + .invalidParams(new ArrayList() {{ + add(new InvalidParameter() + .name("newMatriculationData") + .reason("The given parameter cannot be parsed from json.")); + }})); } - ArrayList invalidParams = getErrorForMatriculationData(matriculationData); + ArrayList invalidParams = getErrorForMatriculationData( + matriculationData, "newMatriculationData"); if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable field") - .title("The following fields in the given parameters do not conform to the specified format.") + .type("hl: unprocessable entity") + .title("The following parameters do not conform to the specified format.") .invalidParams(invalidParams)); } @@ -73,33 +79,39 @@ public String addMatriculationData(final Context ctx, final String jsonMatricula /** * Updates MatriculationData on the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. - * @param jsonMatriculationData json-representation of the new MatriculationData to replace the old with + * @param updatedMatriculationData json-representation of the new MatriculationData to replace the old with * @return Empty string on success, serialized error on failure */ @Transaction() - public String updateMatriculationData(final Context ctx, final String jsonMatriculationData) { + public String updateMatriculationData(final Context ctx, final String updatedMatriculationData) { ChaincodeStub stub = ctx.getStub(); - MatriculationData updatedMatriculationData; + MatriculationData matriculationData; try { - updatedMatriculationData = GSON.fromJson(jsonMatriculationData, MatriculationData.class); + matriculationData = GSON.fromJson(updatedMatriculationData, MatriculationData.class); } catch(Exception e) { - return GSON.toJson(new GenericError() - .type("hl: unprocessable entity") - .title("The given parameter does not conform to the specified format.")); + return GSON.toJson(new DetailedError() + .type("hl: unprocessable entity") + .title("The following parameters do not conform to the specified format.") + .invalidParams(new ArrayList() {{ + add(new InvalidParameter() + .name("updatedMatriculationData") + .reason("The given parameter cannot be parsed from json.")); + }})); } - ArrayList invalidParams = getErrorForMatriculationData(updatedMatriculationData); + ArrayList invalidParams = getErrorForMatriculationData( + matriculationData, "updatedMatriculationData"); if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable field") - .title("The following fields in the given parameters do not conform to the specified format.") + .type("hl: unprocessable entity") + .title("The following parameters do not conform to the specified format.") .invalidParams(invalidParams)); } - String MatriculationDataOnLedger = stub.getStringState(updatedMatriculationData.getMatriculationId()); + String MatriculationDataOnLedger = stub.getStringState(matriculationData.getMatriculationId()); if (MatriculationDataOnLedger == null || MatriculationDataOnLedger.equals("")) { return GSON.toJson(new GenericError() @@ -107,8 +119,8 @@ public String updateMatriculationData(final Context ctx, final String jsonMatric .title("There is no MatriculationData for the given matriculationId.")); } - stub.delState(updatedMatriculationData.getMatriculationId()); - stub.putStringState(updatedMatriculationData.getMatriculationId(), GSON.toJson(updatedMatriculationData)); + stub.delState(matriculationData.getMatriculationId()); + stub.putStringState(matriculationData.getMatriculationId(), GSON.toJson(matriculationData)); return ""; } @@ -144,14 +156,14 @@ public String getMatriculationData(final Context ctx, final String matriculation * Adds a semester entry to a fieldOfStudy of MatriculationData on the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. * @param matriculationId matriculationId to add the matriculations to - * @param listOfSubjectMatriculation list of matriculations + * @param matriculations list of matriculations * @return Empty string on success, serialized error on failure */ @Transaction() public String addEntriesToMatriculationData ( final Context ctx, final String matriculationId, - final String listOfSubjectMatriculation) { + final String matriculations) { ChaincodeStub stub = ctx.getStub(); @@ -176,25 +188,25 @@ public String addEntriesToMatriculationData ( Type listType = new TypeToken>(){}.getType(); ArrayList matriculationStatus; try { - matriculationStatus = GSON.fromJson(listOfSubjectMatriculation, listType); + matriculationStatus = GSON.fromJson(matriculations, listType); } catch(Exception e) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable field") - .title("The following fields in the given parameters do not conform to the specified format.") + .type("hl: unprocessable entity") + .title("The following parameters do not conform to the specified format.") .invalidParams(new ArrayList() {{ add(new InvalidParameter() - .name("listOfSubjectMatriculation") + .name("matriculations") .reason("The given parameter cannot be parsed from json.")); }})); } ArrayList invalidParams = getErrorForSubjectMatriculationList( - matriculationStatus, matriculationData.getBirthDate(), "listOfSubjectMatriculation"); + matriculationStatus, matriculationData.getBirthDate(), "matriculations"); if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable field") - .title("The following fields in the given parameters do not conform to the specified format.") + .type("hl: unprocessable entity") + .title("The following parameters do not conform to the specified format.") .invalidParams(invalidParams)); } @@ -229,31 +241,33 @@ public String addEntriesToMatriculationData ( * @param matriculationData matriculationData to return errors for * @return a list of all errors found for the given matriculationData */ - private ArrayList getErrorForMatriculationData(MatriculationData matriculationData) { + private ArrayList getErrorForMatriculationData( + MatriculationData matriculationData, + String prefix) { ArrayList list = new ArrayList<>(); if(matriculationData.getMatriculationId() == null || matriculationData.getMatriculationId().equals("")) { addAbsent(list, new InvalidParameter() - .name("matriculationId") + .name(prefix+"matriculationId") .reason("ID must not be empty")); } if (matriculationData.getFirstName() == null || matriculationData.getFirstName().equals("")) { addAbsent(list, new InvalidParameter() - .name("firstName") + .name(prefix+"firstName") .reason("First name must not be empty")); } if (matriculationData.getLastName() == null || matriculationData.getLastName().equals("")) { addAbsent(list, new InvalidParameter() - .name("lastName") + .name(prefix+"lastName") .reason("Last name must not be empty")); } if (matriculationData.getBirthDate() == null) { addAbsent(list, new InvalidParameter() - .name("birthDate") + .name(prefix+"birthDate") .reason("Birth date must be the following format \"yyyy-mm-dd\"")); } @@ -261,7 +275,7 @@ private ArrayList getErrorForMatriculationData(MatriculationDa list.addAll(getErrorForSubjectMatriculationList( matriculationStatus, matriculationData.getBirthDate(), - "matriculationStatus")); + prefix+"matriculationStatus")); return list; } From ca338d1b296cdd2eff05661a74da1bdee9832e3e Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Tue, 1 Sep 2020 15:53:34 +0200 Subject: [PATCH 15/32] Update test cases to new error format Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 3 + .../AddEntryToMatriculationDataTestIO.json | 12 +-- .../AddMatriculationDataTestIO.json | 68 +++++++------ .../UpdateMatriculationDataTestIO.json | 98 ++++++++++--------- 4 files changed, 98 insertions(+), 83 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 5a686ba2..031e48fe 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -245,6 +245,9 @@ private ArrayList getErrorForMatriculationData( MatriculationData matriculationData, String prefix) { + if (!prefix.equals(null)) + prefix += "."; + ArrayList list = new ArrayList<>(); if(matriculationData.getMatriculationId() == null || matriculationData.getMatriculationId().equals("")) { diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index 20278f76..cd856fee 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -192,11 +192,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "listOfSubjectMatriculation[0].fieldOfStudy", + "name": "matriculations[0].fieldOfStudy", "reason": "Field of study must be one of the specified values." } ] @@ -239,11 +239,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "listOfSubjectMatriculation[0].semesters[0]", + "name": "matriculations[0].semesters[0]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" } ] diff --git a/chaincode/test_configs/AddMatriculationDataTestIO.json b/chaincode/test_configs/AddMatriculationDataTestIO.json index 657c2f10..904ba4e1 100644 --- a/chaincode/test_configs/AddMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddMatriculationDataTestIO.json @@ -159,11 +159,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationId", + "name": "newMatriculationData.matriculationId", "reason": "ID must not be empty" } ] @@ -194,11 +194,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationId", + "name": "newMatriculationData.matriculationId", "reason": "ID must not be empty" } ] @@ -230,11 +230,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "firstName", + "name": "newMatriculationData.firstName", "reason": "First name must not be empty" } ] @@ -266,11 +266,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "lastName", + "name": "newMatriculationData.lastName", "reason": "Last name must not be empty" } ] @@ -302,11 +302,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "birthDate", + "name": "newMatriculationData.birthDate", "reason": "Birth date must be the following format \"yyyy-mm-dd\"" } ] @@ -331,11 +331,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationStatus", + "name": "newMatriculationData.matriculationStatus", "reason": "Matriculation status must not be empty" } ] @@ -365,11 +365,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationStatus[0].semesters", + "name": "newMatriculationData.matriculationStatus[0].semesters", "reason": "Semesters must not be empty." } ] @@ -400,11 +400,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationStatus[0].fieldOfStudy", + "name": "newMatriculationData.matriculationStatus[0].fieldOfStudy", "reason": "Field of study must be one of the specified values." } ] @@ -435,11 +435,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationStatus[0].fieldOfStudy", + "name": "newMatriculationData.matriculationStatus[0].fieldOfStudy", "reason": "Field of study must be one of the specified values." } ] @@ -470,11 +470,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { - "name": "matriculationStatus[0].semesters[0]", + "name": "newMatriculationData.matriculationStatus[0].semesters[0]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" } ] @@ -532,7 +532,13 @@ "compare": [ { "type": "hl: unprocessable entity", - "title": "The given parameter does not conform to the specified format." + "title": "The following parameters do not conform to the specified format.", + "invalidParams": [ + { + "name": "newMatriculationData", + "reason": "The given parameter cannot be parsed from json." + } + ] } ] } diff --git a/chaincode/test_configs/UpdateMatriculationDataTestIO.json b/chaincode/test_configs/UpdateMatriculationDataTestIO.json index 2b157591..bee4c850 100644 --- a/chaincode/test_configs/UpdateMatriculationDataTestIO.json +++ b/chaincode/test_configs/UpdateMatriculationDataTestIO.json @@ -201,11 +201,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "firstName", + "name": "updatedMatriculationData.firstName", "reason": "First name must not be empty" } ] @@ -251,11 +251,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "birthDate", + "name": "updatedMatriculationData.birthDate", "reason": "Birth date must be the following format \"yyyy-mm-dd\"" } ] @@ -301,11 +301,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "lastName", + "name": "updatedMatriculationData.lastName", "reason": "Last name must not be empty" } ] @@ -346,11 +346,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus", + "name": "updatedMatriculationData.matriculationStatus", "reason": "Matriculation status must not be empty" } ] @@ -396,11 +396,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].semesters", + "name": "updatedMatriculationData.matriculationStatus[0].semesters", "reason": "Semesters must not be empty." } ] @@ -448,11 +448,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].fieldOfStudy", + "name": "updatedMatriculationData.matriculationStatus[0].fieldOfStudy", "reason": "Field of study must be one of the specified values." } ] @@ -500,11 +500,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].fieldOfStudy", + "name": "updatedMatriculationData.matriculationStatus[0].fieldOfStudy", "reason": "Field of study must be one of the specified values." } ] @@ -552,11 +552,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].semesters[0]", + "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", "reason": "Semester must not be earlier than birth date." } ] @@ -611,23 +611,23 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].semesters[0]", + "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" }, { - "name": "matriculationStatus[0].semesters[1]", + "name": "updatedMatriculationData.matriculationStatus[0].semesters[1]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" }, { - "name": "matriculationStatus[1].semesters[0]", + "name": "updatedMatriculationData.matriculationStatus[1].semesters[0]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" }, { - "name": "matriculationStatus[1].semesters[1]", + "name": "updatedMatriculationData.matriculationStatus[1].semesters[1]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" } ] @@ -675,11 +675,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].semesters[0]", + "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" } ] @@ -733,11 +733,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[1].fieldOfStudy", + "name": "updatedMatriculationData.matriculationStatus[1].fieldOfStudy", "reason": "Each field of study must only appear in one matriculationStatus." } ] @@ -785,11 +785,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].semesters[2]", + "name": "updatedMatriculationData.matriculationStatus[0].semesters[2]", "reason": "Each semester must only appear once in matriculationStatus.semesters." } ] @@ -837,11 +837,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationId", + "name": "updatedMatriculationData.matriculationId", "reason": "ID must not be empty" } ] @@ -889,11 +889,11 @@ ], "compare": [ { - "type": "hl: unprocessable field", - "title": "The following fields in the given parameters do not conform to the specified format.", + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { - "name": "matriculationStatus[0].semesters[1]", + "name": "updatedMatriculationData.matriculationStatus[0].semesters[1]", "reason": "Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" } ] @@ -929,7 +929,13 @@ "compare": [ { "type": "hl: unprocessable entity", - "title": "The given parameter does not conform to the specified format." + "title": "The following parameters do not conform to the specified format.", + "invalidParams":[ + { + "name": "updatedMatriculationData", + "reason": "The given parameter cannot be parsed from json." + } + ] } ] } From cfe81eaa1bebb575bc436a3e374682f70c358e91 Mon Sep 17 00:00:00 2001 From: Steffen Date: Fri, 4 Sep 2020 11:56:53 +0200 Subject: [PATCH 16/32] added a new test, refactored code Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 21 ++++++---- .../de/upb/cs/uc4/chaincode/chaincode.iml | 11 ++++++ .../AddEntryToMatriculationDataTestIO.json | 38 +++++++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) create mode 100644 chaincode/src/test/java/de/upb/cs/uc4/chaincode/chaincode.iml diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 031e48fe..526a5f77 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -13,6 +13,7 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -25,10 +26,13 @@ public class MatriculationDataChaincode implements ContractInterface { // setup gson (de-)serializer capable of (de-)serializing dates private static final GsonWrapper GSON = new GsonWrapper(); + /* + IntelliJ says this method is never used?! @Transaction() public void initLedger(final Context ctx) { } + **/ /** * Adds MatriculationData to the ledger. @@ -48,7 +52,7 @@ public String addMatriculationData(final Context ctx, final String newMatriculat return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") .title("The following parameters do not conform to the specified format.") - .invalidParams(new ArrayList() {{ + .invalidParams(new ArrayList<>() {{ add(new InvalidParameter() .name("newMatriculationData") .reason("The given parameter cannot be parsed from json.")); @@ -94,7 +98,7 @@ public String updateMatriculationData(final Context ctx, final String updatedMat return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") .title("The following parameters do not conform to the specified format.") - .invalidParams(new ArrayList() {{ + .invalidParams(new ArrayList<>() {{ add(new InvalidParameter() .name("updatedMatriculationData") .reason("The given parameter cannot be parsed from json.")); @@ -193,7 +197,7 @@ public String addEntriesToMatriculationData ( return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") .title("The following parameters do not conform to the specified format.") - .invalidParams(new ArrayList() {{ + .invalidParams(new ArrayList<>() {{ add(new InvalidParameter() .name("matriculations") .reason("The given parameter cannot be parsed from json.")); @@ -245,7 +249,7 @@ private ArrayList getErrorForMatriculationData( MatriculationData matriculationData, String prefix) { - if (!prefix.equals(null)) + if (!prefix.isEmpty()) prefix += "."; ArrayList list = new ArrayList<>(); @@ -282,11 +286,15 @@ private ArrayList getErrorForMatriculationData( return list; } + /* + Also never used? + private ArrayList getErrorForSubjectMatriculationList( List matriculationStatus, LocalDate birthDate) { return getErrorForSubjectMatriculationList(matriculationStatus, birthDate, ""); } + */ private ArrayList getErrorForSubjectMatriculationList( List matriculationStatus, @@ -328,7 +336,7 @@ private ArrayList getErrorForSubjectMatriculationList( } ArrayList existingSemesters = new ArrayList<>(); - for (int semesterIndex=0; semesterIndex + + + + + + + + + + \ No newline at end of file diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index cd856fee..cb86ac91 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -316,5 +316,43 @@ "title": "The state on the ledger does not conform to the specified format." } ] + }, + + { + "name": "addUnprocessableMatriculationDataToEntry", + "type": "addEntryToMatriculationData_FAILURE", + "setup": [ + "0000001", + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] + } + ], + "input": [ + "0000001", + "something unprocessable" + ], + "compare": [ + { + "type": "hl: unprocessable entity", + "title": "The following parameters do not conform to the specified format.", + "invalidParams": [ + { + "name": "matriculations", + "reason": "The given parameter cannot be parsed from json." + } + ] + } + ] } ] \ No newline at end of file From a58d79dea8e4af528030d538699db74f220b2d4c Mon Sep 17 00:00:00 2001 From: nklsd Date: Fri, 4 Sep 2020 12:56:15 +0200 Subject: [PATCH 17/32] Remove falsely pushed file, re-add type argeument to ArrayLists Co-authored-by: Matthias Geuchen --- .../cs/uc4/chaincode/MatriculationDataChaincode.java | 6 +++--- .../test/java/de/upb/cs/uc4/chaincode/chaincode.iml | 11 ----------- 2 files changed, 3 insertions(+), 14 deletions(-) delete mode 100644 chaincode/src/test/java/de/upb/cs/uc4/chaincode/chaincode.iml diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 526a5f77..e81490df 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -52,7 +52,7 @@ public String addMatriculationData(final Context ctx, final String newMatriculat return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") .title("The following parameters do not conform to the specified format.") - .invalidParams(new ArrayList<>() {{ + .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("newMatriculationData") .reason("The given parameter cannot be parsed from json.")); @@ -98,7 +98,7 @@ public String updateMatriculationData(final Context ctx, final String updatedMat return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") .title("The following parameters do not conform to the specified format.") - .invalidParams(new ArrayList<>() {{ + .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("updatedMatriculationData") .reason("The given parameter cannot be parsed from json.")); @@ -197,7 +197,7 @@ public String addEntriesToMatriculationData ( return GSON.toJson(new DetailedError() .type("hl: unprocessable entity") .title("The following parameters do not conform to the specified format.") - .invalidParams(new ArrayList<>() {{ + .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("matriculations") .reason("The given parameter cannot be parsed from json.")); diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/chaincode.iml b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/chaincode.iml deleted file mode 100644 index b107a2dd..00000000 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/chaincode.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file From c2aaa35668d3b7f1537a5252e2389bc54a64bc3f Mon Sep 17 00:00:00 2001 From: nklsd Date: Fri, 4 Sep 2020 13:41:27 +0200 Subject: [PATCH 18/32] Add new testcases for ading multiple entries to matriculationdata Co-authored-by: Marie-Christin Oczko --- .../AddEntryToMatriculationDataTestIO.json | 284 ++++++++++++++++++ 1 file changed, 284 insertions(+) diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index cb86ac91..258a6559 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -157,7 +157,291 @@ ] }, + { + "name": "addTwoEntriesToExistingSubjectOfExistingMatriculationData", + "type": "addEntryToMatriculationData_SUCCESS", + "setup": [ + "0000001", + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] + } + ], + "input": [ + "0000001", + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + } + ] + ], + "compare": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19", + "SS2019" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + } + ] + } + ] + }, + { + "name": "addMultipleEntriesToExistingSubjectOfExistingMatriculationData", + "type": "addEntryToMatriculationData_SUCCESS", + "setup": [ + "0000001", + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] + } + ], + "input": [ + "0000001", + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019" + ] + } + ] + ], + "compare": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19", + "SS2019" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019" + ] + } + ] + } + ] + }, + + { + "name": "addMultipleEntriesToExistingSubjectOfExistingMatriculationData", + "type": "addEntryToMatriculationData_SUCCESS", + "setup": [ + "0000001", + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019" + ] + } + ] + } + ], + "input": [ + "0000001", + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019" + ] + } + ] + ], + "compare": [ + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19", + "SS2019" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "SS2019" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019" + ] + } + ] + } + ] + }, + { + "name": "addMultipleInvalidEntriesToExistingSubjectOfExistingMatriculationData", + "type": "addEntryToMatriculationData_FAILURE", + "setup": [ + "0000001", + { + "matriculationId": "0000001", + "firstName": "firstName1", + "lastName": "lastName1", + "birthDate": "2000-07-21", + "matriculationStatus": [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] + } + ], + "input": [ + "0000001", + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "SS1990" + ] + }, + { + "fieldOfStudy": "Mathematics", + "semesters": [ + "WS2019" + ] + }, + { + "fieldOfStudy": "Philosophy", + "semesters": [ + "SS2019/20" + ] + } + ] + ], + "compare": [ + { + "type":"hl: unprocessable entity", + "title":"The following parameters do not conform to the specified format.", + "invalidParams": [ + { + "name":"matriculations[0].semesters[0]", + "reason":"Semester must not be earlier than birth date." + }, + { + "name":"matriculations[1].semesters[0]", + "reason":"Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" + }, + { + "name":"matriculations[2].semesters[0]", + "reason":"Semester must be the following format \"(WS\\d{4}/\\d{2}|SS\\d{4})\", e.g. \"WS2020/21\"" + } + ] + } + ] + }, { "name": "addInvalidSubjectEntryToExistingMatriculationData", From 76153c4116becd337bc4d2f15514265171460a44 Mon Sep 17 00:00:00 2001 From: niko Date: Fri, 4 Sep 2020 14:46:48 +0200 Subject: [PATCH 19/32] update msp_definition for dev_network MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Matthias Geuchen Co-authored-by: Niklas Doppelstein Co-authored-by: Anemone Kampkötter --- chaincode/collections_config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index 7e53cd2e..fdbff558 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('org1MSP.member','org2MSP.member','SampleOrg.member')", + "policy": "OR('org1MSP.member','org2MSP.member','SampleOrgMSP.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, From 430ea000540fca69aa20e55814fb8effc008f0fe Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 7 Sep 2020 13:22:18 +0200 Subject: [PATCH 20/32] Fix test case Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko --- chaincode/test_configs/AddEntryToMatriculationDataTestIO.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index cd856fee..eb0643c4 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -306,7 +306,9 @@ [ { "fieldOfStudy": "Computer Science", - "semesters": "WS2018/19" + "semesters": [ + "WS2018/19" + ] } ] ], From da333fe7352256dfe8c9f48e31b06f7b610bd8f8 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 7 Sep 2020 13:30:02 +0200 Subject: [PATCH 21/32] Adjust error types to conform to current api specification Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 24 +++++++------- .../AddEntryToMatriculationDataTestIO.json | 12 +++---- .../AddMatriculationDataTestIO.json | 24 +++++++------- .../GetMatriculationDataTestIO.json | 4 +-- .../UpdateMatriculationDataTestIO.json | 32 +++++++++---------- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index e81490df..cf83b86b 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -50,7 +50,7 @@ public String addMatriculationData(final Context ctx, final String newMatriculat matriculationData = GSON.fromJson(newMatriculationData, MatriculationData.class); } catch(Exception e) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable entity") + .type("HLUnprocessableEntity") .title("The following parameters do not conform to the specified format.") .invalidParams(new ArrayList() {{ add(new InvalidParameter() @@ -64,7 +64,7 @@ public String addMatriculationData(final Context ctx, final String newMatriculat if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable entity") + .type("HLUnprocessableEntity") .title("The following parameters do not conform to the specified format.") .invalidParams(invalidParams)); } @@ -72,7 +72,7 @@ public String addMatriculationData(final Context ctx, final String newMatriculat String result = stub.getStringState(matriculationData.getMatriculationId()); if (result != null && !result.equals("")) { return GSON.toJson(new GenericError() - .type("hl: conflict") + .type("HLConflict") .title("There is already a MatriculationData for the given matriculationId.")); } @@ -96,7 +96,7 @@ public String updateMatriculationData(final Context ctx, final String updatedMat matriculationData = GSON.fromJson(updatedMatriculationData, MatriculationData.class); } catch(Exception e) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable entity") + .type("HLUnprocessableEntity") .title("The following parameters do not conform to the specified format.") .invalidParams(new ArrayList() {{ add(new InvalidParameter() @@ -110,7 +110,7 @@ public String updateMatriculationData(final Context ctx, final String updatedMat if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable entity") + .type("HLUnprocessableEntity") .title("The following parameters do not conform to the specified format.") .invalidParams(invalidParams)); } @@ -119,7 +119,7 @@ public String updateMatriculationData(final Context ctx, final String updatedMat if (MatriculationDataOnLedger == null || MatriculationDataOnLedger.equals("")) { return GSON.toJson(new GenericError() - .type("hl: not found") + .type("HLNotFound") .title("There is no MatriculationData for the given matriculationId.")); } @@ -144,13 +144,13 @@ public String getMatriculationData(final Context ctx, final String matriculation matriculationData = GSON.fromJson(stub.getStringState(matriculationId), MatriculationData.class); } catch(Exception e) { return GSON.toJson(new GenericError() - .type("hl: unprocessable ledger state") + .type("HLUnprocessableLedgerState") .title("The state on the ledger does not conform to the specified format.")); } if (matriculationData == null) { return GSON.toJson(new DetailedError() - .type("hl: not found") + .type("HLNotFound") .title("There is no MatriculationData for the given matriculationId.")); } return GSON.toJson(matriculationData); @@ -175,7 +175,7 @@ public String addEntriesToMatriculationData ( if (jsonMatriculationData == null || jsonMatriculationData.equals("")) { return GSON.toJson(new GenericError() - .type("hl: not found") + .type("HLNotFound") .title("There is no MatriculationData for the given matriculationId.")); } @@ -185,7 +185,7 @@ public String addEntriesToMatriculationData ( matriculationData = GSON.fromJson(jsonMatriculationData, MatriculationData.class); } catch(Exception e) { return GSON.toJson(new GenericError() - .type("hl: unprocessable ledger state") + .type("HLUnprocessableLedgerState") .title("The state on the ledger does not conform to the specified format.")); } @@ -195,7 +195,7 @@ public String addEntriesToMatriculationData ( matriculationStatus = GSON.fromJson(matriculations, listType); } catch(Exception e) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable entity") + .type("HLUnprocessableEntity") .title("The following parameters do not conform to the specified format.") .invalidParams(new ArrayList() {{ add(new InvalidParameter() @@ -209,7 +209,7 @@ public String addEntriesToMatriculationData ( if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() - .type("hl: unprocessable entity") + .type("HLUnprocessableEntity") .title("The following parameters do not conform to the specified format.") .invalidParams(invalidParams)); } diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json index 2d83c75c..4127bef9 100644 --- a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json @@ -423,7 +423,7 @@ ], "compare": [ { - "type":"hl: unprocessable entity", + "type":"HLUnprocessableEntity", "title":"The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -476,7 +476,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -523,7 +523,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -570,7 +570,7 @@ ], "compare": [ { - "type": "hl: not found", + "type": "HLNotFound", "title": "There is no MatriculationData for the given matriculationId." } ] @@ -598,7 +598,7 @@ ], "compare": [ { - "type": "hl: unprocessable ledger state", + "type": "HLUnprocessableLedgerState", "title": "The state on the ledger does not conform to the specified format." } ] @@ -630,7 +630,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { diff --git a/chaincode/test_configs/AddMatriculationDataTestIO.json b/chaincode/test_configs/AddMatriculationDataTestIO.json index 904ba4e1..b5cb874f 100644 --- a/chaincode/test_configs/AddMatriculationDataTestIO.json +++ b/chaincode/test_configs/AddMatriculationDataTestIO.json @@ -129,7 +129,7 @@ ], "compare": [ { - "type": "hl: conflict", + "type": "HLConflict", "title": "There is already a MatriculationData for the given matriculationId." } ] @@ -159,7 +159,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -194,7 +194,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -230,7 +230,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -266,7 +266,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -302,7 +302,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -331,7 +331,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -365,7 +365,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -400,7 +400,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -435,7 +435,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -470,7 +470,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { @@ -531,7 +531,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams": [ { diff --git a/chaincode/test_configs/GetMatriculationDataTestIO.json b/chaincode/test_configs/GetMatriculationDataTestIO.json index 23269ae4..11706395 100644 --- a/chaincode/test_configs/GetMatriculationDataTestIO.json +++ b/chaincode/test_configs/GetMatriculationDataTestIO.json @@ -51,7 +51,7 @@ ], "compare": [ { - "type": "hl: not found", + "type": "HLNotFound", "title": "There is no MatriculationData for the given matriculationId." } ] @@ -71,7 +71,7 @@ ], "compare": [ { - "type": "hl: unprocessable ledger state", + "type": "HLUnprocessableLedgerState", "title": "The state on the ledger does not conform to the specified format." } ] diff --git a/chaincode/test_configs/UpdateMatriculationDataTestIO.json b/chaincode/test_configs/UpdateMatriculationDataTestIO.json index bee4c850..4aa5e1cd 100644 --- a/chaincode/test_configs/UpdateMatriculationDataTestIO.json +++ b/chaincode/test_configs/UpdateMatriculationDataTestIO.json @@ -157,7 +157,7 @@ ], "compare": [ { - "type": "hl: not found", + "type": "HLNotFound", "title": "There is no MatriculationData for the given matriculationId." } ] @@ -201,7 +201,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -251,7 +251,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -301,7 +301,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -346,7 +346,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -396,7 +396,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -448,7 +448,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -500,7 +500,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -552,7 +552,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -611,7 +611,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -675,7 +675,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -733,7 +733,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -785,7 +785,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -837,7 +837,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -889,7 +889,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { @@ -928,7 +928,7 @@ ], "compare": [ { - "type": "hl: unprocessable entity", + "type": "HLUnprocessableEntity", "title": "The following parameters do not conform to the specified format.", "invalidParams":[ { From 41397642a6f23b3932b020266d67ed57a5ce6799 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 7 Sep 2020 13:39:31 +0200 Subject: [PATCH 22/32] Add transient args comment to addMatriculationData transaction Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index a69384a9..1c6f0a0c 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -8,7 +8,6 @@ import org.hyperledger.fabric.contract.annotation.Contract; import org.hyperledger.fabric.contract.annotation.Default; import org.hyperledger.fabric.contract.annotation.Transaction; -import org.hyperledger.fabric.shim.Chaincode; import org.hyperledger.fabric.shim.ChaincodeStub; import java.util.ArrayList; @@ -38,8 +37,9 @@ public void initLedger(final Context ctx) { /** * Adds MatriculationData to the ledger. + * Transient params: + * [0] matriculationData json representation of the new matriculation data * @param ctx - * TODO jsonMatriculationData json-representation of a MatriculationData to be added * @return Empty string on success, serialized error on failure */ @Transaction() From 152fe87da90e20bb07644449cbb6fe00f03e7dae Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 7 Sep 2020 13:58:43 +0200 Subject: [PATCH 23/32] Add transient args to transaction parameter comments Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../upb/cs/uc4/chaincode/MatriculationDataChaincode.java | 9 +++++---- .../cs/uc4/chaincode/MatriculationDataChaincodeTest.java | 2 -- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index dfb3df62..46840581 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -35,8 +35,8 @@ public void initLedger(final Context ctx) { /** * Adds MatriculationData to the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. - * Transient params: - * [0] matriculationData json representation of the new matriculation data + * Transient params: + * [0] newMatriculationData json representation of the new matriculation data * @return Empty string on success, serialized error on failure */ @Transaction() @@ -79,6 +79,8 @@ public String addMatriculationData(final Context ctx) { /** * Updates MatriculationData on the ledger. * @param ctx transaction context providing access to ChaincodeStub etc. + * Transient params: + * [0] updatedMatriculationData json-representation of the new MatriculationData to replace the old with * @return Empty string on success, serialized error on failure */ @Transaction() @@ -338,8 +340,7 @@ public boolean semesterFormatValid(String semester) { if ("WS".equals(semester.substring(0,2))) { int year1 = Integer.parseInt(semester.substring(4,6)); int year2 = Integer.parseInt(semester.substring(7,9)); - if (year2 != (year1 + 1) % 100) - return false; + return year2 == (year1 + 1) % 100; } return true; } diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java index cb41aaf3..68078476 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java @@ -3,7 +3,6 @@ import com.google.gson.reflect.TypeToken; import de.upb.cs.uc4.chaincode.mock.MockChaincodeStub; -import de.upb.cs.uc4.chaincode.mock.MockKeyValue; import de.upb.cs.uc4.chaincode.model.Dummy; import de.upb.cs.uc4.chaincode.model.JsonIOTest; import de.upb.cs.uc4.chaincode.model.MatriculationData; @@ -21,7 +20,6 @@ import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.contentOf; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; From 08056b0d9d69d6f8925692ffc9403ff7d5ecd931 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 7 Sep 2020 14:36:19 +0200 Subject: [PATCH 24/32] Update changelog for v0.7.1 Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- CHANGELOG.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2440303..4364dd93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,19 @@ +# [v0.7.1](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.0...v0.7.1) (2020-09-7) + +## Feature +- move sensitive data to transient data field [#17](https://github.com/upb-uc4/hlf-chaincode/pull/17) + +## Bug Fixes +- + +## Refactor +- refactor tests for private data transactions + + +## Usability +- + + # [v0.7.0](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.6.0.1...v0.7.0) (2020-08-31) ## Feature From c3fb6c13b1d907660ca9b48a340e0db8770028cf Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 7 Sep 2020 15:22:10 +0200 Subject: [PATCH 25/32] Delete unused method. Refactor gson wrapper custom (de-)serializer notation. Move test_config to resources. Co-authored-by: Steffen Luis Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../de/upb/cs/uc4/chaincode/GsonWrapper.java | 87 +++++-------------- .../chaincode/MatriculationDataChaincode.java | 10 --- .../MatriculationDataChaincodeTest.java | 15 ++-- .../AddEntryToMatriculationDataTestIO.json | 0 .../AddMatriculationDataTestIO.json | 0 .../GetMatriculationDataTestIO.json | 0 .../UpdateMatriculationDataTestIO.json | 0 7 files changed, 32 insertions(+), 80 deletions(-) rename chaincode/{ => src/test/resources}/test_configs/AddEntryToMatriculationDataTestIO.json (100%) rename chaincode/{ => src/test/resources}/test_configs/AddMatriculationDataTestIO.json (100%) rename chaincode/{ => src/test/resources}/test_configs/GetMatriculationDataTestIO.json (100%) rename chaincode/{ => src/test/resources}/test_configs/UpdateMatriculationDataTestIO.json (100%) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java index 9bb2e343..a8d9c1a0 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/GsonWrapper.java @@ -1,103 +1,64 @@ package de.upb.cs.uc4.chaincode; import com.google.gson.*; -import com.google.gson.stream.JsonReader; import de.upb.cs.uc4.chaincode.model.Dummy; -import de.upb.cs.uc4.chaincode.model.SubjectMatriculation; import org.jsoup.Jsoup; import org.jsoup.safety.Whitelist; import org.threeten.bp.LocalDate; import org.threeten.bp.format.DateTimeFormatter; import org.threeten.bp.format.DateTimeParseException; -import java.io.FileReader; import java.io.Reader; import java.lang.reflect.Type; -import java.util.ArrayList; public class GsonWrapper { private static final Gson gson = new GsonBuilder() .registerTypeAdapter( LocalDate.class, - new JsonDeserializer() { - @Override - public LocalDate deserialize( - JsonElement json, - Type type, - JsonDeserializationContext jsonDeserializationContext - ) throws JsonParseException { - try { - return LocalDate.parse(json.getAsJsonPrimitive().getAsString()); - } catch (DateTimeParseException e) { - return null; - } + (JsonDeserializer) (json, type, jsonDeserializationContext) -> { + try { + return LocalDate.parse(json.getAsJsonPrimitive().getAsString()); + } catch (DateTimeParseException e) { + return null; } }) .registerTypeAdapter( LocalDate.class, - new JsonSerializer() { - @Override - public JsonElement serialize(LocalDate date, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // "yyyy-mm-dd" - } + (JsonSerializer) (date, typeOfSrc, context) -> { + return new JsonPrimitive(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // "yyyy-mm-dd" }) .registerTypeAdapter( Integer.class, - new JsonDeserializer() { - @Override - public Integer deserialize( - JsonElement json, - Type type, - JsonDeserializationContext jsonDeserializationContext - ) throws JsonParseException { - try { - return json.getAsInt(); - } catch (RuntimeException e) { - return null; - } + (JsonDeserializer) (json, type, jsonDeserializationContext) -> { + try { + return json.getAsInt(); + } catch (RuntimeException e) { + return null; } }) .registerTypeAdapter( Dummy.class, - new JsonSerializer() { - @Override - public JsonElement serialize(Dummy dummy, Type typeOfSrc, JsonSerializationContext context) { - return new JsonPrimitive(dummy.getContent()); // "yyyy-mm-dd" - } + (JsonSerializer) (dummy, typeOfSrc, context) -> { + return new JsonPrimitive(dummy.getContent()); // "yyyy-mm-dd" }) .registerTypeAdapter( Dummy.class, - new JsonDeserializer() { - @Override - public Dummy deserialize( - JsonElement json, - Type type, - JsonDeserializationContext jsonDeserializationContext - ) throws JsonParseException { - try { - String s = json.toString(); - if (s.charAt(0) == '"') { - s = s.substring(1, s.length()-1); - } - return new Dummy(s); - } catch (RuntimeException e) { - return null; + (JsonDeserializer) (json, type, jsonDeserializationContext) -> { + try { + String s = json.toString(); + if (s.charAt(0) == '"') { + s = s.substring(1, s.length()-1); } + return new Dummy(s); + } catch (RuntimeException e) { + return null; } }) .registerTypeAdapter( String.class, - new JsonDeserializer() { - @Override - public String deserialize( - JsonElement json, - Type type, - JsonDeserializationContext jsonDeserializationContext - ) throws JsonParseException { - return Jsoup.clean(json.getAsJsonPrimitive().getAsString(), Whitelist.none()); - } - }) + (JsonDeserializer) (json, type, jsonDeserializationContext) -> + Jsoup.clean(json.getAsJsonPrimitive().getAsString(), Whitelist.none())) .create(); public T fromJson(String json, Class t) throws JsonSyntaxException { diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 27616bd8..bb418748 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -296,16 +296,6 @@ private ArrayList getErrorForMatriculationData( return list; } - /* - Also never used? - - private ArrayList getErrorForSubjectMatriculationList( - List matriculationStatus, - LocalDate birthDate) { - return getErrorForSubjectMatriculationList(matriculationStatus, birthDate, ""); - } - */ - private ArrayList getErrorForSubjectMatriculationList( List matriculationStatus, LocalDate birthDate, diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java index 1094f652..6d871124 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java @@ -27,7 +27,8 @@ public final class MatriculationDataChaincodeTest { @TestFactory List createTests() { - File dir = new File("test_configs"); + String testConfigDir = "src/test/resources/test_configs"; + File dir = new File(testConfigDir); File[] testConfigs = dir.listFiles(); GsonWrapper gson = new GsonWrapper(); @@ -149,9 +150,9 @@ private Executable addMatriculationDataSuccessTest( contract.addMatriculationData(ctx); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); assertThat( - new String(stub.getPrivateDataUTF8( + stub.getPrivateDataUTF8( contract.getCollectionName(), - matriculationData.getMatriculationId()))) + matriculationData.getMatriculationId())) .isEqualTo(compare.get(0).getContent()); }; } @@ -202,9 +203,9 @@ private Executable updateMatriculationDataSuccessTest( contract.updateMatriculationData(ctx); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); assertThat( - new String(stub.getPrivateDataUTF8( + stub.getPrivateDataUTF8( contract.getCollectionName(), - matriculationData.getMatriculationId()))) + matriculationData.getMatriculationId())) .isEqualTo(compare.get(0).getContent()); }; @@ -252,9 +253,9 @@ private Executable addEntryToMatriculationDataSuccessTest( input.get(1).getContent()); MatriculationData matriculationData = gson.fromJson(compare.get(0).getContent(), MatriculationData.class); assertThat( - new String(stub.getPrivateDataUTF8( + stub.getPrivateDataUTF8( contract.getCollectionName(), - matriculationData.getMatriculationId()))) + matriculationData.getMatriculationId())) .isEqualTo(compare.get(0).getContent()); }; } diff --git a/chaincode/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json similarity index 100% rename from chaincode/test_configs/AddEntryToMatriculationDataTestIO.json rename to chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json diff --git a/chaincode/test_configs/AddMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json similarity index 100% rename from chaincode/test_configs/AddMatriculationDataTestIO.json rename to chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json diff --git a/chaincode/test_configs/GetMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/GetMatriculationDataTestIO.json similarity index 100% rename from chaincode/test_configs/GetMatriculationDataTestIO.json rename to chaincode/src/test/resources/test_configs/GetMatriculationDataTestIO.json diff --git a/chaincode/test_configs/UpdateMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json similarity index 100% rename from chaincode/test_configs/UpdateMatriculationDataTestIO.json rename to chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json From 247c6e8c404dc86d77908849c1835576e0358d83 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 9 Sep 2020 10:08:23 +0200 Subject: [PATCH 26/32] Remove colon from title. Co-authored-by: Niklas Doppelstein Co-authored-by: Marie-Christin Oczko --- .../chaincode/MatriculationDataChaincode.java | 24 +++++++------- .../AddEntryToMatriculationDataTestIO.json | 12 +++---- .../AddMatriculationDataTestIO.json | 24 +++++++------- .../GetMatriculationDataTestIO.json | 4 +-- .../UpdateMatriculationDataTestIO.json | 32 +++++++++---------- 5 files changed, 48 insertions(+), 48 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index bb418748..452f6199 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -57,7 +57,7 @@ public String addMatriculationData(final Context ctx) { } catch(Exception e) { return GSON.toJson(new DetailedError() .type("HLUnprocessableEntity") - .title("The following parameters do not conform to the specified format.") + .title("The following parameters do not conform to the specified format") .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("newMatriculationData") @@ -71,7 +71,7 @@ public String addMatriculationData(final Context ctx) { if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() .type("HLUnprocessableEntity") - .title("The following parameters do not conform to the specified format.") + .title("The following parameters do not conform to the specified format") .invalidParams(invalidParams)); } @@ -79,7 +79,7 @@ public String addMatriculationData(final Context ctx) { if (result != null && !result.equals("")) { return GSON.toJson(new GenericError() .type("HLConflict") - .title("There is already a MatriculationData for the given matriculationId.")); + .title("There is already a MatriculationData for the given matriculationId")); } stub.putPrivateData(collectionName, matriculationData.getMatriculationId(),GSON.toJson(matriculationData)); @@ -107,7 +107,7 @@ public String updateMatriculationData(final Context ctx) { } catch(Exception e) { return GSON.toJson(new DetailedError() .type("HLUnprocessableEntity") - .title("The following parameters do not conform to the specified format.") + .title("The following parameters do not conform to the specified format") .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("updatedMatriculationData") @@ -121,7 +121,7 @@ public String updateMatriculationData(final Context ctx) { if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() .type("HLUnprocessableEntity") - .title("The following parameters do not conform to the specified format.") + .title("The following parameters do not conform to the specified format") .invalidParams(invalidParams)); } @@ -130,7 +130,7 @@ public String updateMatriculationData(final Context ctx) { if (MatriculationDataOnLedger == null || MatriculationDataOnLedger.equals("")) { return GSON.toJson(new GenericError() .type("HLNotFound") - .title("There is no MatriculationData for the given matriculationId.")); + .title("There is no MatriculationData for the given matriculationId")); } stub.delPrivateData(collectionName, matriculationData.getMatriculationId()); @@ -155,13 +155,13 @@ public String getMatriculationData(final Context ctx, final String matriculation } catch(Exception e) { return GSON.toJson(new GenericError() .type("HLUnprocessableLedgerState") - .title("The state on the ledger does not conform to the specified format.")); + .title("The state on the ledger does not conform to the specified format")); } if (matriculationData == null) { return GSON.toJson(new DetailedError() .type("HLNotFound") - .title("There is no MatriculationData for the given matriculationId.")); + .title("There is no MatriculationData for the given matriculationId")); } return GSON.toJson(matriculationData); } @@ -186,7 +186,7 @@ public String addEntriesToMatriculationData ( if (jsonMatriculationData == null || jsonMatriculationData.equals("")) { return GSON.toJson(new GenericError() .type("HLNotFound") - .title("There is no MatriculationData for the given matriculationId.")); + .title("There is no MatriculationData for the given matriculationId")); } MatriculationData matriculationData; @@ -196,7 +196,7 @@ public String addEntriesToMatriculationData ( } catch(Exception e) { return GSON.toJson(new GenericError() .type("HLUnprocessableLedgerState") - .title("The state on the ledger does not conform to the specified format.")); + .title("The state on the ledger does not conform to the specified format")); } Type listType = new TypeToken>(){}.getType(); @@ -206,7 +206,7 @@ public String addEntriesToMatriculationData ( } catch(Exception e) { return GSON.toJson(new DetailedError() .type("HLUnprocessableEntity") - .title("The following parameters do not conform to the specified format.") + .title("The following parameters do not conform to the specified format") .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("matriculations") @@ -220,7 +220,7 @@ public String addEntriesToMatriculationData ( if (!invalidParams.isEmpty()) { return GSON.toJson(new DetailedError() .type("HLUnprocessableEntity") - .title("The following parameters do not conform to the specified format.") + .title("The following parameters do not conform to the specified format") .invalidParams(invalidParams)); } diff --git a/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json index 4127bef9..2891e610 100644 --- a/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json @@ -424,7 +424,7 @@ "compare": [ { "type":"HLUnprocessableEntity", - "title":"The following parameters do not conform to the specified format.", + "title":"The following parameters do not conform to the specified format", "invalidParams": [ { "name":"matriculations[0].semesters[0]", @@ -477,7 +477,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "matriculations[0].fieldOfStudy", @@ -524,7 +524,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "matriculations[0].semesters[0]", @@ -571,7 +571,7 @@ "compare": [ { "type": "HLNotFound", - "title": "There is no MatriculationData for the given matriculationId." + "title": "There is no MatriculationData for the given matriculationId" } ] }, @@ -599,7 +599,7 @@ "compare": [ { "type": "HLUnprocessableLedgerState", - "title": "The state on the ledger does not conform to the specified format." + "title": "The state on the ledger does not conform to the specified format" } ] }, @@ -631,7 +631,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "matriculations", diff --git a/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json index 11de81b4..d90205a8 100644 --- a/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json @@ -130,7 +130,7 @@ "compare": [ { "type": "HLConflict", - "title": "There is already a MatriculationData for the given matriculationId." + "title": "There is already a MatriculationData for the given matriculationId" } ] }, @@ -160,7 +160,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationId", @@ -195,7 +195,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationId", @@ -231,7 +231,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.firstName", @@ -267,7 +267,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.lastName", @@ -303,7 +303,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.birthDate", @@ -332,7 +332,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationStatus", @@ -366,7 +366,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].semesters", @@ -401,7 +401,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].fieldOfStudy", @@ -436,7 +436,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].fieldOfStudy", @@ -471,7 +471,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].semesters[0]", @@ -532,7 +532,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams": [ { "name": "newMatriculationData", diff --git a/chaincode/src/test/resources/test_configs/GetMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/GetMatriculationDataTestIO.json index 11706395..233eb47a 100644 --- a/chaincode/src/test/resources/test_configs/GetMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/GetMatriculationDataTestIO.json @@ -52,7 +52,7 @@ "compare": [ { "type": "HLNotFound", - "title": "There is no MatriculationData for the given matriculationId." + "title": "There is no MatriculationData for the given matriculationId" } ] }, @@ -72,7 +72,7 @@ "compare": [ { "type": "HLUnprocessableLedgerState", - "title": "The state on the ledger does not conform to the specified format." + "title": "The state on the ledger does not conform to the specified format" } ] } diff --git a/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json index 4aa5e1cd..ba27312f 100644 --- a/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json @@ -158,7 +158,7 @@ "compare": [ { "type": "HLNotFound", - "title": "There is no MatriculationData for the given matriculationId." + "title": "There is no MatriculationData for the given matriculationId" } ] }, @@ -202,7 +202,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.firstName", @@ -252,7 +252,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.birthDate", @@ -302,7 +302,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.lastName", @@ -347,7 +347,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus", @@ -397,7 +397,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters", @@ -449,7 +449,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].fieldOfStudy", @@ -501,7 +501,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].fieldOfStudy", @@ -553,7 +553,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", @@ -612,7 +612,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", @@ -676,7 +676,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", @@ -734,7 +734,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[1].fieldOfStudy", @@ -786,7 +786,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[2]", @@ -838,7 +838,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationId", @@ -890,7 +890,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[1]", @@ -929,7 +929,7 @@ "compare": [ { "type": "HLUnprocessableEntity", - "title": "The following parameters do not conform to the specified format.", + "title": "The following parameters do not conform to the specified format", "invalidParams":[ { "name": "updatedMatriculationData", From 7e1735a5c4865349f91d4915983f0135b84288ca Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 9 Sep 2020 10:12:28 +0200 Subject: [PATCH 27/32] Remove colon from reason field of invalidParam Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein --- .../chaincode/MatriculationDataChaincode.java | 16 ++++++++-------- .../AddEntryToMatriculationDataTestIO.json | 6 +++--- .../test_configs/AddMatriculationDataTestIO.json | 8 ++++---- .../UpdateMatriculationDataTestIO.json | 14 +++++++------- 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 452f6199..5cdae125 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -61,7 +61,7 @@ public String addMatriculationData(final Context ctx) { .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("newMatriculationData") - .reason("The given parameter cannot be parsed from json.")); + .reason("The given parameter cannot be parsed from json")); }})); } @@ -111,7 +111,7 @@ public String updateMatriculationData(final Context ctx) { .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("updatedMatriculationData") - .reason("The given parameter cannot be parsed from json.")); + .reason("The given parameter cannot be parsed from json")); }})); } @@ -210,7 +210,7 @@ public String addEntriesToMatriculationData ( .invalidParams(new ArrayList() {{ add(new InvalidParameter() .name("matriculations") - .reason("The given parameter cannot be parsed from json.")); + .reason("The given parameter cannot be parsed from json")); }})); } @@ -318,12 +318,12 @@ private ArrayList getErrorForSubjectMatriculationList( if (subMat.getFieldOfStudy() == null) { addAbsent(list, new InvalidParameter() .name(prefix+"["+subMatIndex+"].fieldOfStudy") - .reason("Field of study must be one of the specified values.")); + .reason("Field of study must be one of the specified values")); } else { if (existingFields.contains(subMat.getFieldOfStudy())) { addAbsent(list, new InvalidParameter() .name(prefix+"["+subMatIndex+"].fieldOfStudy") - .reason("Each field of study must only appear in one matriculationStatus.")); + .reason("Each field of study must only appear in one matriculationStatus")); } else existingFields.add(subMat.getFieldOfStudy()); } @@ -332,7 +332,7 @@ private ArrayList getErrorForSubjectMatriculationList( if (semesters == null || semesters.isEmpty()) { addAbsent(list, new InvalidParameter() .name(prefix+"["+subMatIndex+"].semesters") - .reason("Semesters must not be empty.")); + .reason("Semesters must not be empty")); } ArrayList existingSemesters = new ArrayList<>(); @@ -346,13 +346,13 @@ private ArrayList getErrorForSubjectMatriculationList( if (semesterYear < birthDate.getYear()) { addAbsent(list, new InvalidParameter() .name(prefix+"["+subMatIndex+"].semesters["+semesterIndex+"]") - .reason("Semester must not be earlier than birth date.")); + .reason("Semester must not be earlier than birth date")); } if (existingSemesters.contains(semester)) { addAbsent(list, new InvalidParameter() .name(prefix+"["+subMatIndex+"].semesters["+semesterIndex+"]") - .reason("Each semester must only appear once in matriculationStatus.semesters.")); + .reason("Each semester must only appear once in matriculationStatus.semesters")); } else existingSemesters.add(semester); } diff --git a/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json index 2891e610..0edbfe32 100644 --- a/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json @@ -428,7 +428,7 @@ "invalidParams": [ { "name":"matriculations[0].semesters[0]", - "reason":"Semester must not be earlier than birth date." + "reason":"Semester must not be earlier than birth date" }, { "name":"matriculations[1].semesters[0]", @@ -481,7 +481,7 @@ "invalidParams": [ { "name": "matriculations[0].fieldOfStudy", - "reason": "Field of study must be one of the specified values." + "reason": "Field of study must be one of the specified values" } ] } @@ -635,7 +635,7 @@ "invalidParams": [ { "name": "matriculations", - "reason": "The given parameter cannot be parsed from json." + "reason": "The given parameter cannot be parsed from json" } ] } diff --git a/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json index d90205a8..61427e4d 100644 --- a/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/AddMatriculationDataTestIO.json @@ -370,7 +370,7 @@ "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].semesters", - "reason": "Semesters must not be empty." + "reason": "Semesters must not be empty" } ] } @@ -405,7 +405,7 @@ "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].fieldOfStudy", - "reason": "Field of study must be one of the specified values." + "reason": "Field of study must be one of the specified values" } ] } @@ -440,7 +440,7 @@ "invalidParams": [ { "name": "newMatriculationData.matriculationStatus[0].fieldOfStudy", - "reason": "Field of study must be one of the specified values." + "reason": "Field of study must be one of the specified values" } ] } @@ -536,7 +536,7 @@ "invalidParams": [ { "name": "newMatriculationData", - "reason": "The given parameter cannot be parsed from json." + "reason": "The given parameter cannot be parsed from json" } ] } diff --git a/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json index ba27312f..ebe648ce 100644 --- a/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/UpdateMatriculationDataTestIO.json @@ -401,7 +401,7 @@ "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters", - "reason": "Semesters must not be empty." + "reason": "Semesters must not be empty" } ] } @@ -453,7 +453,7 @@ "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].fieldOfStudy", - "reason": "Field of study must be one of the specified values." + "reason": "Field of study must be one of the specified values" } ] } @@ -505,7 +505,7 @@ "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].fieldOfStudy", - "reason": "Field of study must be one of the specified values." + "reason": "Field of study must be one of the specified values" } ] } @@ -557,7 +557,7 @@ "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[0]", - "reason": "Semester must not be earlier than birth date." + "reason": "Semester must not be earlier than birth date" } ] } @@ -738,7 +738,7 @@ "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[1].fieldOfStudy", - "reason": "Each field of study must only appear in one matriculationStatus." + "reason": "Each field of study must only appear in one matriculationStatus" } ] } @@ -790,7 +790,7 @@ "invalidParams":[ { "name": "updatedMatriculationData.matriculationStatus[0].semesters[2]", - "reason": "Each semester must only appear once in matriculationStatus.semesters." + "reason": "Each semester must only appear once in matriculationStatus.semesters" } ] } @@ -933,7 +933,7 @@ "invalidParams":[ { "name": "updatedMatriculationData", - "reason": "The given parameter cannot be parsed from json." + "reason": "The given parameter cannot be parsed from json" } ] } From 8f6e77e47db0de44a609f833c6e0b6a3cf89109e Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 9 Sep 2020 12:45:24 +0200 Subject: [PATCH 28/32] Add collections_config for dev network. Remove non-existing msp from production collections_config. Co-authored-by: Marie-Christin Oczko Co-authored-by: Niklas Doppelstein Co-authored-by: Paul Kramer --- chaincode/collections_config.json | 2 +- chaincode/collections_config_dev.json | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 chaincode/collections_config_dev.json diff --git a/chaincode/collections_config.json b/chaincode/collections_config.json index fdbff558..583599a6 100644 --- a/chaincode/collections_config.json +++ b/chaincode/collections_config.json @@ -1,7 +1,7 @@ [ { "name": "TestCollection", - "policy": "OR('org1MSP.member','org2MSP.member','SampleOrgMSP.member')", + "policy": "OR('org1MSP.member','org2MSP.member')", "requiredPeerCount": 0, "maxPeerCount": 3, "blockToLive": 0, diff --git a/chaincode/collections_config_dev.json b/chaincode/collections_config_dev.json new file mode 100644 index 00000000..9850717c --- /dev/null +++ b/chaincode/collections_config_dev.json @@ -0,0 +1,10 @@ +[ + { + "name": "TestCollection", + "policy": "OR('SampleOrgMSP.member')", + "requiredPeerCount": 0, + "maxPeerCount": 3, + "blockToLive": 0, + "memberOnlyRead": true + } +] \ No newline at end of file From f3b4b2ce8281fa6fcfb99f10de84f5d10b364cc6 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Wed, 9 Sep 2020 13:49:38 +0200 Subject: [PATCH 29/32] Update changelog v0.7.2 Co-authored-by: Niklas Doppelstein --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4364dd93..bda691c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +# [v0.7.2](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.1...v0.7.2) (2020-09-9) + +## Feature +- + +## Bug Fixes +- split up *collections_config* for dev/production network [#21](https://github.com/upb-uc4/hlf-chaincode/pull/21) + +## Refactor +- refactor ```addEntryToMatriculation``` to take list of entries [#20](https://github.com/upb-uc4/hlf-chaincode/pull/20) +- refactor error format to conform to api [#37](https://github.com/upb-uc4/api/pull/37), [#39](https://github.com/upb-uc4/api/pull/39) + + +## Usability +- + + # [v0.7.1](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.0...v0.7.1) (2020-09-7) ## Feature From 7669ea889fc99eaa3aa89affef65b3e2e80bd3aa Mon Sep 17 00:00:00 2001 From: Niko Bergemann Date: Sat, 12 Sep 2020 11:41:55 +0200 Subject: [PATCH 30/32] attempt at solving issue of not recognizing nonexistent MatId in Collection --- .../uc4/chaincode/MatriculationDataChaincode.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java index 5cdae125..20463dea 100755 --- a/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java +++ b/chaincode/src/main/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincode.java @@ -181,14 +181,22 @@ public String addEntriesToMatriculationData ( ChaincodeStub stub = ctx.getStub(); - String jsonMatriculationData = stub.getPrivateDataUTF8(collectionName, matriculationId); - + // retrieve jsonMatriculationData + String jsonMatriculationData; + try { + jsonMatriculationData = stub.getPrivateDataUTF8(collectionName, matriculationId); + } catch(Exception e) { + return GSON.toJson(new GenericError() + .type("HLNotFound") + .title("There is no MatriculationData for the given matriculationId")); + } if (jsonMatriculationData == null || jsonMatriculationData.equals("")) { return GSON.toJson(new GenericError() .type("HLNotFound") .title("There is no MatriculationData for the given matriculationId")); } + // retrieve MatriculationData Object MatriculationData matriculationData; try { @@ -199,6 +207,7 @@ public String addEntriesToMatriculationData ( .title("The state on the ledger does not conform to the specified format")); } + // manipulate object as intended Type listType = new TypeToken>(){}.getType(); ArrayList matriculationStatus; try { From 2052b418ac4ddda3abad3bdc6c0d67f6a1891a43 Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Sat, 12 Sep 2020 16:38:45 +0200 Subject: [PATCH 31/32] Fix tests not throwing error when querying the private data collection for empty string --- .../MatriculationDataChaincodeTest.java | 12 +++++----- .../AddEntryToMatriculationDataTestIO.json | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java index 6d871124..d51574c6 100644 --- a/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java +++ b/chaincode/src/test/java/de/upb/cs/uc4/chaincode/MatriculationDataChaincodeTest.java @@ -113,8 +113,8 @@ static Executable getMatriculationDataTest( Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState(null)).thenThrow(new RuntimeException()); - when(stub.getStringState("")).thenThrow(new RuntimeException()); + when(stub.getPrivateDataUTF8(contract.getCollectionName(),null)).thenThrow(new RuntimeException()); + when(stub.getPrivateDataUTF8(contract.getCollectionName(),"")).thenThrow(new RuntimeException()); if (!setup.isEmpty()) when(stub.getPrivateDataUTF8(contract.getCollectionName(), setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); @@ -167,8 +167,8 @@ private Executable addMatriculationDataFailureTest( Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState(null)).thenThrow(new RuntimeException()); - when(stub.getStringState("")).thenThrow(new RuntimeException()); + when(stub.getPrivateDataUTF8(contract.getCollectionName(),null)).thenThrow(new RuntimeException()); + when(stub.getPrivateDataUTF8(contract.getCollectionName(),"")).thenThrow(new RuntimeException()); if (!setup.isEmpty()) { when(stub.getPrivateDataUTF8(contract.getCollectionName(), setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); @@ -270,8 +270,8 @@ private Executable addEntryToMatriculationDataFailureTest( Context ctx = mock(Context.class); ChaincodeStub stub = mock(ChaincodeStub.class); when(ctx.getStub()).thenReturn(stub); - when(stub.getStringState(null)).thenThrow(new RuntimeException()); - when(stub.getStringState("")).thenThrow(new RuntimeException()); + when(stub.getPrivateDataUTF8(contract.getCollectionName(), null)).thenThrow(new RuntimeException()); + when(stub.getPrivateDataUTF8(contract.getCollectionName(),"")).thenThrow(new RuntimeException()); if (!setup.isEmpty()) { when(stub.getPrivateDataUTF8(contract.getCollectionName(), setup.get(0).getContent())) .thenReturn(setup.get(1).getContent()); diff --git a/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json index 0edbfe32..42291ef9 100644 --- a/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json +++ b/chaincode/src/test/resources/test_configs/AddEntryToMatriculationDataTestIO.json @@ -577,6 +577,30 @@ }, + { + "name": "addEmptyMatriculationIdEntryToMatriculationData", + "type": "addEntryToMatriculationData_FAILURE", + "setup": [], + "input": [ + "", + [ + { + "fieldOfStudy": "Computer Science", + "semesters": [ + "WS2018/19" + ] + } + ] + ], + "compare": [ + { + "type": "HLNotFound", + "title": "There is no MatriculationData for the given matriculationId" + } + ] + }, + + { "name": "addEntryToUnprocessableMatriculationData", From ced54151d0b9a9bcdcefa0c76a328014c046014f Mon Sep 17 00:00:00 2001 From: Matthias Geuchen Date: Mon, 14 Sep 2020 14:28:02 +0200 Subject: [PATCH 32/32] Update changelog for v0.8.0 Co-authored-by: Niklas Doppelstein --- CHANGELOG.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bda691c2..9ecbaf86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,25 @@ -# [v0.7.2](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.1...v0.7.2) (2020-09-9) +# [v0.8.0](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.2...v0.8.0) (2020-09-14) ## Feature - +## Bug Fixes +- fix tests not throwing error when querying ```getPrivateDataUTF8``` for empty string [#25](https://github.com/upb-uc4/hlf-chaincode/pull/25) + +## Refactor +- + + +## Usability +- + + + +# [v0.7.2](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.1...v0.7.2) (2020-09-9) + +## Feature +- + ## Bug Fixes - split up *collections_config* for dev/production network [#21](https://github.com/upb-uc4/hlf-chaincode/pull/21) @@ -18,7 +35,7 @@ # [v0.7.1](https://github.com/upb-uc4/hyperledger_chaincode/compare/v0.7.0...v0.7.1) (2020-09-7) ## Feature -- move sensitive data to transient data field [#17](https://github.com/upb-uc4/hlf-chaincode/pull/17) +- move sensitive data to transient data field and store data in private data collection [#17](https://github.com/upb-uc4/hlf-chaincode/pull/17) ## Bug Fixes -