Skip to content

Commit e7863cb

Browse files
authored
Merge pull request #761 from bserdar/update-if-same
Update if same
2 parents 21a3505 + 1b4ec7e commit e7863cb

33 files changed

+275
-42
lines changed

config/src/test/resources/valid-deletion-req.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"objectType": "some_entity",
2+
"entity": "some_entity",
33
"client": {"id": "1"},
44
"execution": {
55
"timeLimit": 5000,

core-api/src/main/java/com/redhat/lightblue/ResultMetadata.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,13 @@ public class ResultMetadata extends JsonObject {
4141
*/
4242
public static final String MD_PROPERTY_DOCVER="documentVersion";
4343

44+
/**
45+
* Document version is a string that uniquely identifies the
46+
* document in its back end at a point in time. Thus, this string
47+
* contains the backend specific unique ID and the document's
48+
* timestamp/version. When the document is modified, its version
49+
* changes.
50+
*/
4451
private String documentVersion;
4552

4653
public String getDocumentVersion() {

crud/src/main/java/com/redhat/lightblue/crud/CRUDOperationContext.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ public abstract class CRUDOperationContext implements MetadataResolver, Serializ
5353
private final CRUDOperation CRUDOperation;
5454
private final HookManager hookManager;
5555
private final ExecutionOptions executionOptions;
56+
private final Set<String> documentVersions=new HashSet<>();
57+
private boolean updateIfCurrent;
5658

5759
/**
5860
* This is the constructor used to represent the context of an operation
@@ -108,6 +110,27 @@ public CRUDOperationContext(CRUDOperation op,
108110
this.executionOptions = eo;
109111
}
110112

113+
/**
114+
* If this list is non-empty, then update operations should be
115+
* performed only if document versions are unchanged
116+
*/
117+
public Set<String> getUpdateDocumentVersions() {
118+
return documentVersions;
119+
}
120+
121+
/**
122+
* If true, then only update the documents in
123+
* updateDocumentVersions set, and update them only if they are
124+
* unchanged
125+
*/
126+
public boolean isUpdateIfCurrent() {
127+
return updateIfCurrent;
128+
}
129+
130+
public void setUpdateIfCurrent(boolean b) {
131+
updateIfCurrent=b;
132+
}
133+
111134
/**
112135
* Returns the execution options
113136
*/

crud/src/main/java/com/redhat/lightblue/crud/DeleteRequest.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package com.redhat.lightblue.crud;
2020

21+
import java.util.List;
22+
2123
import com.fasterxml.jackson.databind.JsonNode;
2224
import com.fasterxml.jackson.databind.node.ObjectNode;
2325
import com.redhat.lightblue.Request;
@@ -31,6 +33,7 @@ public class DeleteRequest extends Request implements WithQuery {
3133

3234
private QueryExpression query;
3335

36+
3437
/**
3538
* The query whose result set will be deleted
3639
*/

crud/src/main/java/com/redhat/lightblue/crud/SaveRequest.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,43 @@
1818
*/
1919
package com.redhat.lightblue.crud;
2020

21+
import java.util.List;
22+
2123
import com.fasterxml.jackson.databind.JsonNode;
2224
import com.fasterxml.jackson.databind.node.ObjectNode;
2325
import com.redhat.lightblue.query.Projection;
2426

2527
/**
2628
* Request to save documents
2729
*/
28-
public class SaveRequest extends DocRequest implements WithRange, WithProjection {
30+
public class SaveRequest extends DocRequest implements WithRange, WithProjection, WithIfCurrent {
2931

3032
private Projection returnFields;
3133
private boolean upsert;
3234
private Long from;
3335
private Long to;
36+
private boolean ifCurrentOnly;
37+
private List<String> documentVersions;
38+
39+
@Override
40+
public boolean isIfCurrentOnly() {
41+
return ifCurrentOnly;
42+
}
43+
44+
@Override
45+
public void setIfCurrentOnly(boolean b) {
46+
ifCurrentOnly=b;
47+
}
48+
49+
@Override
50+
public List<String> getDocumentVersions() {
51+
return documentVersions;
52+
}
53+
54+
@Override
55+
public void setDocumentVersions(List<String> s) {
56+
documentVersions=s;
57+
}
3458

3559
/**
3660
* Specifies the fields of the inserted entities to return. This can be used
@@ -100,6 +124,7 @@ public JsonNode toJson() {
100124
node.set("projection", returnFields.toJson());
101125
}
102126
node.put("upsert", upsert);
127+
WithIfCurrent.toJson(this,node);
103128
WithRange.toJson(this, getFactory(), node);
104129
return node;
105130
}
@@ -118,6 +143,7 @@ public static SaveRequest fromJson(ObjectNode node) {
118143
if (x != null) {
119144
req.upsert = x.asBoolean();
120145
}
146+
WithIfCurrent.fromJson(req,node);
121147
Range r = WithRange.fromJson(node);
122148
req.setFrom(r.from);
123149
req.setTo(r.to);

crud/src/main/java/com/redhat/lightblue/crud/UpdateRequest.java

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package com.redhat.lightblue.crud;
2020

21+
import java.util.List;
22+
2123
import com.fasterxml.jackson.databind.JsonNode;
2224
import com.fasterxml.jackson.databind.node.ObjectNode;
2325
import com.redhat.lightblue.Request;
@@ -28,13 +30,35 @@
2830
/**
2931
* Request to update documents based on a query
3032
*/
31-
public class UpdateRequest extends Request implements WithQuery, WithProjection, WithRange {
33+
public class UpdateRequest extends Request implements WithQuery, WithProjection, WithRange, WithIfCurrent {
3234

3335
private QueryExpression query;
3436
private UpdateExpression updateExpression;
3537
private Projection returnFields;
3638
private Long from;
3739
private Long to;
40+
private boolean ifCurrentOnly;
41+
private List<String> documentVersions;
42+
43+
@Override
44+
public boolean isIfCurrentOnly() {
45+
return ifCurrentOnly;
46+
}
47+
48+
@Override
49+
public void setIfCurrentOnly(boolean b) {
50+
ifCurrentOnly=b;
51+
}
52+
53+
@Override
54+
public List<String> getDocumentVersions() {
55+
return documentVersions;
56+
}
57+
58+
@Override
59+
public void setDocumentVersions(List<String> s) {
60+
documentVersions=s;
61+
}
3862

3963
/**
4064
* The fields to return from the updated documents
@@ -122,6 +146,7 @@ public JsonNode toJson() {
122146
if (returnFields != null) {
123147
node.set("projection", returnFields.toJson());
124148
}
149+
WithIfCurrent.toJson(this,node);
125150
WithRange.toJson(this, getFactory(), node);
126151
return node;
127152
}
@@ -144,6 +169,7 @@ public static UpdateRequest fromJson(ObjectNode node) {
144169
if (x != null) {
145170
req.returnFields = Projection.fromJson(x);
146171
}
172+
WithIfCurrent.fromJson(req,node);
147173
Range r = WithRange.fromJson(node);
148174
req.setFrom(r.from);
149175
req.setTo(r.to);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/*
2+
Copyright 2013 Red Hat, Inc. and/or its affiliates.
3+
4+
This file is part of lightblue.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
*/
19+
package com.redhat.lightblue.crud;
20+
21+
import java.util.List;
22+
import java.util.ArrayList;
23+
import java.util.Iterator;
24+
25+
import com.fasterxml.jackson.databind.JsonNode;
26+
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
27+
import com.fasterxml.jackson.databind.node.ObjectNode;
28+
import com.fasterxml.jackson.databind.node.ArrayNode;
29+
import com.fasterxml.jackson.databind.node.BooleanNode;
30+
import com.fasterxml.jackson.databind.node.NullNode;
31+
import com.fasterxml.jackson.databind.node.ValueNode;
32+
33+
/**
34+
* Marker interface for requests containing if-same flag, and doc versions
35+
*/
36+
public interface WithIfCurrent {
37+
38+
/**
39+
* Returns true if the is-samne-only flag is set.
40+
*/
41+
boolean isIfCurrentOnly();
42+
void setIfCurrentOnly(boolean b);
43+
44+
/**
45+
* The list of document versions. If isIfCurrentOnly()==true, then,
46+
* only the documents that are in this list will be updated, and
47+
* only if their versions are the same.
48+
*/
49+
List<String> getDocumentVersions();
50+
void setDocumentVersions(List<String> s);
51+
52+
public static void toJson(WithIfCurrent w,ObjectNode parent) {
53+
if(w!=null&&w.isIfCurrentOnly()) {
54+
parent.set("onlyIfCurrent",JsonNodeFactory.instance.booleanNode(true));
55+
List<String> versions=w.getDocumentVersions();
56+
if(versions!=null&&!versions.isEmpty()) {
57+
ArrayNode arr=JsonNodeFactory.instance.arrayNode();
58+
for(String x:versions)
59+
arr.add(JsonNodeFactory.instance.textNode(x));
60+
parent.set("documentVersions",arr);
61+
}
62+
}
63+
}
64+
65+
public static void fromJson(WithIfCurrent dest,ObjectNode node) {
66+
JsonNode x=node.get("onlyIfCurrent");
67+
if(x instanceof ValueNode && x.booleanValue()) {
68+
dest.setIfCurrentOnly(true);
69+
x=node.get("documentVersions");
70+
if(x instanceof ArrayNode) {
71+
List<String> versions=new ArrayList<>(x.size());
72+
for(Iterator<JsonNode> itr=x.elements();itr.hasNext();) {
73+
JsonNode elem=itr.next();
74+
if(!(elem instanceof NullNode)) {
75+
versions.add(elem.asText());
76+
}
77+
}
78+
dest.setDocumentVersions(versions);
79+
}
80+
} else {
81+
dest.setIfCurrentOnly(false);
82+
}
83+
}
84+
}

crud/src/main/java/com/redhat/lightblue/mediator/Mediator.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import com.redhat.lightblue.crud.UpdateRequest;
5454
import com.redhat.lightblue.crud.WithQuery;
5555
import com.redhat.lightblue.crud.WithRange;
56+
import com.redhat.lightblue.crud.WithIfCurrent;
5657
import com.redhat.lightblue.assoc.AnalyzeQuery;
5758
import com.redhat.lightblue.assoc.QueryFieldInfo;
5859
import com.redhat.lightblue.eval.FieldAccessRoleEvaluator;
@@ -668,7 +669,17 @@ public BulkResponse bulkRequest(BulkRequest requests) {
668669
}
669670

670671
protected OperationContext newCtx(Request request, CRUDOperation CRUDOperation) {
671-
return new OperationContext(request, metadata, factory, CRUDOperation);
672+
OperationContext ctx=new OperationContext(request, metadata, factory, CRUDOperation);
673+
if(request instanceof WithIfCurrent) {
674+
WithIfCurrent wif=(WithIfCurrent)request;
675+
if(wif.isIfCurrentOnly()) {
676+
ctx.setUpdateIfCurrent(true);
677+
List<String> list=wif.getDocumentVersions();
678+
if(list!=null)
679+
ctx.getUpdateDocumentVersions().addAll(list);
680+
}
681+
}
682+
return ctx;
672683
}
673684

674685
/**

crud/src/main/resources/json-schema/crudCommon.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@
7171
},
7272
"common": {
7373
"properties": {
74-
"objectType": {
74+
"entity": {
7575
"type": "string",
7676
"description": "The name of the entity being operated on."
7777
},
@@ -89,7 +89,7 @@
8989
}
9090
},
9191
"required": [
92-
"objectType"
92+
"entity"
9393
]
9494
}
9595
}

crud/src/main/resources/json-schema/deleteRequest.json

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,27 @@
2323
"properties": {
2424
"client": {
2525
},
26-
"objectType": {
26+
"entity": {
2727
},
28-
"version": {
28+
"entityVersion": {
2929
},
3030
"execution": {
3131
},
3232
"projection": {
3333
},
3434
"query": {
35-
"$ref": "/json-schema/crudCommon.json#/definitions/query"
36-
}
35+
"$ref": "/json-schema/crudCommon.json#/definitions/query"
36+
},
37+
"onlyIfCurrent":{
38+
"type":"boolean",
39+
"description":"If true, perform the operation only if document version is unchanged"
40+
},
41+
"documentVersions":{
42+
"type":"array",
43+
"items":{
44+
"type":"string"
45+
}
46+
}
3747
},
3848
"required": [
3949
"query"

0 commit comments

Comments
 (0)