From bf74662e17356d1eccbab4503bf7f9ea5cad46e7 Mon Sep 17 00:00:00 2001 From: Doris Lam Date: Fri, 16 Feb 2024 17:16:37 -0800 Subject: [PATCH 1/4] bugfix: check if element was deleted before commit but after last modified time --- .../openmbee/mms/core/dao/CommitIndexDAO.java | 2 ++ .../mms/crud/services/NodeGetHelper.java | 29 ++++++++++++++++++- .../mms/elastic/CommitElasticDAOImpl.java | 27 +++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/openmbee/mms/core/dao/CommitIndexDAO.java b/core/src/main/java/org/openmbee/mms/core/dao/CommitIndexDAO.java index 34926b267..41d91fb04 100644 --- a/core/src/main/java/org/openmbee/mms/core/dao/CommitIndexDAO.java +++ b/core/src/main/java/org/openmbee/mms/core/dao/CommitIndexDAO.java @@ -25,6 +25,8 @@ public interface CommitIndexDAO { List elementHistory(String id, Set commitIds); + List elementDeletedHistory(String id, Collection commitIds); + CommitJson update(CommitJson commitJson); } diff --git a/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java b/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java index 61faa7226..09c0dbbb8 100644 --- a/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java +++ b/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java @@ -13,7 +13,10 @@ import org.openmbee.mms.data.domains.scoped.Branch; import org.openmbee.mms.data.domains.scoped.Commit; import org.openmbee.mms.data.domains.scoped.Node; +import org.openmbee.mms.core.dao.CommitIndexDAO; +import org.openmbee.mms.json.CommitJson; import org.openmbee.mms.json.ElementJson; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import static org.openmbee.mms.core.config.ContextHolder.getContext; @@ -21,6 +24,13 @@ @Service public class NodeGetHelper extends NodeOperation { + protected CommitIndexDAO commitIndex; + + @Autowired + public void setCommitIndex(CommitIndexDAO commitIndex) { + this.commitIndex = commitIndex; + } + public NodeGetInfo processGetJsonFromNodes(List nodes, NodeService service) { NodeGetInfo info = initInfoFromNodes(nodes, null); return processLatest(info, service); @@ -129,7 +139,24 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService rejectNotFound(info, nodeId); // element not found at commit time } } else if (info.getExistingNodeMap().get(nodeId).isDeleted()) { // latest element is before commit, but deleted - rejectDeleted(info, nodeId, indexElement); + if (refCommitIds == null) { // need list of commitIds of current ref to filter on + refCommitIds = getRefCommitIds(time); + } + List commits = commitIndex.elementDeletedHistory(nodeId, refCommitIds); + boolean isDeleted = false; + for (CommitJson c: commits) { + Instant deletedTime = Instant.from(formatter.parse(c.getCreated())); + if ((deletedTime.isBefore(time) || c.getId().equals(commitId)) && deletedTime.isAfter(modified)) { + //there's a delete between element last modified time and requested commit time + //or element is deleted at commit + isDeleted = true; + } + } + if (isDeleted) { + rejectDeleted(info, nodeId, indexElement); + } else { + info.getActiveElementMap().put(nodeId, indexElement); + } } else { // latest element version is version at commit, not deleted info.getActiveElementMap().put(nodeId, indexElement); } diff --git a/elastic/src/main/java/org/openmbee/mms/elastic/CommitElasticDAOImpl.java b/elastic/src/main/java/org/openmbee/mms/elastic/CommitElasticDAOImpl.java index 9cb2ce422..7c760023a 100644 --- a/elastic/src/main/java/org/openmbee/mms/elastic/CommitElasticDAOImpl.java +++ b/elastic/src/main/java/org/openmbee/mms/elastic/CommitElasticDAOImpl.java @@ -124,6 +124,33 @@ private QueryBuilder getCommitHistoryQuery(String id, Set commitIds) { return query; } + @Override + public List elementDeletedHistory(String id, Collection commitIds) { + QueryBuilder query = QueryBuilders.boolQuery() + .filter(QueryBuilders.termQuery("deleted.id", id)) + .filter(QueryBuilders.termsQuery(CommitJson.ID, commitIds)); + try { + List commits = new ArrayList<>(); + SearchHits hits = getCommitResults(query); + if (hits.getTotalHits().value == 0) { + return new ArrayList<>(); + } + for (SearchHit hit : hits.getHits()) { + Map source = hit.getSourceAsMap();// gets "_source" + CommitJson ob = newInstance(); + ob.putAll(source); + ob.remove(CommitJson.ADDED); + ob.remove(CommitJson.UPDATED); + ob.remove(CommitJson.DELETED); + commits.add(ob); + } + return commits; + } catch (IOException e) { + logger.error(e.getMessage(), e); + throw new InternalErrorException(e); + } + } + /** * Returns the commit history of a element *

Returns a list of commit metadata for the specified id From 798ebc264ac5491362fc85a5a9ded012bbed0cb1 Mon Sep 17 00:00:00 2001 From: Doris Lam Date: Sat, 17 Feb 2024 09:54:42 -0800 Subject: [PATCH 2/4] pull out elementDeleted to function --- .../mms/crud/services/NodeGetHelper.java | 37 ++++++++++++------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java b/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java index 09c0dbbb8..617f73bee 100644 --- a/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java +++ b/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java @@ -132,9 +132,14 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService Optional e = nodeIndex.getElementLessThanOrEqualTimestamp(nodeId, formatter.format(time), refCommitIds); if (e.isPresent()) { // found version of element at commit time - //TODO determine if element was deleted at the time? - e.get().setRefId(ContextHolder.getContext().getBranchId()); - info.getActiveElementMap().put(nodeId, e.get()); + Instant realModified = Instant.from(formatter.parse(e.get().getModified())); + boolean isDeleted = elementDeleted(nodeId, commitId, time, realModified, refCommitIds); + if (isDeleted) { + rejectDeleted(info, nodeId, indexElement); + } else { + e.get().setRefId(ContextHolder.getContext().getBranchId()); + info.getActiveElementMap().put(nodeId, e.get()); + } } else { rejectNotFound(info, nodeId); // element not found at commit time } @@ -142,16 +147,7 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService if (refCommitIds == null) { // need list of commitIds of current ref to filter on refCommitIds = getRefCommitIds(time); } - List commits = commitIndex.elementDeletedHistory(nodeId, refCommitIds); - boolean isDeleted = false; - for (CommitJson c: commits) { - Instant deletedTime = Instant.from(formatter.parse(c.getCreated())); - if ((deletedTime.isBefore(time) || c.getId().equals(commitId)) && deletedTime.isAfter(modified)) { - //there's a delete between element last modified time and requested commit time - //or element is deleted at commit - isDeleted = true; - } - } + boolean isDeleted = elementDeleted(nodeId, commitId, time, modified, refCommitIds); if (isDeleted) { rejectDeleted(info, nodeId, indexElement); } else { @@ -164,6 +160,21 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService return info; } + private boolean elementDeleted(String nodeId, String commitId, Instant time, Instant modified, List refCommitIds) { + List commits = commitIndex.elementDeletedHistory(nodeId, refCommitIds); + boolean isDeleted = false; + for (CommitJson c: commits) { + Instant deletedTime = Instant.from(formatter.parse(c.getCreated())); + if ((deletedTime.isBefore(time) || c.getId().equals(commitId)) && deletedTime.isAfter(modified)) { + //there's a delete between element last modified time and requested commit time + //or element is deleted at commit + isDeleted = true; + break; + } + } + return isDeleted; + } + public NodeGetInfo processGetJson(List elements, Instant time, NodeService service) { Optional ref = branchRepository.findByBranchId(getContext().getBranchId()); if (ref.isPresent()) { From 03f78639ab45373be79613800518360ffb85a950 Mon Sep 17 00:00:00 2001 From: Doris Lam Date: Sat, 17 Feb 2024 14:46:06 -0800 Subject: [PATCH 3/4] add tests --- .circleci/config.yml | 5 +- example/getAtCommits.postman_collection.json | 884 +++++++++++++++++++ 2 files changed, 887 insertions(+), 2 deletions(-) create mode 100644 example/getAtCommits.postman_collection.json diff --git a/.circleci/config.yml b/.circleci/config.yml index df27e029d..f8446b1a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -20,19 +20,20 @@ jobs: - setup_remote_docker - - run: + - run: name: "Create and start all services from the docker-compose configuration" command: | cp example/src/main/resources/application.properties.example ./example/src/main/resources/application.properties docker-compose up --build -d docker run --network container:mms curlimages/curl --retry 8 --retry-delay 10 --retry-max-time 90 --retry-connrefused http://mms:8080/healthcheck - - run: + - run: name: "Run and test Postman Collection" command: | docker create -v /etc/newman --name mms_test_configs alpine:3.4 /bin/true docker cp example/. mms_test_configs:/etc/newman docker run --volumes-from mms_test_configs --network container:mms -t postman/newman run crud.postman_collection.json -e test-env.json --delay-request 500 + docker run --volumes-from mms_test_configs --network container:mms -t postman/newman run getAtCommits.postman_collection.json -e test-env.json --delay-request 500 docker run --volumes-from mms_test_configs --network container:mms -t postman/newman run cameo.postman_collection.json -e test-env.json --delay-request 1000 docker run --volumes-from mms_test_configs --network container:mms -t postman/newman run jupyter.postman_collection.json -e test-env.json --delay-request 500 docker run --volumes-from mms_test_configs --network container:mms -t postman/newman run localauth.postman_collection.json -e test-env.json --delay-request 500 diff --git a/example/getAtCommits.postman_collection.json b/example/getAtCommits.postman_collection.json new file mode 100644 index 000000000..db2bb4538 --- /dev/null +++ b/example/getAtCommits.postman_collection.json @@ -0,0 +1,884 @@ +{ + "info": { + "_postman_id": "c3e5107f-904c-47a4-8c31-e6bfa70f9ac4", + "name": "GetAtCommits", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "7302261" + }, + "item": [ + { + "name": "login using admin", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "", + "pm.test(\"Status code is 200\", function () {", + " pm.response.to.have.status(200);", + " ", + "});", + "", + "pm.test(\"response has token\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.token).to.be.a('string');", + " pm.environment.set(\"token\", jsonData.token);", + "", + "});", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "auth": { + "type": "noauth" + }, + "method": "POST", + "header": [ + { + "key": "Content-Type", + "name": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"username\": \"{{adminUsername}}\",\n\t\"password\": \"{{adminPassword}}\"\n}" + }, + "url": { + "raw": "{{host}}/authentication", + "host": [ + "{{host}}" + ], + "path": [ + "authentication" + ] + } + }, + "response": [] + }, + { + "name": "add org", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has org commits\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.orgs[0].id).to.eql('commits');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"orgs\": [\n\t\t{\n\t\t\t\"id\": \"commits\",\n\t\t\t\"name\": \"commits\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/orgs", + "host": [ + "{{host}}" + ], + "path": [ + "orgs" + ] + } + }, + "response": [] + }, + { + "name": "add project", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has project commits\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.projects[0].id).to.eql('commits');", + "});" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"projects\": [\n\t\t{\n\t\t\t\"id\": \"commits\", \n\t\t\t\"name\": \"commits\",\n\t\t\t\"orgId\": \"commits\",\n\t\t\t\"schema\": \"default\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/projects", + "host": [ + "{{host}}" + ], + "path": [ + "projects" + ] + } + }, + "response": [] + }, + { + "name": "add a and b", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(2);", + "});", + "", + "pm.environment.set(\"addABCommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n\t\t{\n\t\t\t\"id\": \"a\",\n\t\t\t\"name\": \"a\"\n\t\t}, {\n\t\t\t\"id\": \"b\", \n\t\t\t\"name\": \"b\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "add c", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"addCCommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n\t\t{\n\t\t\t\"id\": \"c\",\n\t\t\t\"name\": \"c\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "add d", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"addDCommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n\t\t{\n\t\t\t\"id\": \"d\",\n\t\t\t\"name\": \"d\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "delete a", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"deleteACommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements/a", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements", + "a" + ] + } + }, + "response": [] + }, + { + "name": "update b", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"updateBCommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n {\n\t\t\t\"id\": \"b\", \n\t\t\t\"name\": \"b updated\"\n\t\t}\n\t]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "delete c", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"deleteCCommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "DELETE", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n {\n\t\t\t\"id\": \"c\"\n\t\t}\n\t]\n}", + "options": { + "raw": { + "language": "json" + } + } + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "add e", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"addECommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n\t\t{\n\t\t\t\"id\": \"e\",\n\t\t\t\"name\": \"e\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "recurrect c", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has elements\", function () {", + " var jsonData = pm.response.json();", + " pm.expect(jsonData.elements.length).to.eql(1);", + "});", + "", + "pm.environment.set(\"resurrectCCommitId\", pm.response.json().commitId);" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "POST", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "body": { + "mode": "raw", + "raw": "{\n\t\"elements\": [\n\t\t{\n\t\t\t\"id\": \"c\",\n\t\t\t\"name\": \"c\"\n\t\t}\n\t]\n}" + }, + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ] + } + }, + "response": [] + }, + { + "name": "get elements at initial commit", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has a and b\", function () {", + " var jsonData = pm.response.json();", + "", + " pm.expect(jsonData.elements.length).to.eql(2);", + " var result = jsonData.elements.map(e => ({id: e.id}));", + " pm.expect(result).to.deep.have.members([{id: 'a'}, {id: 'b'}]);", + " pm.expect(jsonData.commitId).to.eql(pm.environment.get('addABCommitId'));", + " ", + "})", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements?commitId={{addABCommitId}}", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ], + "query": [ + { + "key": "commitId", + "value": "{{addABCommitId}}" + } + ] + } + }, + "response": [] + }, + { + "name": "get elements at add d", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has a,b,c,d\", function () {", + " var jsonData = pm.response.json();", + "", + " pm.expect(jsonData.elements.length).to.eql(4);", + " var result = jsonData.elements.map(e => ({id: e.id}));", + " pm.expect(result).to.deep.have.members([{id: 'a'}, {id: 'b'}, {id: 'c'}, {id: 'd'}]);", + " pm.expect(jsonData.commitId).to.eql(pm.environment.get('addDCommitId'));", + " ", + "})", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements?commitId={{addDCommitId}}", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ], + "query": [ + { + "key": "commitId", + "value": "{{addDCommitId}}" + } + ] + } + }, + "response": [] + }, + { + "name": "get elements at delete a", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has b,c,d\", function () {", + " var jsonData = pm.response.json();", + "", + " pm.expect(jsonData.elements.length).to.eql(3);", + " var result = jsonData.elements.map(e => ({id: e.id}));", + " pm.expect(result).to.deep.have.members([{id: 'b'}, {id: 'c'}, {id: 'd'}]);", + " pm.expect(jsonData.commitId).to.eql(pm.environment.get('deleteACommitId'));", + " ", + "})", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements?commitId={{deleteACommitId}}", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ], + "query": [ + { + "key": "commitId", + "value": "{{deleteACommitId}}" + } + ] + } + }, + "response": [] + }, + { + "name": "get elements at update b", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has b,c,d with updated b name\", function () {", + " var jsonData = pm.response.json();", + "", + " pm.expect(jsonData.elements.length).to.eql(3);", + " var result = jsonData.elements.map(e => ({id: e.id, name: e.name}));", + " pm.expect(result).to.deep.have.members([{id: 'b', name: 'b updated'}, {id: 'c', name: 'c'}, {id: 'd', name: 'd'}]);", + " pm.expect(jsonData.commitId).to.eql(pm.environment.get('updateBCommitId'));", + " ", + "})", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements?commitId={{updateBCommitId}}", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ], + "query": [ + { + "key": "commitId", + "value": "{{updateBCommitId}}" + } + ] + } + }, + "response": [] + }, + { + "name": "get elements at add e", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has b,d,e\", function () {", + " var jsonData = pm.response.json();", + "", + " pm.expect(jsonData.elements.length).to.eql(3);", + " var result = jsonData.elements.map(e => ({id: e.id}));", + " pm.expect(result).to.deep.have.members([{id: 'b'}, {id: 'd'}, {id: 'e'}]);", + " pm.expect(jsonData.commitId).to.eql(pm.environment.get('addECommitId'));", + " ", + "})", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements?commitId={{addECommitId}}", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ], + "query": [ + { + "key": "commitId", + "value": "{{addECommitId}}" + } + ] + } + }, + "response": [] + }, + { + "name": "get elements at resurrect c", + "event": [ + { + "listen": "test", + "script": { + "exec": [ + "pm.test(\"response has b,c,d,e\", function () {", + " var jsonData = pm.response.json();", + "", + " pm.expect(jsonData.elements.length).to.eql(4);", + " var result = jsonData.elements.map(e => ({id: e.id}));", + " pm.expect(result).to.deep.have.members([{id: 'b'}, {id: 'c'}, {id: 'd'}, {id: 'e'}]);", + " pm.expect(jsonData.commitId).to.eql(pm.environment.get('resurrectCCommitId'));", + " ", + "})", + "", + "" + ], + "type": "text/javascript" + } + } + ], + "request": { + "method": "GET", + "header": [ + { + "key": "Content-Type", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "{{host}}/projects/commits/refs/master/elements?commitId={{resurrectCCommitId}}", + "host": [ + "{{host}}" + ], + "path": [ + "projects", + "commits", + "refs", + "master", + "elements" + ], + "query": [ + { + "key": "commitId", + "value": "{{resurrectCCommitId}}" + } + ] + } + }, + "response": [] + } + ], + "auth": { + "type": "bearer", + "bearer": [ + { + "key": "token", + "value": "{{token}}", + "type": "string" + } + ] + }, + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] +} \ No newline at end of file From e1080c04b210344424a5d34a69d5b904bf9eb3b9 Mon Sep 17 00:00:00 2001 From: Doris Lam Date: Sat, 17 Feb 2024 15:15:13 -0800 Subject: [PATCH 4/4] simplify lines --- .../openmbee/mms/crud/services/NodeGetHelper.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java b/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java index 617f73bee..00e14f78f 100644 --- a/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java +++ b/crud/src/main/java/org/openmbee/mms/crud/services/NodeGetHelper.java @@ -133,9 +133,8 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService formatter.format(time), refCommitIds); if (e.isPresent()) { // found version of element at commit time Instant realModified = Instant.from(formatter.parse(e.get().getModified())); - boolean isDeleted = elementDeleted(nodeId, commitId, time, realModified, refCommitIds); - if (isDeleted) { - rejectDeleted(info, nodeId, indexElement); + if (elementDeleted(nodeId, commitId, time, realModified, refCommitIds)) { + rejectDeleted(info, nodeId, e.get()); } else { e.get().setRefId(ContextHolder.getContext().getBranchId()); info.getActiveElementMap().put(nodeId, e.get()); @@ -147,8 +146,7 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService if (refCommitIds == null) { // need list of commitIds of current ref to filter on refCommitIds = getRefCommitIds(time); } - boolean isDeleted = elementDeleted(nodeId, commitId, time, modified, refCommitIds); - if (isDeleted) { + if (elementDeleted(nodeId, commitId, time, modified, refCommitIds)) { rejectDeleted(info, nodeId, indexElement); } else { info.getActiveElementMap().put(nodeId, indexElement); @@ -162,17 +160,15 @@ private NodeGetInfo processCommit(NodeGetInfo info, String commitId, NodeService private boolean elementDeleted(String nodeId, String commitId, Instant time, Instant modified, List refCommitIds) { List commits = commitIndex.elementDeletedHistory(nodeId, refCommitIds); - boolean isDeleted = false; for (CommitJson c: commits) { Instant deletedTime = Instant.from(formatter.parse(c.getCreated())); if ((deletedTime.isBefore(time) || c.getId().equals(commitId)) && deletedTime.isAfter(modified)) { //there's a delete between element last modified time and requested commit time //or element is deleted at commit - isDeleted = true; - break; + return true; } } - return isDeleted; + return false; } public NodeGetInfo processGetJson(List elements, Instant time, NodeService service) {