Commit d3bb1794 by Eli Ben Baruch

mde - phase 2 - full support of ge parking and traffic. generalization of dynamic variables

parent dcc59bb1
Showing with 3253 additions and 474 deletions
...@@ -13,7 +13,7 @@ repositories { ...@@ -13,7 +13,7 @@ repositories {
} }
dependencies { dependencies {
compile 'com.flipkart.zjsonpatch:zjsonpatch:0.2.1' // compile 'com.flipkart.zjsonpatch:zjsonpatch:0.2.1'
// compile group:'com.ipgallery.common', name:'microservice', version:'1.2.0' // compile group:'com.ipgallery.common', name:'microservice', version:'1.2.0'
compile group:'com.ipgallery.common', name:'microservice', version:'1.3.2' compile group:'com.ipgallery.common', name:'microservice', version:'1.3.2'
compile group:'com.ipgallery.common', name:'itc', version:'1.0.0' compile group:'com.ipgallery.common', name:'itc', version:'1.0.0'
...@@ -21,34 +21,29 @@ dependencies { ...@@ -21,34 +21,29 @@ dependencies {
compile 'io.swagger:swagger-annotations:1.5.7' compile 'io.swagger:swagger-annotations:1.5.7'
compile 'org.slf4j:slf4j-simple:1.7.19' compile 'org.slf4j:slf4j-simple:1.7.19'
compile 'com.javadocmd:simplelatlng:1.3.1' compile 'com.javadocmd:simplelatlng:1.3.1'
compile group: 'org.json', name: 'json', version: '20160212'
// https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api
compile group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1' compile group: 'javax.websocket', name: 'javax.websocket-api', version: '1.1'
compile 'com.neovisionaries:nv-websocket-client:1.30' compile 'com.neovisionaries:nv-websocket-client:1.30'
compile 'org.java-websocket:Java-WebSocket:1.3.0' compile 'org.java-websocket:Java-WebSocket:1.3.0'
// compile 'com.google.oauth-client:google-oauth-client:1.22.0' ///json-patch start
// compile 'com.google.api.client:google-api-client-json:1.2.3-alpha' compile 'com.google.guava:guava:1.18.0'
// compile 'com.google.http-client:google-http-client-jackson:1.15.0-rc' compile 'com.github.fge:json-patch:1.9'
compile group: 'org.apache.commons', name: 'commons-collections4', version: '4.0'
// <dependency> ///json-patch end
// <groupId>com.google.api.client</groupId>
//<artifactId>google-api-client</artifactId>
// <version>1.4.1-beta</version>
//</dependency>
testCompile 'junit:junit:4.12' testCompile 'junit:junit:4.12'
// testCompile 'com.neovisionaries:nv-websocket-client:1.30' // testCompile fileTree(dir: '../ds/lib/external/sap', include: '*.jar')
testCompile fileTree(dir: '../ds/lib/external/sap', include: '*.jar')
testCompile 'org.java-websocket:Java-WebSocket:1.3.0' testCompile 'org.java-websocket:Java-WebSocket:1.3.0'
testCompile 'com.google.oauth-client:google-oauth-client:1.22.0' testCompile 'com.google.oauth-client:google-oauth-client:1.22.0'
testCompile 'com.google.api.client:google-api-client-json:1.2.3-alpha' // testCompile 'com.google.api.client:google-api-client-zjsonpatch:1.2.3-alpha'
testCompile 'com.google.http-client:google-http-client-jackson:1.15.0-rc' testCompile 'com.google.http-client:google-http-client-jackson:1.15.0-rc'
testCompile 'com.google.api.client:google-api-client:1.4.1-beta' testCompile 'com.google.api.client:google-api-client:1.4.1-beta'
} }
jar { jar {
......
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
"headers": [{ "headers": [{
"name": "predix-zone-id", "name": "predix-zone-id",
"value": "c54e3e63-8dc6-425e-a533-64e061f64023" "value": "c54e3e63-8dc6-425e-a533-64e061f64023"
}, {
"name": "Authorization",
"value": "bearer $token"
}] }]
}, },
"authentication": { "authentication": {
...@@ -34,8 +31,7 @@ ...@@ -34,8 +31,7 @@
}, { }, {
"name": "q", "name": "q",
"value": "location-type:PARKING_SPOT" "value": "location-type:PARKING_SPOT"
}, }, {
{
"name": "size", "name": "size",
"value": "30" "value": "30"
}], }],
...@@ -56,22 +52,29 @@ ...@@ -56,22 +52,29 @@
"metaDataActionClass": "logic.adapter.action.JsonConvertAction", "metaDataActionClass": "logic.adapter.action.JsonConvertAction",
"params": { "params": {
"intermediateOperations": [{ "intermediateOperations": [{
"metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapJsonToStringOperation", "metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapStringToJsonOperation",
"operationParams": { "operationParams": {
"action": { "action": {
"metaDataActionClass": "logic.adapter.action.ExtractValueAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": { "params": {
"variables": {
"id": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/_links/self/href", "path": "/_links/self/href",
"valueType": "STRING" "valueType": "STRING"
},
"subString": {
"from": {
"str": "/",
"location": "LAST",
"index": null
},
"to": null
} }
} }
} }},
}, {
"metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapStringToJsonOperation",
"operationParams": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": {
"id": "getLocationDetails", "id": "getLocationDetails",
"httpMethod": "GET", "httpMethod": "GET",
"path": "locations/$id", "path": "locations/$id",
...@@ -79,8 +82,7 @@ ...@@ -79,8 +82,7 @@
"headers": [], "headers": [],
"content": null "content": null
} }
}, }
"id": "lastToken"
} }
}, { }, {
"metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapJsonToJsonOperation", "metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapJsonToJsonOperation",
...@@ -88,6 +90,25 @@ ...@@ -88,6 +90,25 @@
"action": { "action": {
"metaDataActionClass": "logic.adapter.action.JsonPatchAction", "metaDataActionClass": "logic.adapter.action.JsonPatchAction",
"params": { "params": {
"variables": {
"mdeKey": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/_embedded/assets/0/_links/self/href",
"valueType": "STRING"
},
"subString": {
"from": {
"str": "/",
"location": "LAST",
"index": null
},
"to": null
}
}
}
},
"fileInput": null, "fileInput": null,
"filePatch": "parkingSpotJsonPatch.json" "filePatch": "parkingSpotJsonPatch.json"
} }
...@@ -98,10 +119,7 @@ ...@@ -98,10 +119,7 @@
} }
}] }]
}, },
"onError": { "onError": null
"actionsInput": "CONTENT",
"actions": []
}
} }
}, { }, {
"action": { "action": {
...@@ -125,8 +143,7 @@ ...@@ -125,8 +143,7 @@
"actions": [] "actions": []
} }
} }
}, }, {
{
"action": { "action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": { "params": {
...@@ -136,8 +153,7 @@ ...@@ -136,8 +153,7 @@
"queryParams": [{ "queryParams": [{
"name": "event-types", "name": "event-types",
"value": "PKIN,PKOUT" "value": "PKIN,PKOUT"
} }],
],
"headers": [], "headers": [],
"content": null "content": null
} }
...@@ -146,19 +162,30 @@ ...@@ -146,19 +162,30 @@
"onSuccess": { "onSuccess": {
"actionsInput": "CONTENT", "actionsInput": "CONTENT",
"actions": [{ "actions": [{
"metaDataActionClass": "logic.adapter.action.ExtractValueAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": { "params": {
"variables": {
"webSocket": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/url", "path": "/url",
"valueType": "STRING" "valueType": "STRING"
},
"subString": {
"from": null,
"to": null
}
}
} }
}, },
{ "headers": [{
"metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": {
"headers":[{
"name": "predix-zone-id", "name": "predix-zone-id",
"value": "c54e3e63-8dc6-425e-a533-64e061f64023" "value": "c54e3e63-8dc6-425e-a533-64e061f64023"
}] }],
"webSocket": "$webSocket",
"mdeKey": "$mdeKey",
"uid": "$uid"
} }
}] }]
}, },
...@@ -167,5 +194,7 @@ ...@@ -167,5 +194,7 @@
"actions": [] "actions": []
} }
} }
}] }
]
} }
\ No newline at end of file
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
"headers": [{ "headers": [{
"name": "predix-zone-id", "name": "predix-zone-id",
"value": "b6fc22b6-ad71-423e-867b-a1b197f6cfc2" "value": "b6fc22b6-ad71-423e-867b-a1b197f6cfc2"
}, {
"name": "Authorization",
"value": "bearer $token"
}] }]
}, },
"authentication": { "authentication": {
...@@ -26,10 +23,138 @@ ...@@ -26,10 +23,138 @@
"action": { "action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": { "params": {
"id": "GetAllTrafficLanes",
"httpMethod": "GET",
"path": "locations/search",
"queryParams": [{
"name": "bbox",
"value": "32.123:-117,32.723179:-117.172655"
}, {
"name": "q",
"value": "location-type:TRAFFIC_LANE"
}, {
"name": "size",
"value": "30"
}],
"headers": [],
"content": null
}
},
"onResponse": {
"onSuccess": {
"actionsInput": "CONTENT",
"actions": [{
"metaDataActionClass": "logic.adapter.action.ExtractValueAction",
"params": {
"path": "/_embedded/locations",
"valueType": "ARRAY-NODE"
}
}, {
"metaDataActionClass": "logic.adapter.action.JsonConvertAction",
"params": {
"intermediateOperations": [{
"metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapStringToJsonOperation",
"operationParams": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": {
"variables": {
"id": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/_links/self/href",
"valueType": "STRING"
},
"subString": {
"from": {
"str": "/",
"location": "LAST",
"index": null
},
"to": null
}
}
}},
"id": "getLocationDetails",
"httpMethod": "GET",
"path": "locations/$id",
"queryParams": null,
"headers": [],
"content": null
}
}
}
},
{
"metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapJsonToJsonOperation",
"operationParams": {
"action": {
"metaDataActionClass": "logic.adapter.action.JsonPatchAction",
"params": {
"variables": {
"mdeKey": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/_embedded/assets/0/_links/self/href",
"valueType": "STRING"
},
"subString": {
"from": {
"str": "/",
"location": "LAST",
"index": null
},
"to": null
}
}
}
},
"fileInput": null,
"filePatch": "trafficLaneJsonPatch.json"
}
}
}
}],
"terminateOperation": null
}
}]
},
"onError": null
}
}, {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": {
"id": "getLocationDetails",
"httpMethod": "GET",
"path": "locations/$id",
"queryParams": [],
"headers": [],
"content": null
}
},
"onResponse": {
"onSuccess": {
"actionsInput": "CONTENT",
"actions": []
},
"onError": {
"actionsInput": "CONTENT",
"actions": []
}
}
},
{
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": {
"id": "subscribe", "id": "subscribe",
"httpMethod": "GET", "httpMethod": "GET",
"path": "assets/$mdeKey/live-events", "path": "assets/$mdeKey/live-events",
"queryParams": [{ "queryParams": [
{
"name": "event-types", "name": "event-types",
"value": "TFEVT" "value": "TFEVT"
} }
...@@ -41,22 +166,37 @@ ...@@ -41,22 +166,37 @@
"onResponse": { "onResponse": {
"onSuccess": { "onSuccess": {
"actionsInput": "CONTENT", "actionsInput": "CONTENT",
"actions": [{ "actions": [
"metaDataActionClass": "logic.adapter.action.ExtractValueAction", {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": { "params": {
"variables": {
"webSocket": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/url", "path": "/url",
"valueType": "STRING" "valueType": "STRING"
},
"subString": {
"from": null,
"to": null
}
}
} }
}, },
"headers": [
{ {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": {
"headers":[{
"name": "predix-zone-id", "name": "predix-zone-id",
"value": "b6fc22b6-ad71-423e-867b-a1b197f6cfc2" "value": "c54e3e63-8dc6-425e-a533-64e061f64023"
}]
} }
}] ],
"webSocket": "$webSocket",
"mdeKey": "$mdeKey",
"uid": "$uid"
}
}
]
}, },
"onError": { "onError": {
"actionsInput": "CONTENT", "actionsInput": "CONTENT",
...@@ -64,5 +204,6 @@ ...@@ -64,5 +204,6 @@
} }
} }
} }
]
]
} }
\ No newline at end of file
{ {
"apiList": [ "apiList": [
{ {
"apiIn": "spots", "apiIn": { "name": "spots", "paramsTypes": null},
"method": "GET", "method": "GET",
"actions": [{ "actions": [{
"adapterId": "adapter.ge.parking", "adapterId": "adapter.ge.parking",
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
}] }]
}, },
{ {
"apiIn": "resources/devices/$id", "apiIn": {"name": "resources/devices/$id", "paramsTypes": ["DIGITS"]},
"method": "GET", "method": "GET",
"actions": [{ "actions": [{
"adapterId": "adapter.ge.parking", "adapterId": "adapter.ge.parking",
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
}] }]
}, },
{ {
"apiIn": "subscribe/$mde-id/$uid", "apiIn": {"name": "subscribe/$mdeKey/$uid", "paramsTypes": ["DIGITS","NO_CHECK"]},
"method": "POST", "method": "POST",
"actions": [{ "actions": [{
"adapterId": "adapter.ge.parking", "adapterId": "adapter.ge.parking",
......
{ {
"apiList": [ "apiList": [
{ {
"apiIn": "subscribe/$mde-id/$uid", "apiIn": {"name": "subscribe/$mdeKey/$uid", "paramsTypes": ["DIGITS","NO_CHECK"]},
"method": "POST", "method": "POST",
"actions": [{ "actions": [{
"adapterId": "adapter.ge.traffic", "adapterId": "adapter.ge.traffic",
"apiOut": "subscribe" "apiOut": "subscribe"
}] }]
},
{
"apiIn": { "name": "traffic-lanes", "paramsTypes": null},
"method": "GET",
"actions": [{
"adapterId": "adapter.ge.traffic",
"apiOut": "GetAllTrafficLanes"
}]
} }
] ]
} }
[
{ "op": "remove", "path": "/city"},
{ "op": "remove", "path": "/state"},
{ "op": "remove", "path": "/country"},
{ "op": "remove", "path": "/zipcode"},
{ "op": "remove", "path": "/_links"},
{ "op": "remove", "path": "/location-type"},
{ "op": "remove", "path": "/address"},
{ "op": "remove", "path": "/_embedded"},
{ "op": "remove", "path": "/analytic-category"},
{ "op": "add", "path": "/properties", "value": { "vehicleType": null, "measures": null, "timestamp": 0, "mde-key": "$mdeKey"}}
]
\ No newline at end of file
...@@ -9,4 +9,6 @@ mde: ...@@ -9,4 +9,6 @@ mde:
- "50040:50040" - "50040:50040"
extra_hosts: extra_hosts:
- "transportation:172.16.1.151" - "transportation:172.16.1.151"
- "parking:172.16.1.244" - "parking:172.16.1.56"
\ No newline at end of file # volumes:
# - "/opt/mcz/user_images:/opt/mcz/user_images"
\ No newline at end of file
...@@ -3,13 +3,28 @@ package defs; ...@@ -3,13 +3,28 @@ package defs;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import util.Utils; import util.Utils;
import java.util.regex.Pattern;
/** /**
* Created by eli on 6/26/16. * Created by eli on 6/26/16.
*/ */
public class Constants { public class Constants {
public static final String ADAPTERS_PATH = "adapters.json"; public final static String ADAPTERS_PATH = "adapters.json";
public static final String SERVICES_PATH = "services.json"; public final static String SERVICES_PATH = "services.json";
public static final String CONFIG_LOCATION = "/opt/mcx/config/"; public final static String CONFIG_LOCATION = "/opt/mcx/config/";
private final static String regexQueryParamValue = "^\\$[a-zA-Z]{1,15}\\.[a-zA-Z]{1,15}$";
public final static Pattern patternFullMatchValue = Pattern.compile(regexQueryParamValue);
private final static String regexPathParamValue = "^\\$[a-zA-Z]{1,15}\\.[a-zA-Z]{1,15}$";
public final static Pattern patternPathParamValue = Pattern.compile(regexPathParamValue);
private final static String regexPathKeyWord= "^\\$[a-zA-Z0-9]{1,15}\\.[a-zA-Z]{1,15}$";
public final static Pattern patternPathKeyWord = Pattern.compile(regexPathKeyWord);
private final static String regex = "\\$[a-zA-Z0-9]{1,15}";
public final static Pattern compiledRegEx = Pattern.compile(regex);
private final static String regexWord = "^\\$[a-zA-Z0-9]{1,15}$";
public final static Pattern compiledRegExWord = Pattern.compile(regexWord);
private final static String regexDigits = "^[0-9]{1,15}$";
public final static Pattern compiledRegexDigits = Pattern.compile(regexDigits);
} }
package defs; package defs;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import java.util.regex.Pattern;
import static defs.Constants.compiledRegexDigits;
/** /**
* Created by eli on 7/5/16. * Created by eli on 7/5/16.
*/ */
...@@ -32,6 +40,45 @@ public class Enums { ...@@ -32,6 +40,45 @@ public class Enums {
} }
public enum ePreDefinedRegexTypes{
STRING_EQUALS("NORMAL",null),
REGEX_NO_CHECK("NO_CHECK",null),
REGEX_DIGITS("DIGITS",compiledRegexDigits);
private final String name;
private final Pattern rexEx;
public Pattern getPattern() {
return rexEx;
}
private ePreDefinedRegexTypes(String name,Pattern rexEx) {
this.name = name;
this.rexEx=rexEx;
}
@JsonValue
public String toString() {
return name;
}
@JsonCreator
public static ePreDefinedRegexTypes forValue(String name){
ePreDefinedRegexTypes[] types = ePreDefinedRegexTypes.values();
for (ePreDefinedRegexTypes type : types)
{
if (type.toString().equals(name))
return type;
}
return null;
}
}
public enum eKeyWord{ public enum eKeyWord{
QUERY("query"), QUERY("query"),
HEADER("header"); HEADER("header");
...@@ -58,4 +105,40 @@ public class Enums { ...@@ -58,4 +105,40 @@ public class Enums {
} }
} }
public enum eSubStringLocation{
@JsonProperty("FIRST")
FIRST("FIRST"),
@JsonProperty("LAST")
LAST("LAST"),
@JsonProperty("XXX_th")
XXX_th("XXX_th"),
@JsonProperty("INDEX")
INDEX("INDEX");
private final String name;
private eSubStringLocation(String name) {
this.name = name;
}
public String getName() {
return name;
}
@JsonCreator
public static eSubStringLocation resolveName(String name){
eSubStringLocation[] keys = eSubStringLocation.values();
for (eSubStringLocation eName : keys)
{
if (eName.getName().equals(name))
return eName;
}
return null;
}
}
} }
package defs;
/**
* Created by eli on 12/14/16.
*/
public class KeyIndexParam {
private String key;
private int index;
public KeyIndexParam(String key, int index) {
this.key = key;
this.index = index;
}
public String getKey() {
return key;
}
public int getIndex() {
return index;
}
}
...@@ -34,14 +34,28 @@ public class MdeHandler extends BaseHandler { ...@@ -34,14 +34,28 @@ public class MdeHandler extends BaseHandler {
@Override @Override
public void init() { public void init() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
this.mdeManager = new MdeManager(logger); this.mdeManager = new MdeManager(logger);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e);
}
this.rcc = new RedisCacheClient(this.getConfigValueAsString("redis.host","localhost")); this.rcc = new RedisCacheClient(this.getConfigValueAsString("redis.host","localhost"));
} }
@Override @Override
public void doCreate(RequestContext requestContext) { public void doCreate(RequestContext requestContext) {
JsonNode content = (JsonNode)readObjectFromRequest(requestContext,JsonNode.class); JsonNode content = (JsonNode)readObjectFromRequest(requestContext,JsonNode.class);
BaseRestResponse brr = mdeManager.doCreate(requestContext,content); BaseRestResponse brr;
brr = validityCheck(requestContext);
if (brr.success) {
brr = mdeManager.doCreate(requestContext, content);
}
writeObjectToResponse(requestContext, brr); writeObjectToResponse(requestContext, brr);
} }
...@@ -51,27 +65,43 @@ public class MdeHandler extends BaseHandler { ...@@ -51,27 +65,43 @@ public class MdeHandler extends BaseHandler {
// GET ../mde/{tenantId}/{serviceId}/{apiId} // GET ../mde/{tenantId}/{serviceId}/{apiId}
// example: GET ../mde/chicago/transportation/routes?key=gT2nciTKwRv6Jy5njqm8fe7LW // example: GET ../mde/chicago/transportation/routes?key=gT2nciTKwRv6Jy5njqm8fe7LW
//change to!!!!!: // example: GET ../mde/chicago.transportation/routes?key=gT2nciTKwRv6Jy5njqm8fe7LW //change to!!!!!: // example: GET ../mde/chicago.transportation/routes?key=gT2nciTKwRv6Jy5njqm8fe7LW
BaseRestResponse brr = mdeManager.doRead(requestContext); BaseRestResponse brr;
brr = validityCheck(requestContext);
if (brr.success) {
brr = mdeManager.doRead(requestContext);
}
writeObjectToResponse(requestContext, brr); writeObjectToResponse(requestContext, brr);
} }
@Override @Override
public void doUpdate(RequestContext requestContext) { public void doUpdate(RequestContext requestContext) {
BaseRestResponse brr = mdeManager.doUpdate(requestContext); BaseRestResponse brr;
brr = validityCheck(requestContext);
if (brr.success) {
brr = mdeManager.doUpdate(requestContext);
}
writeObjectToResponse(requestContext, brr); writeObjectToResponse(requestContext, brr);
} }
@Override @Override
public void doDelete(RequestContext requestContext) { public void doDelete(RequestContext requestContext) {
BaseRestResponse brr = mdeManager.doDelete(requestContext); BaseRestResponse brr;
brr = validityCheck(requestContext);
if (brr.success) {
brr = mdeManager.doDelete(requestContext);
}
writeObjectToResponse(requestContext, brr); writeObjectToResponse(requestContext, brr);
} }
private SimpleRestResponse errorResponse(String error) { private BaseRestResponse validityCheck(RequestContext requestContext) {
String[] params=requestContext.params;
if (params.length>=3)
return new BaseRestResponse(true,null);
else{
return new BaseRestResponse(false,"missing url parameters. after base url at least "+params.length+ " parameters must be populated");
}
SimpleRestResponse resp = new SimpleRestResponse();
resp.error = error;
return resp;
} }
} }
...@@ -18,6 +18,8 @@ import microservice.types.BaseRestResponse; ...@@ -18,6 +18,8 @@ import microservice.types.BaseRestResponse;
import util.Utils; import util.Utils;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* Created by eli on 6/7/16. * Created by eli on 6/7/16.
...@@ -32,7 +34,7 @@ public class MdeManager { ...@@ -32,7 +34,7 @@ public class MdeManager {
private ServicesRepository servicesRepository; private ServicesRepository servicesRepository;
public MdeManager(ILogger logger) { public MdeManager(ILogger logger) throws Exception {
try{ try{
jsonPatchAddLocationUID = Utils.readJsonNodeFromFile(Constants.CONFIG_LOCATION+"jsonPatchAddLocationUid.json"); jsonPatchAddLocationUID = Utils.readJsonNodeFromFile(Constants.CONFIG_LOCATION+"jsonPatchAddLocationUid.json");
jsonPatchAddAppKey = Utils.readJsonNodeFromFile(Constants.CONFIG_LOCATION+"jsonPatchAddAppKey.json"); jsonPatchAddAppKey = Utils.readJsonNodeFromFile(Constants.CONFIG_LOCATION+"jsonPatchAddAppKey.json");
...@@ -43,7 +45,7 @@ public class MdeManager { ...@@ -43,7 +45,7 @@ public class MdeManager {
ValidityCheck(); ValidityCheck();
} }
catch(Exception e){ catch(Exception e){
logger.error("Failed to construct MdeManager with exception "+e); throw new Exception("Failed to construct MdeManager with exception "+e);
} }
} }
...@@ -58,97 +60,75 @@ public class MdeManager { ...@@ -58,97 +60,75 @@ public class MdeManager {
// example: GET ../mde/api/v1/chicago/transportation/routes?key=gT2nciTKwRv6Jy5njqm8fe7LW // example: GET ../mde/api/v1/chicago/transportation/routes?key=gT2nciTKwRv6Jy5njqm8fe7LW
public BaseRestResponse doRead(RequestContext requestContext) { public BaseRestResponse doRead(RequestContext requestContext) {
BaseRestResponse brr=null; BaseRestResponse brr=null;
String serviceId = requestContext.params[0] +"." +requestContext.params[1]; String[] params = requestContext.params;
String apiId = requestContext.params[2]; String serviceId = params[0] +"." +params[1];
String[] apiIdAsParams = getApiIdAsParams(requestContext);
String error = null; String error = null;
SimpleHttpResponse resp=null; SimpleHttpResponse resp=null;
Api api= servicesRepository.getApi(serviceId,apiId); brr = executeRequest(serviceId,apiIdAsParams,requestContext,null);
List<Action> actions = api.getActions(); return brr;
// TODO: 7/18/16 currently handle one action only
if (actions.size()==0)
error = "failed to find adapter for: "+serviceId+"."+apiId;
else {
for (Action action : actions) {
BaseAdapter adapter = adaptersRepository.getAdapter(action.getAdapterId());
if (adapter != null) {// && adapter.getClass().isInstance(HttpAdapter.class)) {
RequestParams requestParams = convertToRequestParams(requestContext, null);
resp = ((HttpAdapter) adapter).executeFlow(action.getApiOut(), requestParams);
// else
// error = "failed to find adapter " + action.getAdapterId();
break;//currently only one action
}
}
} }
return convertToBaseRestResponse(resp,error);
}
//one the parameter assumed to be null. if resp has a valid value it is converted,
//else if error is valid new BestRestResponse is created with this error
private BaseRestResponse convertToBaseRestResponse(SimpleHttpResponse resp, String error) {
BaseRestResponse baseRestResponse=null;
String errorContent=null;
if (resp!=null) { public BaseRestResponse doCreate(RequestContext requestContext, JsonNode content) {
if (resp.getStatusCode() == 200) { BaseRestResponse brr=null;
baseRestResponse = new BaseRestResponse(true, null); String serviceId ;
String content = resp.getContent();
baseRestResponse.objectNode = JsonHandler.getJsonNodeFromString(content);
} else {
errorContent = resp.getContent();
baseRestResponse = new BaseRestResponse(false, "Error: " + resp.getStatusCode() + ((errorContent != null) ? errorContent : ""));
}
}
else
baseRestResponse=new BaseRestResponse(false,error);
return baseRestResponse; int i;
serviceId = getServiceId(requestContext);
String[] apiIdAsParams = getApiIdAsParams(requestContext);
} brr = executeRequest(serviceId,apiIdAsParams,requestContext,content);
return brr;
private RequestParams convertToRequestParams(RequestContext requestContext, JsonNode content) {
RequestParams requestParams = new RequestParams();
requestParams.setParams(requestContext.params);
requestParams.setQueryParameters(requestContext.queryParameters);
requestParams.setMethod(requestContext.enumCrudMethod);
if (content != null )
requestParams.setContent(content.toString());
return requestParams;
} }
public BaseRestResponse doCreate(RequestContext requestContext, JsonNode content) { private BaseRestResponse executeRequest(String serviceId, String[] apiIdAsParams, RequestContext requestContext, JsonNode content) {
BaseRestResponse brr=null;
String serviceId = requestContext.params[0] +"." +requestContext.params[1];
String apiId = requestContext.params[2];
String error = null;
SimpleHttpResponse resp=null; SimpleHttpResponse resp=null;
String error=null;
Api api= servicesRepository.getApi(serviceId,apiId); if (apiIdAsParams!=null) {
Api api = servicesRepository.getApi(serviceId, apiIdAsParams);
if (api != null) {
List<Action> actions = api.getActions(); List<Action> actions = api.getActions();
// TODO: 7/18/16 currently handle one action only // TODO: 7/18/16 currently handle one action only
if (actions.size()==0) if (actions.size() != 0) {
error = "failed to find adapter for: "+serviceId+"."+apiId;
else {
for (Action action : actions) { for (Action action : actions) {
BaseAdapter adapter = adaptersRepository.getAdapter(action.getAdapterId()); BaseAdapter adapter = adaptersRepository.getAdapter(action.getAdapterId());
if (adapter != null) {// && adapter.getClass().isInstance(HttpAdapter.class)) { if (adapter != null) {// && adapter.getClass().isInstance(HttpAdapter.class)) {
RequestParams requestParams = convertToRequestParams(requestContext,content); RequestParams requestParams = convertToRequestParams(requestContext, content, api.getMapKeyToParamIndex());
resp = ((HttpAdapter) adapter).executeFlow(action.getApiOut(), requestParams); resp = ((HttpAdapter) adapter).executeFlow(action.getApiOut(), requestParams);
// else
// error = "failed to find adapter " + action.getAdapterId();
break;//currently only one action break;//currently only one action
} }
} }
} else
error = "failed to find adapter for serviceID: " + serviceId + ", apiId" + apiIdAsParams + " reason: missing actions";
} else
error = "failed to find adapter for serviceID: " + serviceId + ", apiId" + apiIdAsParams + " reason: api is null";
} }
else
error = "failed to find adapter for serviceID: " + serviceId + ", apiId" + apiIdAsParams + " reason: apiIdAsParams is null";
return convertToBaseRestResponse(resp,error); return convertToBaseRestResponse(resp,error);
} }
private String getServiceId(RequestContext requestContext) {
return requestContext.params[0]+"."+requestContext.params[1];
}
private String[] getApiIdAsParams(RequestContext requestContext) {
String[] params = null;
int size = requestContext.params.length;
if (size>2){
params = new String[size-2];
System.arraycopy(requestContext.params, 2, params,0, size-2);
}
return params;
}
public BaseRestResponse doUpdate(RequestContext requestContext) { public BaseRestResponse doUpdate(RequestContext requestContext) {
return new BaseRestResponse(false, "method " +Thread.currentThread().getStackTrace()[1].getMethodName() + "not implemented yet"); return new BaseRestResponse(false, "method " +Thread.currentThread().getStackTrace()[1].getMethodName() + "not implemented yet");
} }
...@@ -164,8 +144,7 @@ public class MdeManager { ...@@ -164,8 +144,7 @@ public class MdeManager {
private void ValidityCheck() { private void ValidityCheck() {
} }
private void loadAdapters(ILogger logger) private void loadAdapters(ILogger logger) throws Exception {
{
adaptersRepository = new AdaptersRepository(logger); adaptersRepository = new AdaptersRepository(logger);
adaptersRepository.load(); adaptersRepository.load();
} }
...@@ -176,4 +155,50 @@ public class MdeManager { ...@@ -176,4 +155,50 @@ public class MdeManager {
servicesRepository.load(); servicesRepository.load();
} }
//one the parameter assumed to be null. if resp has a valid value it is converted,
//else if error is valid new BestRestResponse is created with this error
private BaseRestResponse convertToBaseRestResponse(SimpleHttpResponse resp, String error) {
BaseRestResponse baseRestResponse=null;
String errorContent=null;
if (resp!=null) {
if (resp.getStatusCode() == 200) {
baseRestResponse = new BaseRestResponse(true, null);
String content = resp.getContent();
baseRestResponse.objectNode = JsonHandler.getJsonNodeFromString(content);
} else {
errorContent = resp.getContent();
baseRestResponse = new BaseRestResponse(false, "Error: " + resp.getStatusCode() + ((errorContent != null) ? errorContent : ""));
}
}
else
baseRestResponse=new BaseRestResponse(false,error);
return baseRestResponse;
}
private RequestParams convertToRequestParams(RequestContext requestContext, JsonNode content, Map<String, Integer> mapVariableToParamIndex) {
RequestParams requestParams = new RequestParams();
requestParams.setParams(requestContext.params);
requestParams.setQueryParameters(requestContext.queryParameters);
requestParams.setMethod(requestContext.enumCrudMethod);
if (content != null )
requestParams.setContent(content.toString());
if (mapVariableToParamIndex!=null && mapVariableToParamIndex.size()>0) {
Map<String,String> keyValueVariables = mapVariableToParamIndex.entrySet().stream()
.collect(Collectors.toMap(
e -> e.getKey(),
e -> requestContext.params[e.getValue()]));
requestParams.setVariablesValues(keyValueVariables);
}
return requestParams;
}
} }
...@@ -57,25 +57,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -57,25 +57,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
httpClient = new SimpleHttpClient(); httpClient = new SimpleHttpClient();
httpClient.Initialize(100); httpClient.Initialize(100);
this.webSocketManager = new WebSocketManager(authClient,config.getConfigHttpRequestParams().getHeaders(),adapterId);
List<NameValueParam> headers= new ArrayList<>();
NameValueParam header = new NameValueParam();
if (this.adapterId.equals("adapter.ge.parking")) {
//parking
header.setName("predix-zone-id");
header.setValue("c54e3e63-8dc6-425e-a533-64e061f64023");
headers.add(header);
}
//traffic
else if (this.adapterId.equals("adapter.ge.traffic")){
header.setName("predix-zone-id");
header.setValue("b6fc22b6-ad71-423e-867b-a1b197f6cfc2");
headers.add(header);
}
this.webSocketManager = new WebSocketManager(authClient,headers,adapterId);
this.setModelReferences(); this.setModelReferences();
...@@ -89,6 +71,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -89,6 +71,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
HttpAdapterConfig config = (HttpAdapterConfig) getModel().getConfig(); HttpAdapterConfig config = (HttpAdapterConfig) getModel().getConfig();
OnHttpResponse onHttpResponse; OnHttpResponse onHttpResponse;
SimpleHttpAction httpAction; SimpleHttpAction httpAction;
List<BaseAction> actions;
// ActionsList actionsListOnSuccess, actionsListOnError; // ActionsList actionsListOnSuccess, actionsListOnError;
HttpContentActions actionsListOnSuccess, actionsListOnError; HttpContentActions actionsListOnSuccess, actionsListOnError;
...@@ -102,24 +85,23 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -102,24 +85,23 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
onHttpResponse = (OnHttpResponse) httpFlow.getOnResponse(); onHttpResponse = (OnHttpResponse) httpFlow.getOnResponse();
if (onHttpResponse != null) { if (onHttpResponse != null) {
actionsListOnSuccess = onHttpResponse.getOnSuccess(); actionsListOnSuccess = onHttpResponse.getOnSuccess();
List<BaseAction> actions = actionsListOnSuccess.getActions(); if (actionsListOnSuccess!=null) {
actions = actionsListOnSuccess.getActions();
for (BaseAction action : for (BaseAction action :
actions) { actions) {
if (myTypeOf(action).equals("WebSocketAction")) { if (myTypeOf(action).equals("WebSocketAction")) {
httpFlow.addWebSocketAction((WebSocketAction) action); httpFlow.addWebSocketAction((WebSocketAction) action);
((WebSocketAction)action).setWebSocetManager(webSocketManager); ((WebSocketAction) action).setWebSocetManager(webSocketManager);
} } else if (myTypeOf(action).equals("SimpleHttpAction")) {
else if (myTypeOf(action).equals("SimpleHttpAction")) {
action.setAdapterReferences(config.getConfigHttpRequestParams(), action.setAdapterReferences(config.getConfigHttpRequestParams(),
httpClient, httpClient,
authClient); authClient);
httpFlow.addHttpAction((SimpleHttpAction) action); httpFlow.addHttpAction((SimpleHttpAction) action);
} } else if (myTypeOf(action).equals("JsonConvertAction")) {
else if (myTypeOf(action).equals("JsonConvertAction")) {
List<IntermediateOperation> interOperations = ((JsonConvertAction) action).getParams().getIntermediateOperations(); List<IntermediateOperation> interOperations = ((JsonConvertAction) action).getParams().getIntermediateOperations();
for (IntermediateOperation operation : for (IntermediateOperation operation :
interOperations) { interOperations) {
if (myTypeOf(operation.getOperationParams()).contains("Map")) { if (myTypeOf(operation).contains("Map")) {
BaseAction action1 = ((MapOperationParams) operation.getOperationParams()).getAction(); BaseAction action1 = ((MapOperationParams) operation.getOperationParams()).getAction();
if (myTypeOf(action1).equals("SimpleHttpAction")) { if (myTypeOf(action1).equals("SimpleHttpAction")) {
httpFlow.addHttpAction((SimpleHttpAction) action1); httpFlow.addHttpAction((SimpleHttpAction) action1);
...@@ -131,25 +113,26 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -131,25 +113,26 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
} }
} }
} }
}
actionsListOnError = onHttpResponse.getOnError(); actionsListOnError = onHttpResponse.getOnError();
if (actionsListOnError != null) {
actions = actionsListOnError.getActions(); actions = actionsListOnError.getActions();
for (BaseAction act : actions) { for (BaseAction act : actions) {
if (myTypeOf(act).equals("WebSocketAction")) { if (myTypeOf(act).equals("WebSocketAction")) {
httpFlow.addWebSocketAction((WebSocketAction) act); httpFlow.addWebSocketAction((WebSocketAction) act);
((WebSocketAction)act).setWebSocetManager(webSocketManager); ((WebSocketAction) act).setWebSocetManager(webSocketManager);
} }
if (myTypeOf(act).equals("SimpleHttpAction")) { if (myTypeOf(act).equals("SimpleHttpAction")) {
httpFlow.addHttpAction((SimpleHttpAction) act); httpFlow.addHttpAction((SimpleHttpAction) act);
act.setAdapterReferences(config.getConfigHttpRequestParams(), act.setAdapterReferences(config.getConfigHttpRequestParams(),
httpClient, httpClient,
authClient); authClient);
} } else if (myTypeOf(act).equals("JsonConvertAction")) {
else if (myTypeOf(act).equals("JsonConvertAction")) {
List<IntermediateOperation> interOperations = ((JsonConvertAction) act).getParams().getIntermediateOperations(); List<IntermediateOperation> interOperations = ((JsonConvertAction) act).getParams().getIntermediateOperations();
for (IntermediateOperation operation : for (IntermediateOperation operation :
interOperations) { interOperations) {
if (myTypeOf(operation.getOperationParams()).contains("Map")) { if (myTypeOf(operation).contains("Map")) {
BaseAction action1 = ((MapOperationParams) operation.getOperationParams()).getAction(); BaseAction action1 = ((MapOperationParams) operation.getOperationParams()).getAction();
if (myTypeOf(action1).equals("SimpleHttpAction")) { if (myTypeOf(action1).equals("SimpleHttpAction")) {
httpFlow.addHttpAction((SimpleHttpAction) action1); httpFlow.addHttpAction((SimpleHttpAction) action1);
...@@ -165,6 +148,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -165,6 +148,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
} }
} }
} }
}
private void setHttpActionsReferences(List<BaseAction> listBaseActions) { private void setHttpActionsReferences(List<BaseAction> listBaseActions) {
...@@ -205,6 +189,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -205,6 +189,7 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
HttpFlow flow = this.getModel().getFlow(flowId); HttpFlow flow = this.getModel().getFlow(flowId);
if (flow!=null){ if (flow!=null){
//set run time RequestParams to all action of types SimpleHttpAction and WebSocketAction
flow.setRunTimeHttpRequest(input); flow.setRunTimeHttpRequest(input);
try { try {
resp = flow.execute(input); resp = flow.execute(input);
......
package logic.adapter.HttpAdapter; package logic.adapter.HttpAdapter;
import logic.adapter.HttpAdapter.model.NameValueParam;
import microservice.defs.Enums; import microservice.defs.Enums;
import java.util.ArrayList;
import java.util.Deque; import java.util.Deque;
import java.util.Map; import java.util.Map;
...@@ -7,6 +10,17 @@ import java.util.Map; ...@@ -7,6 +10,17 @@ import java.util.Map;
* Created by eli on 11/29/16. * Created by eli on 11/29/16.
*/ */
public class RequestParams { public class RequestParams {
private String[] params = null;
private Map<String, String> variablesValues =null;
private Map<String, Deque<String>> queryParameters = null;
private Enums.EnumCrudMethod enumCrudMethod;
private Map<String, String> headersMap = null;
private String content;
public String[] getParams() { public String[] getParams() {
return params; return params;
} }
...@@ -40,11 +54,13 @@ public class RequestParams { ...@@ -40,11 +54,13 @@ public class RequestParams {
this.content = content; this.content = content;
} }
private String[] params = null; public Map<String, String> getVariablesValues() {
private Map<String, Deque<String>> queryParameters = null; return variablesValues;
private Enums.EnumCrudMethod enumCrudMethod; }
private Map<String, String> headersMap = null;
private String content; public void setVariablesValues(Map<String, String> variablesValues) {
this.variablesValues = variablesValues;
}
public RequestParams() {} public RequestParams() {}
public String getQueryParameter(String paramName) { public String getQueryParameter(String paramName) {
......
package logic.adapter.HttpAdapter.action;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import logic.adapter.action.BaseAction;
import logic.adapter.action.ExtractValueAction;
import logic.adapter.action.SubStringAction;
import logic.adapter.model.ExtractValueActionParams;
import logic.adapter.model.SubStringActionParams;
import java.util.function.Function;
/**
* Created by eli on 12/18/16.
*/
public class ExtractSubStringAction implements Function<JsonNode,String>{
private ExtractValueAction extractValueAction;
private SubStringAction subStringAction;
@JsonCreator
public ExtractSubStringAction(@JsonProperty("extract") ExtractValueActionParams extractValueActionParams,
@JsonProperty("subString") SubStringActionParams subStringActionParams) {
this.extractValueAction = new ExtractValueAction(extractValueActionParams);
this.subStringAction = new SubStringAction(subStringActionParams);
}
/**
* Applies this function to the given argument.
*
* @param jsonNode the function argument
* @return the function result
*/
@Override
public String apply(JsonNode jsonNode) {
JsonNode retNode;
String retStr=null;
try {
retNode = extractValueAction.apply(jsonNode);
retStr = subStringAction.apply(retNode);
} catch (Exception e) {
e.printStackTrace();
}
return retStr;
}
}
...@@ -3,16 +3,12 @@ package logic.adapter.HttpAdapter.action; ...@@ -3,16 +3,12 @@ package logic.adapter.HttpAdapter.action;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import common.JsonHandler;
import http.simpleHttpClient.SimpleHttpRequest;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.HttpAdapter; import logic.adapter.HttpAdapter.HttpAdapter;
import logic.adapter.HttpAdapter.RequestParams; import logic.adapter.HttpAdapter.RequestParams;
import logic.adapter.action.ActionsList;
import logic.adapter.action.BaseAction; import logic.adapter.action.BaseAction;
import util.Utils; import util.Utils;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
...@@ -99,21 +95,24 @@ public class HttpContentActions {//extends ActionsList<SimpleHttpResponse> { ...@@ -99,21 +95,24 @@ public class HttpContentActions {//extends ActionsList<SimpleHttpResponse> {
} }
public void setRunTimeHttpRequest(RequestParams inRequestParams) { // public void setRunTimeHttpRequest(RequestParams inRequestParams) {
this.runTimeHttpRequest = inRequestParams; // this.runTimeHttpRequest = inRequestParams;
} // }
//
private RequestParams runTimeHttpRequest; // private RequestParams runTimeHttpRequest;
// @Override // @Override
public SimpleHttpResponse executeActions(SimpleHttpResponse input) throws Exception { public SimpleHttpResponse executeActions(SimpleHttpResponse input) throws Exception {
String content = input.getContent(); String content = input.getContent();
JsonNode node = (JsonNode)Utils.readObjectFromString1(content, JsonNode.class); JsonNode node = (JsonNode)Utils.readObjectFromString1(content, JsonNode.class);
List<BaseAction> actions=getActions(); List<BaseAction> actions=getActions();
SimpleHttpResponse resp;
for (BaseAction action : actions) for (BaseAction action : actions)
{ {
if (action.getType().equals(SimpleHttpAction.TYPE)) { if (action.getType().equals(SimpleHttpAction.TYPE)) {
SimpleHttpResponse resp = (SimpleHttpResponse) action.apply(runTimeHttpRequest); //SimpleHttpResponse resp = (SimpleHttpResponse) action.apply(runTimeHttpRequest);
((SimpleHttpAction)action).computeVariables(node);
resp = (SimpleHttpResponse) action.apply(null);
if (resp.getStatusCode()!= 200) if (resp.getStatusCode()!= 200)
{ {
return new SimpleHttpResponse(500,"failed onSuccess.executeActions.httpAction with error:" +resp.getStatusCode() ); return new SimpleHttpResponse(500,"failed onSuccess.executeActions.httpAction with error:" +resp.getStatusCode() );
...@@ -123,10 +122,12 @@ public class HttpContentActions {//extends ActionsList<SimpleHttpResponse> { ...@@ -123,10 +122,12 @@ public class HttpContentActions {//extends ActionsList<SimpleHttpResponse> {
} }
//assumed that after extractValueAction //assumed that after extractValueAction
else if (HttpAdapter.myTypeOf(action).equals("WebSocketAction")){ else if (HttpAdapter.myTypeOf(action).equals("WebSocketAction")){
Map<String,String > runTimeParams = new HashMap<>(); // Map<String,String > runTimeParams = new HashMap<>();
if (node!=null && node.isTextual()) runTimeParams.put("webSocket", node.asText()); // if (node!=null && node.isTextual()) runTimeParams.put("webSocket", node.asText());
action.setRunTimeParameters(runTimeParams); // action.setRunTimeVariables(runTimeParams);
SimpleHttpResponse resp = (SimpleHttpResponse) action.apply(runTimeHttpRequest); // SimpleHttpResponse resp = (SimpleHttpResponse) action.apply(runTimeHttpRequest);
((WebSocketAction)action).computeVariables(node);
resp = (SimpleHttpResponse) action.apply(null);
} }
else //JsonNodeAction.class else //JsonNodeAction.class
......
...@@ -2,21 +2,16 @@ package logic.adapter.HttpAdapter.action; ...@@ -2,21 +2,16 @@ package logic.adapter.HttpAdapter.action;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import http.simpleHttpClient.SimpleHttpClient; import com.fasterxml.jackson.databind.JsonNode;
import http.simpleHttpClient.SimpleHttpRequest; import http.simpleHttpClient.SimpleHttpRequest;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.ErrorLoginException; import logic.adapter.HttpAdapter.ErrorLoginException;
import logic.adapter.HttpAdapter.OAuth2Client;
import logic.adapter.HttpAdapter.RequestParams; import logic.adapter.HttpAdapter.RequestParams;
import logic.adapter.HttpAdapter.model.ConfigHttpRequestParams;
import logic.adapter.HttpAdapter.model.HttpRequestActionParams; import logic.adapter.HttpAdapter.model.HttpRequestActionParams;
import logic.adapter.HttpAdapter.model.NameValueParam;
import logic.adapter.action.BaseAction; import logic.adapter.action.BaseAction;
import util.HttpRequestResolver; import util.HttpRequestResolver;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.util.Base64;
import java.util.List;
/** /**
* Created by eli on 11/17/16. * Created by eli on 11/17/16.
...@@ -72,7 +67,6 @@ public class SimpleHttpAction extends BaseAction<HttpRequestActionParams ,Reques ...@@ -72,7 +67,6 @@ public class SimpleHttpAction extends BaseAction<HttpRequestActionParams ,Reques
RequestParams inRequestParams = (requestParams!=null)?requestParams:getRunTimeInput(); RequestParams inRequestParams = (requestParams!=null)?requestParams:getRunTimeInput();
//if authentication not needed or token already exist //if authentication not needed or token already exist
httpRequest = buildHttpRequest(inRequestParams); httpRequest = buildHttpRequest(inRequestParams);
try { try {
resp = httpClient.processRequest(httpRequest); resp = httpClient.processRequest(httpRequest);
...@@ -100,16 +94,20 @@ public class SimpleHttpAction extends BaseAction<HttpRequestActionParams ,Reques ...@@ -100,16 +94,20 @@ public class SimpleHttpAction extends BaseAction<HttpRequestActionParams ,Reques
private SimpleHttpRequest buildHttpRequest(RequestParams inRequestParams) { protected SimpleHttpRequest buildHttpRequest(RequestParams inRequestParams) {
SimpleHttpRequest request = new HttpRequestResolver().createResolvedRequest(inRequestParams, SimpleHttpRequest request = new HttpRequestResolver().createResolvedRequest(inRequestParams,
adapterHttpParams, adapterHttpParams,
getParams(), getParams(),
((oauth2Client != null)?oauth2Client.getToken():null), ((oauth2Client != null)?oauth2Client.getToken():null),
getRunTimeParameters()); getRunTimeVariables());
return request; return request;
} }
public void computeVariables(JsonNode node) throws Exception {
setRunTimeVariables(getParams().computeVariables(node));
}
} }
...@@ -3,6 +3,7 @@ package logic.adapter.HttpAdapter.action; ...@@ -3,6 +3,7 @@ package logic.adapter.HttpAdapter.action;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import com.neovisionaries.ws.client.WebSocketException; import com.neovisionaries.ws.client.WebSocketException;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.ErrorLoginException; import logic.adapter.HttpAdapter.ErrorLoginException;
...@@ -61,9 +62,8 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa ...@@ -61,9 +62,8 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa
public SimpleHttpResponse apply(RequestParams requestParams) { public SimpleHttpResponse apply(RequestParams requestParams) {
OnEventDetails details=null; OnEventDetails details=null;
RequestParams inRequestParams = (requestParams!=null)?requestParams:getRunTimeInput(); RequestParams inRequestParams = (requestParams!=null)?requestParams:getRunTimeInput();
String[] params = inRequestParams.getParams(); String mdeKey=null;
String mdeKey = params[3];//id String uid=null;
String uid = params[4];//uid
String httpPayload = inRequestParams.getContent(); String httpPayload = inRequestParams.getContent();
try { try {
details = (OnEventDetails) Utils.readObjectFromString1(httpPayload, OnEventDetails.class); details = (OnEventDetails) Utils.readObjectFromString1(httpPayload, OnEventDetails.class);
...@@ -72,7 +72,7 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa ...@@ -72,7 +72,7 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa
return new SimpleHttpResponse(500, "Failed to read Request payload OnEventDetails"); return new SimpleHttpResponse(500, "Failed to read Request payload OnEventDetails");
} }
Map<String, String> runTimeParameters = getRunTimeParameters(); Map<String, String> runTimeParameters = getRunTimeVariables();
String webSocket=null; String webSocket=null;
if (runTimeParameters.containsKey("webSocket")){ if (runTimeParameters.containsKey("webSocket")){
webSocket = runTimeParameters.get("webSocket"); webSocket = runTimeParameters.get("webSocket");
...@@ -81,6 +81,9 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa ...@@ -81,6 +81,9 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa
return new SimpleHttpResponse(500, "Failed to extract web socket url"); return new SimpleHttpResponse(500, "Failed to extract web socket url");
try { try {
mdeKey=getParams().getResolvedMdeKey(inRequestParams.getVariablesValues());
uid=getParams().getResolvedUid(inRequestParams.getVariablesValues());
webSocket=getParams().getResolvedWebSocket(getRunTimeVariables());
webSocketManager.connect(mdeKey,uid,webSocket,details); webSocketManager.connect(mdeKey,uid,webSocket,details);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
return new SimpleHttpResponse(500, "failed to connect to webSocket with error: "+e); return new SimpleHttpResponse(500, "failed to connect to webSocket with error: "+e);
...@@ -107,18 +110,10 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa ...@@ -107,18 +110,10 @@ public class WebSocketAction extends BaseAction<WebSocketActionParams ,RequestPa
this.webSocketManager = webSocetManager; this.webSocketManager = webSocetManager;
} }
public void computeVariables(JsonNode node) throws Exception {
setRunTimeVariables(getParams().computeVariables(node));
}
// private SimpleHttpRequest buildHttpRequest(RequestParams inRequestParams) {
//
//
// SimpleHttpRequest request = new HttpRequestResolver().createResolvedRequest(inRequestParams,
// adapterHttpParams,
// getParams(),
// ((oauth2Client != null)?oauth2Client.getToken():null),
// getRunTimeParameters());
//
// return request;
// }
} }
......
package logic.adapter.HttpAdapter.action; package logic.adapter.HttpAdapter.action;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import logic.adapter.HttpAdapter.model.ComputeVariable;
import logic.adapter.HttpAdapter.model.NameValueParam; import logic.adapter.HttpAdapter.model.NameValueParam;
import logic.adapter.model.BaseActionParams; import logic.adapter.model.BaseActionParams;
import logic.adapter.model.DynamicVariablesParams;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Created by eli on 12/4/16. * Created by eli on 12/4/16.
*/ */
public class WebSocketActionParams extends BaseActionParams{ public class WebSocketActionParams extends DynamicVariablesParams{
@JsonProperty("headers") @JsonProperty("headers")
private List<NameValueParam> headers = new ArrayList<>(); private List<NameValueParam> headers;
@JsonProperty("webSocket")
private String webSocket;
@JsonProperty("mdeKey")
private String mdeKey;
@JsonProperty("uid")
private String uid;
// "webSocket": "$webSocket"
// "mdeKey": "$mdeKey",
// "uid": "$uid"
public WebSocketActionParams(@JsonProperty("variables") Map<String, ComputeVariable> mapVariableToValueComputation,
@JsonProperty("headers") List<NameValueParam> headers,
@JsonProperty("webSocket") String webSocket,
@JsonProperty("mdeKey") String mdeKey,
@JsonProperty("uid") String uid) {
super(mapVariableToValueComputation);
this.headers=headers;
this.webSocket=webSocket;
this.mdeKey=mdeKey;
this.uid=uid;
}
@Override @Override
...@@ -26,4 +51,28 @@ public class WebSocketActionParams extends BaseActionParams{ ...@@ -26,4 +51,28 @@ public class WebSocketActionParams extends BaseActionParams{
public boolean isValid() { public boolean isValid() {
return true; return true;
} }
public String getResolvedMdeKey(Map<String, String> variablesValues) {
return resolve(this.mdeKey,variablesValues);
}
private String resolve(String key, Map<String, String> variablesValues) {
String resolved=null;
String realKey=null;
if (key!=null && key.startsWith("$")){
realKey = key.substring(1);
resolved = variablesValues.get(realKey);
}
else if (key!=null)
resolved=key;
return resolved;
}
public String getResolvedUid(Map<String, String> variablesValues) {
return resolve(this.uid,variablesValues);
}
public String getResolvedWebSocket(Map<String, String> variablesValues) {
return resolve(this.webSocket,variablesValues);
}
} }
package logic.adapter.HttpAdapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import logic.adapter.HttpAdapter.action.ExtractSubStringAction;
import logic.adapter.action.BaseAction;
import logic.adapter.action.ExtractValueAction;
import logic.adapter.action.SubStringAction;
import logic.adapter.model.BaseActionParams;
import java.util.List;
import static util.Utils.myTypeOf;
/**
* Created by eli on 12/11/16.
*/
public class ComputeVariable{
public ExtractSubStringAction getAction() {
return action;
}
@JsonProperty("action")
private ExtractSubStringAction action;
@JsonCreator
public ComputeVariable(@JsonProperty("action") ExtractSubStringAction action) {
this.action = action;
}
@JsonIgnore
private String actionRunTimeResult;
public String execute(JsonNode node) throws Exception {
return action.apply(node);
}
}
package logic.adapter.HttpAdapter.model; package logic.adapter.HttpAdapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonPropertyOrder;
...@@ -27,6 +28,15 @@ public class ConfigHttpRequestParams implements ModelValidator { ...@@ -27,6 +28,15 @@ public class ConfigHttpRequestParams implements ModelValidator {
@JsonProperty("headers") @JsonProperty("headers")
private List<NameValueParam> headers = new ArrayList<>(); private List<NameValueParam> headers = new ArrayList<>();
@JsonCreator
public ConfigHttpRequestParams(@JsonProperty("baseUrl") String baseUrl,
@JsonProperty("basePath") String basePath,
@JsonProperty("headers") ArrayList<NameValueParam> headers) {
this.baseUrl = baseUrl;
this.basePath = basePath;
this.headers = headers;
}
/** /**
* *
......
...@@ -4,9 +4,11 @@ import com.fasterxml.jackson.annotation.JsonInclude; ...@@ -4,9 +4,11 @@ import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder; import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import logic.adapter.model.BaseActionParams; import logic.adapter.model.BaseActionParams;
import logic.adapter.model.DynamicVariablesParams;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* Created by eli on 11/17/16. * Created by eli on 11/17/16.
...@@ -19,7 +21,7 @@ import java.util.List; ...@@ -19,7 +21,7 @@ import java.util.List;
"headers", "headers",
"content" "content"
}) })
public class HttpRequestActionParams extends BaseActionParams { public class HttpRequestActionParams extends DynamicVariablesParams {
@JsonProperty("id") @JsonProperty("id")
private String id; private String id;
...@@ -34,7 +36,8 @@ public class HttpRequestActionParams extends BaseActionParams { ...@@ -34,7 +36,8 @@ public class HttpRequestActionParams extends BaseActionParams {
@JsonProperty("content") @JsonProperty("content")
private Object content; private Object content;
public HttpRequestActionParams() { public HttpRequestActionParams(@JsonProperty("variables") Map<String, ComputeVariable> variablesToCompute) {
super(variablesToCompute);
} }
......
package logic.adapter.HttpAdapter.model; package logic.adapter.HttpAdapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import http.simpleHttpClient.SimpleHttpClient; import http.simpleHttpClient.SimpleHttpClient;
import logic.adapter.HttpAdapter.OAuth2Client; import logic.adapter.HttpAdapter.OAuth2Client;
import logic.adapter.action.BaseAction;
import java.util.HashMap;
import java.util.function.Function; import java.util.function.Function;
/** /**
...@@ -11,7 +15,8 @@ import java.util.function.Function; ...@@ -11,7 +15,8 @@ import java.util.function.Function;
public abstract class IntermediateOperation<TypeParams extends BaseOperationParams, TypeFunc> public abstract class IntermediateOperation<TypeParams extends BaseOperationParams, TypeFunc>
extends Operation<TypeParams> { extends Operation<TypeParams> {
public IntermediateOperation(TypeParams operationParams) {
public IntermediateOperation( TypeParams operationParams) {
super(operationParams); super(operationParams);
this.func=buildFunc(); this.func=buildFunc();
} }
...@@ -27,6 +32,8 @@ public abstract class IntermediateOperation<TypeParams extends BaseOperationPara ...@@ -27,6 +32,8 @@ public abstract class IntermediateOperation<TypeParams extends BaseOperationPara
OAuth2Client oAuth2Client){ OAuth2Client oAuth2Client){
getOperationParams().setAdapterReferences(configHttpRequestParams,httpClient,oAuth2Client ); getOperationParams().setAdapterReferences(configHttpRequestParams,httpClient,oAuth2Client );
} }
private TypeFunc func; private TypeFunc func;
......
package logic.adapter.HttpAdapter.model; package logic.adapter.HttpAdapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import logic.adapter.action.BaseAction;
import util.Utils;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Stream; import java.util.stream.Stream;
...@@ -9,7 +18,12 @@ import java.util.stream.Stream; ...@@ -9,7 +18,12 @@ import java.util.stream.Stream;
public abstract class MapIntermediateOperation<TypeIn, TypeOut> extends IntermediateOperation<MapOperationParams, Function<TypeIn,TypeOut>> public abstract class MapIntermediateOperation<TypeIn, TypeOut> extends IntermediateOperation<MapOperationParams, Function<TypeIn,TypeOut>>
{ {
public static final String TYPE = "MapIntermediateOperation"; public static final String TYPE = "MapIntermediateOperation";
public MapIntermediateOperation(MapOperationParams operationParams) {
@JsonCreator
public MapIntermediateOperation(@JsonProperty("operationParams") MapOperationParams operationParams)
{
super(operationParams); super(operationParams);
} }
@Override @Override
......
...@@ -6,11 +6,14 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -6,11 +6,14 @@ import com.fasterxml.jackson.databind.JsonNode;
import common.JsonHandler; import common.JsonHandler;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.action.SimpleHttpAction; import logic.adapter.HttpAdapter.action.SimpleHttpAction;
import logic.adapter.action.BaseAction;
import logic.adapter.action.JsonNodeAction; import logic.adapter.action.JsonNodeAction;
import util.Utils;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
import static util.Utils.myTypeOf;
/** /**
* Created by eli on 11/22/16. * Created by eli on 11/22/16.
*/ */
...@@ -25,19 +28,22 @@ public class MapJsonToJsonOperation extends MapIntermediateOperation<JsonNode, J ...@@ -25,19 +28,22 @@ public class MapJsonToJsonOperation extends MapIntermediateOperation<JsonNode, J
protected Function<JsonNode, JsonNode> buildFunc() { protected Function<JsonNode, JsonNode> buildFunc() {
Function<JsonNode,JsonNode> ret = (node) -> { Function<JsonNode,JsonNode> ret = (node) -> {
SimpleHttpResponse resp; SimpleHttpResponse resp;
String content;
try { try {
int end_index = getOperationParams().getAction().toString().indexOf('@'); String type=myTypeOf(getOperationParams().getAction());
String type=getOperationParams().getAction().toString().substring(0,end_index);
int startIndex = type.lastIndexOf(".");
startIndex++;
type = type.substring(startIndex,end_index);
if (type.equals("SimpleHttpAction")) { if (type.equals("SimpleHttpAction")) {
SimpleHttpAction httpAction = (SimpleHttpAction)getOperationParams().getAction(); SimpleHttpAction httpAction = (SimpleHttpAction)getOperationParams().getAction();
//assumed that the action holds its input already, and use it //assumed that the action holds its input already, and use it
resp = httpAction.apply(null); httpAction.computeVariables(node);
resp = ((SimpleHttpAction)httpAction).apply(null);
if (resp.getStatusCode()!=200) if (resp.getStatusCode()!=200)
throw new Exception("MapJsonToJsonOperation: http action failed with status code: "+resp.getStatusCode()+" errorMsg: "+ resp.getContent() ); throw new Exception("MapJsonToJsonOperation: http action failed with status code: "+resp.getStatusCode()+" errorMsg: "+ resp.getContent() );
return JsonHandler.getJsonNodeFromObject(resp.getContent()); else{
content=resp.getContent();
System.out.println("MapJsonToJsonOperation params="+ getOperationParams().toString()+" convert node= "+node.toString()+" to convertedNode= "+content);
return JsonHandler.getJsonNodeFromObject(content);
}
} }
//assumed JsonNodeAction.class //assumed JsonNodeAction.class
//else if(getOperationParams().getAction().getClass().isInstance(JsonNodeAction.class)) { //else if(getOperationParams().getAction().getClass().isInstance(JsonNodeAction.class)) {
......
...@@ -4,11 +4,11 @@ package logic.adapter.HttpAdapter.model; ...@@ -4,11 +4,11 @@ package logic.adapter.HttpAdapter.model;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import common.JsonHandler;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.action.SimpleHttpAction; import logic.adapter.HttpAdapter.action.SimpleHttpAction;
import logic.adapter.action.JsonNodeAction; import logic.adapter.action.JsonNodeAction;
import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
/** /**
...@@ -18,7 +18,7 @@ import java.util.function.Function; ...@@ -18,7 +18,7 @@ import java.util.function.Function;
public class MapJsonToStringOperation extends MapIntermediateOperation<JsonNode, JsonNode> { public class MapJsonToStringOperation extends MapIntermediateOperation<JsonNode, JsonNode> {
@JsonCreator @JsonCreator
public MapJsonToStringOperation(@JsonProperty("operationParams") MapOperationParams operationParams) { public MapJsonToStringOperation(@JsonProperty("operationParams") MapOperationParams operationParams){
super(operationParams); super(operationParams);
} }
...@@ -26,12 +26,15 @@ public class MapJsonToStringOperation extends MapIntermediateOperation<JsonNode ...@@ -26,12 +26,15 @@ public class MapJsonToStringOperation extends MapIntermediateOperation<JsonNode
protected Function<JsonNode, JsonNode> buildFunc() { protected Function<JsonNode, JsonNode> buildFunc() {
Function<JsonNode,JsonNode> ret = (node) -> { Function<JsonNode,JsonNode> ret = (node) -> {
SimpleHttpResponse resp; SimpleHttpResponse resp;
JsonNode retNode;
try { try {
//in this case assumed that the action get and return JsonNode!!!!! no else section //in this case assumed that the action get and return JsonNode!!!!! no else section
if(!getOperationParams().getAction().getClass().isInstance(SimpleHttpAction.class)) { if(!getOperationParams().getAction().getClass().isInstance(SimpleHttpAction.class)) {
JsonNodeAction JsonAction = (JsonNodeAction)getOperationParams().getAction(); JsonNodeAction JsonAction = (JsonNodeAction)getOperationParams().getAction();
JsonNode transformedNode = (JsonNode)JsonAction.apply(node); retNode = (JsonNode)JsonAction.apply(node);
return transformedNode; System.out.println("MapJsonToStringOperation ,params="+ getOperationParams().toString()+"convert from node= [" +node.toString()+"] to convertedNode= ["+ retNode.toString()+"]");
return retNode;
} }
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
......
...@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.*; ...@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.*;
import http.simpleHttpClient.SimpleHttpClient; import http.simpleHttpClient.SimpleHttpClient;
import logic.adapter.HttpAdapter.OAuth2Client; import logic.adapter.HttpAdapter.OAuth2Client;
import logic.adapter.action.BaseAction; import logic.adapter.action.BaseAction;
import logic.adapter.model.BaseActionParams; import microservice.params.CommandParamsBuilder;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
...@@ -22,21 +22,27 @@ public class MapOperationParams extends BaseOperationParams{ ...@@ -22,21 +22,27 @@ public class MapOperationParams extends BaseOperationParams{
public BaseAction getAction() { public BaseAction getAction() {
return action; return action;
} }
private BaseAction action; private BaseAction action;
@JsonIgnore
private Map<String, String> additionalProperties = new HashMap<String, String>();
@JsonAnyGetter
public Map<String, String> getAdditionalProperties() {
return this.additionalProperties;
}
@JsonAnySetter public String toString(){
public void setAdditionalProperty(String name, String value) { String str="action="+action.toString();
this.additionalProperties.put(name, value); return str;
} }
// @JsonIgnore
// private Map<String, String> additionalProperties = new HashMap<String, String>();
// @JsonAnyGetter
// public Map<String, String> getAdditionalProperties() {
// return this.additionalProperties;
// }
//
// @JsonAnySetter
// public void setAdditionalProperty(String name, String value) {
// this.additionalProperties.put(name, value);
// }
......
...@@ -6,9 +6,7 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -6,9 +6,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import common.JsonHandler; import common.JsonHandler;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.action.SimpleHttpAction; import logic.adapter.HttpAdapter.action.SimpleHttpAction;
import logic.adapter.action.JsonNodeAction;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.function.Function; import java.util.function.Function;
...@@ -18,38 +16,30 @@ import java.util.function.Function; ...@@ -18,38 +16,30 @@ import java.util.function.Function;
public class MapStringToJsonOperation extends MapIntermediateOperation<JsonNode, JsonNode> { public class MapStringToJsonOperation extends MapIntermediateOperation<JsonNode, JsonNode> {
@JsonCreator @JsonCreator
public MapStringToJsonOperation(@JsonProperty("operationParams") MapOperationParams operationParams) { public MapStringToJsonOperation(@JsonProperty("operationParams") MapOperationParams operationParams){
super(operationParams); super(operationParams);
} }
@Override @Override
protected Function<JsonNode, JsonNode> buildFunc() { protected Function<JsonNode, JsonNode> buildFunc() {
Function<JsonNode,JsonNode> ret = (str) -> { Function<JsonNode,JsonNode> ret = (node) -> {
SimpleHttpResponse resp; SimpleHttpResponse resp;
String last; String content;
try { try {
//currently support only httpAction //currently support only httpAction
if (getOperationParams().getAction().getType().equals(SimpleHttpAction.TYPE)) { if (getOperationParams().getAction().getType().equals(SimpleHttpAction.TYPE)) {
SimpleHttpAction httpAction = (SimpleHttpAction)getOperationParams().getAction(); SimpleHttpAction httpAction = (SimpleHttpAction)getOperationParams().getAction();
Map<String,String> parameters = getOperationParams().getAdditionalProperties();
Map<String,String> convertedParameters = new HashMap<>();
for (Map.Entry<String,String> parameter:
parameters.entrySet()) {
if (parameter.getValue().equals("lastToken")) {
String str1 = str.asText();
last = str1.substring(str1.lastIndexOf('/') + 1);
convertedParameters.put(parameter.getKey(), last);
}
else
convertedParameters.put(parameter.getKey(), parameter.getValue());
}
httpAction.setRunTimeParameters(convertedParameters);
//assumed that the action holds its input already, and use it //assumed that the action holds its input already, and use it
httpAction.computeVariables(node);
resp = httpAction.apply(null); resp = httpAction.apply(null);
if (resp.getStatusCode()!=200) if (resp.getStatusCode()!=200)
throw new Exception("MapJsonToJsonOperation: http action failed with status code: "+resp.getStatusCode()+" errorMsg: "+ resp.getContent() ); throw new Exception("MapJsonToJsonOperation: http action failed with status code: "+resp.getStatusCode()+" errorMsg: "+ resp.getContent() );
content=resp.getContent();
System.out.println("MapStringToJsonOperation params="+ getOperationParams().toString()+" convert node= "+node.toString()+" to convertedNode= "+content.toString());
return JsonHandler.getJsonNodeFromString(resp.getContent()); return JsonHandler.getJsonNodeFromString(resp.getContent());
} }
...@@ -63,4 +53,6 @@ public class MapStringToJsonOperation extends MapIntermediateOperation<JsonNode, ...@@ -63,4 +53,6 @@ public class MapStringToJsonOperation extends MapIntermediateOperation<JsonNode,
} }
} }
...@@ -3,11 +3,21 @@ package logic.adapter.HttpAdapter.model; ...@@ -3,11 +3,21 @@ package logic.adapter.HttpAdapter.model;
/** /**
* Created by eli on 6/27/16. * Created by eli on 6/27/16.
*/ */
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
public class NameValueParam { public class NameValueParam {
private String name; private String name;
private String value; private String value;
@JsonCreator
public NameValueParam(@JsonProperty("name") String name,
@JsonProperty("value") String value) {
this.name = name;
this.value = value;
}
@JsonIgnore @JsonIgnore
public String toString(){ public String toString(){
return new String(name+"="+value); return new String(name+"="+value);
......
package logic.adapter.HttpAdapter.model; package logic.adapter.HttpAdapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import logic.adapter.action.BaseAction;
import logic.adapter.action.StringAction;
import java.util.HashMap;
/** /**
* Created by eli on 11/22/16. * Created by eli on 11/22/16.
*/ */
@JsonTypeInfo(use= JsonTypeInfo.Id.CLASS, include= JsonTypeInfo.As.PROPERTY, property="metaDataOperationClass") @JsonTypeInfo(use= JsonTypeInfo.Id.CLASS, include= JsonTypeInfo.As.PROPERTY, property="metaDataOperationClass")
public abstract class Operation<T extends BaseOperationParams> { public abstract class Operation<T extends BaseOperationParams> {
public Operation(T operationParams) {
public Operation(@JsonProperty("operationParams") T operationParams) {
this.operationParams = operationParams; this.operationParams = operationParams;
} }
...@@ -17,5 +24,4 @@ public abstract class Operation<T extends BaseOperationParams> { ...@@ -17,5 +24,4 @@ public abstract class Operation<T extends BaseOperationParams> {
private T operationParams; private T operationParams;
} }
...@@ -2,6 +2,7 @@ package logic.adapter.action; ...@@ -2,6 +2,7 @@ package logic.adapter.action;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.JsonNode;
import http.simpleHttpClient.SimpleHttpClient; import http.simpleHttpClient.SimpleHttpClient;
import logic.adapter.HttpAdapter.OAuth2Client; import logic.adapter.HttpAdapter.OAuth2Client;
import logic.adapter.HttpAdapter.model.ConfigHttpRequestParams; import logic.adapter.HttpAdapter.model.ConfigHttpRequestParams;
...@@ -9,7 +10,6 @@ import logic.adapter.model.BaseActionParams; ...@@ -9,7 +10,6 @@ import logic.adapter.model.BaseActionParams;
import logic.adapter.model.ModelValidator; import logic.adapter.model.ModelValidator;
import java.util.Map; import java.util.Map;
import java.util.function.Function;
/** /**
* Created by eli on 11/17/16. * Created by eli on 11/17/16.
...@@ -20,11 +20,11 @@ public abstract class BaseAction<T extends BaseActionParams, TypeIn, TypeOut> im ...@@ -20,11 +20,11 @@ public abstract class BaseAction<T extends BaseActionParams, TypeIn, TypeOut> im
@JsonProperty @JsonProperty
T params; T params;
public Map<String, String> getRunTimeParameters() { public Map<String, String> getRunTimeVariables() {
return runTimeParameters; return runTimeVariables;
} }
private Map<String, String> runTimeParameters; private Map<String, String> runTimeVariables;
public BaseAction(T params) { public BaseAction(T params) {
this.params = params; this.params = params;
...@@ -46,10 +46,10 @@ public abstract class BaseAction<T extends BaseActionParams, TypeIn, TypeOut> im ...@@ -46,10 +46,10 @@ public abstract class BaseAction<T extends BaseActionParams, TypeIn, TypeOut> im
} }
abstract public String getType(); abstract public String getType();
public abstract void build(); public abstract void build() throws Exception;
public void setRunTimeParameters(Map<String, String> convertedParameters) { public void setRunTimeVariables(Map<String, String> convertedParameters) {
this.runTimeParameters = convertedParameters; this.runTimeVariables = convertedParameters;
} }
...@@ -77,4 +77,7 @@ public abstract class BaseAction<T extends BaseActionParams, TypeIn, TypeOut> im ...@@ -77,4 +77,7 @@ public abstract class BaseAction<T extends BaseActionParams, TypeIn, TypeOut> im
this.httpClient = httpClient; this.httpClient = httpClient;
this.oauth2Client = oauth2Client; this.oauth2Client = oauth2Client;
} }
} }
...@@ -33,6 +33,9 @@ public class ExtractValueAction extends JsonNodeAction<ExtractValueActionParams> ...@@ -33,6 +33,9 @@ public class ExtractValueAction extends JsonNodeAction<ExtractValueActionParams>
public JsonNode apply(JsonNode jsonNode) throws Exception { public JsonNode apply(JsonNode jsonNode) throws Exception {
Enums.eNodeType eType = getParams().getValueType(); Enums.eNodeType eType = getParams().getValueType();
JsonNode transformedNode = jsonNode.at(pathPointer); JsonNode transformedNode = jsonNode.at(pathPointer);
if (transformedNode.isMissingNode() )
System.out.println("ExtractValueAction didn't match "+pathPointer.toString()+ "for node: "+ jsonNode.toString());
switch (eType){ switch (eType){
case ARRAY_NODE: case ARRAY_NODE:
if (!transformedNode.isArray()) if (!transformedNode.isArray())
......
...@@ -3,7 +3,6 @@ package logic.adapter.action; ...@@ -3,7 +3,6 @@ package logic.adapter.action;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import logic.adapter.HttpAdapter.model.*; import logic.adapter.HttpAdapter.model.*;
import logic.adapter.model.JsonConvertActionParams; import logic.adapter.model.JsonConvertActionParams;
import logic.adapter.model.TerminateOperation; import logic.adapter.model.TerminateOperation;
...@@ -12,10 +11,11 @@ import util.ArrayNodeCollector; ...@@ -12,10 +11,11 @@ import util.ArrayNodeCollector;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import java.util.stream.StreamSupport; import java.util.stream.StreamSupport;
import static util.Utils.myTypeOf;
/** /**
* Created by eli on 11/21/16. * Created by eli on 11/21/16.
...@@ -60,12 +60,7 @@ public class JsonConvertAction extends JsonNodeAction<JsonConvertActionParams> ...@@ -60,12 +60,7 @@ public class JsonConvertAction extends JsonNodeAction<JsonConvertActionParams>
List<IntermediateOperation> operations = params.getIntermediateOperations(); List<IntermediateOperation> operations = params.getIntermediateOperations();
for (IntermediateOperation operation : operations) { for (IntermediateOperation operation : operations) {
int end_index = operation.toString().indexOf('@'); String type=myTypeOf(operation);
String type=operation.toString().substring(0,end_index);
int startIndex = type.lastIndexOf(".");
startIndex++;
type = type.substring(startIndex,end_index);
if (type.equals("MapJsonToJsonOperation")){ if (type.equals("MapJsonToJsonOperation")){
Function<JsonNode,JsonNode> func = ((MapJsonToJsonOperation)operation).getFunc(); Function<JsonNode,JsonNode> func = ((MapJsonToJsonOperation)operation).getFunc();
streamOfJsonNodes=streamOfJsonNodes.map(func); streamOfJsonNodes=streamOfJsonNodes.map(func);
......
...@@ -2,27 +2,37 @@ package logic.adapter.action; ...@@ -2,27 +2,37 @@ package logic.adapter.action;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.flipkart.zjsonpatch.JsonPatch;
import logic.adapter.model.JsonPatchActionParams; import logic.adapter.model.JsonPatchActionParams;
import util.Utils; import util.Utils;
import util.zjsonpatch.ZJsonPatch;
import java.io.IOException; import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import static defs.Constants.CONFIG_LOCATION; import static defs.Constants.CONFIG_LOCATION;
import static defs.Constants.compiledRegEx;
/** /**
* Created by eli on 12/1/16. * Created by eli on 12/1/16.
*/ */
public class JsonPatchAction extends JsonNodeAction<JsonPatchActionParams>{ public class JsonPatchAction extends JsonNodeAction<JsonPatchActionParams>{
//***DEMO***/
private JsonNode jsonPatch;
private String strJsonPatch;
//this map holds for each key(i.e $id) its (start,end) indexes
//in order to be replaced in run time more effectively
private List<KeyPointer> variablesLocations = new ArrayList<>();
//***DEMO***/
@JsonCreator @JsonCreator
public JsonPatchAction(@JsonProperty("params") JsonPatchActionParams params) { public JsonPatchAction(@JsonProperty("params") JsonPatchActionParams params) {
super(params); super(params);
try {
this.build();
} catch (Exception e) {
e.printStackTrace();
}
} }
@Override @Override
...@@ -31,61 +41,90 @@ public class JsonPatchAction extends JsonNodeAction<JsonPatchActionParams>{ ...@@ -31,61 +41,90 @@ public class JsonPatchAction extends JsonNodeAction<JsonPatchActionParams>{
} }
@Override @Override
public void build() { public void build() throws Exception {
String jsonPatchfile = getParams().getFileJsonPatch();
try {
jsonPatch = Utils.readJsonNodeFromFile(CONFIG_LOCATION + jsonPatchfile);
strJsonPatch = jsonPatch.toString();
// String result=target;
Matcher matcher = compiledRegEx.matcher(strJsonPatch);
int start, end;
String key;
while (matcher.find()) {
start = matcher.start();
end = matcher.end();
//if matched not last portion of the string
key= strJsonPatch.substring(start+1,end);
KeyPointer strIndexes = new KeyPointer(key,start,end);
variablesLocations.add(strIndexes);
}
//by now strJsonPatch holds the String of JsonPatch, and variablesLocations holds the list of
//key->locations the can be run on run time at o(n) and replaced with the real time values
} }
catch(Exception e){
throw new Exception("failed to build JsonPathAction: error reading file: "+ ((jsonPatchfile!=null)?jsonPatchfile:"null")+" Exception: "+e);
}
}
@Override @Override
public JsonNode apply(JsonNode jsonNode) throws Exception { public JsonNode apply(JsonNode jsonNode) throws Exception {
JsonNode jsonInput;
JsonPatchActionParams params = getParams();
String JsonPatchFile = params.getFileJsonPatch();
JsonNode jsonPatch;
////if DEMO *******/
if (params.getFileJsonPatch().equals("parkingSpotJsonPatch.json") ){
JsonPointer demo = JsonPointer.compile("/_embedded/assets/0/_links/self/href");
JsonNode transformedNode = jsonNode.at(demo);
String str1 = transformedNode.asText();
String lastAssetIdToken = str1.substring(str1.lastIndexOf('/') + 1);
jsonPatch = Utils.readJsonNodeFromFile(CONFIG_LOCATION + JsonPatchFile);
////*******for DEMO start*******/
String json = jsonPatch.toString();
json = json.replaceFirst("\\$mdeKey", lastAssetIdToken);
jsonPatch = Utils.getJsonNodeFromString(json);
JsonNode currentJsonPatch;
if (variablesLocations.size()>0){
String strTransformedJsonPatch = replaceKeysWithValues(jsonNode);
currentJsonPatch = Utils.getJsonNodeFromString(strTransformedJsonPatch);
}
//jsonPatch is static without dynamic variables and we can use it as is without replacements
else{
currentJsonPatch=jsonPatch;
} }
else////not Demo
jsonPatch = Utils.readJsonNodeFromFile(CONFIG_LOCATION + JsonPatchFile);
if (params.getFileJsonInput() == null)
jsonInput=jsonNode;
else
jsonInput=Utils.readJsonNodeFromFile(CONFIG_LOCATION+JsonPatchFile);
if (jsonPatch!=null && !jsonPatch.isNull() && jsonInput!=null && !jsonInput.isNull()){ if (currentJsonPatch!=null && !currentJsonPatch.isNull() && jsonNode!=null && !jsonNode.isNull()){
return JsonPatch.apply(jsonPatch, jsonInput); return ZJsonPatch.apply(currentJsonPatch, jsonNode);
} }
else else
return null; return null;
} }
private String replaceKeysWithValues(JsonNode jsonNode) throws Exception {
StringBuilder strBuilder = new StringBuilder();
String strKey=null;
// Map<String, String> runTimeParameters = getRunTimeVariables();
Map<String, String> runTimeParameters = getParams().computeVariables(jsonNode);
String subString;
int currentLocation=0;
for (KeyPointer key: variablesLocations){
strKey=key.getKey();
if (runTimeParameters.containsKey(strKey))
{
subString = strJsonPatch.substring(currentLocation,key.getStart());
strBuilder.append(subString);
strBuilder.append(runTimeParameters.get(strKey));
currentLocation=key.getEnd();
}
else
System.out.println("replacekeysWithValues run time error, missing key: "+ ((strKey!=null)? strKey: "null"));
}
//insert the last substring from last replacement to the end
if (currentLocation>0){
subString = strJsonPatch.substring(currentLocation);
strBuilder.append(subString);
}
return strBuilder.toString();
}
private JsonNode jsonPatchApply(String jsonPatchfile, String jsonInputfile ) throws IOException { private JsonNode jsonPatchApply(String jsonPatchfile, String jsonInputfile ) throws IOException {
JsonNode jsonPatch = Utils.readJsonNodeFromFile(jsonPatchfile); JsonNode jsonPatch = Utils.readJsonNodeFromFile(jsonPatchfile);
JsonNode jsonInput = Utils.readJsonNodeFromFile(jsonInputfile); JsonNode jsonInput = Utils.readJsonNodeFromFile(jsonInputfile);
if (jsonPatch!=null && !jsonPatch.isNull() && jsonInput!=null && !jsonInput.isNull()){ if (jsonPatch!=null && !jsonPatch.isNull() && jsonInput!=null && !jsonInput.isNull()){
return JsonPatch.apply(jsonPatch, jsonInput); return ZJsonPatch.apply(jsonPatch, jsonInput);
} }
return null; return null;
} }
......
package logic.adapter.action;
/**
* Created by eli on 12/12/16.
*/
public class KeyPointer {
public int getStart() {
return start;
}
public int getEnd() {
return end;
}
private int start;
private int end;
public String getKey() {
return key;
}
private String key;
public KeyPointer(String key, int start, int end) {
this.start = start;
this.end = end;
this.key=key;
}
}
package logic.adapter.action;
import com.fasterxml.jackson.databind.JsonNode;
import logic.adapter.model.BaseActionParams;
/**
* Created by eli on 12/8/16.
*/
public abstract class StringAction<T extends BaseActionParams> extends BaseAction<T, JsonNode, String> {
public StringAction(T params) {
super(params);
}
}
package logic.adapter.action;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.JsonNode;
import defs.Enums;
import logic.adapter.model.SubStringActionParams;
import logic.adapter.model.WithinStringPointer;
/**
* Created by eli on 12/8/16.
*/
public class SubStringAction extends StringAction<SubStringActionParams> {
@JsonCreator
public SubStringAction(@JsonProperty("params") SubStringActionParams params) {
super(params);
}
@Override
public String getType() {
return null;
}
@Override
public void build() {
}
@Override
public String apply(JsonNode jsonNode) throws Exception {
String retStr;
SubStringActionParams params = getParams();
WithinStringPointer from = params.getFrom();
WithinStringPointer to = params.getTo();
if (jsonNode!=null && jsonNode.isMissingNode())
throw new Exception("SubStringAction expect none missing node input. [from: "
+((from!=null)?from.toString():"null")+"], [to="+((to!=null)?to.toString():"null")+"]");
if (!jsonNode.isTextual())
throw new Exception("SubStringAction expect textual JsonNode");
retStr=subStringOf(jsonNode.asText(), from, to);
if (retStr==null)
throw new Exception("SubStringAction failed, check your configuration");
return retStr;
}
private String subStringOf(String str, WithinStringPointer from, WithinStringPointer to) {
int fromIndex, toIndex;
String retString=null;
if (from != null) {
fromIndex = indexOf(str, from);
if (fromIndex != -1) {
retString = str.substring(fromIndex);
//if to==null return substring from "fromIndex" till end of the string
if (to != null)
{
toIndex = indexOf(str, to);
if (toIndex != -1)
retString = retString.substring(fromIndex, toIndex);
}
}
}
else
retString=str;
return retString;
}
//find the index of "pointer" in the string. in case that pointer include prefix to look for
//the returned index points to the index right after the given prefix
private int indexOf(String string,WithinStringPointer pointer) {
int index=-1;
if (pointer == null) return -1;
String token = pointer.getPrefix();
Enums.eSubStringLocation type = pointer.geteLocationType();
switch(type){
case FIRST:
index = string.indexOf(token);
break;
case LAST:
index = string.lastIndexOf(token);
break;
case XXX_th:
int count = pointer.getIndex();
index=0;
while (count>0){
index=string.indexOf(token,index);
if (index==-1)
break;
else
count--;
}
if (index==0) index--;
break;
case INDEX:
index=pointer.getIndex();
break;
}
if (type!= Enums.eSubStringLocation.INDEX&& index!=-1)
index+=token.length();
return index;
}
}
package logic.adapter.model; package logic.adapter.model;
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonIgnore;
//import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.annotation.*;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.adapter.HttpAdapter.RequestParams; import logic.adapter.HttpAdapter.RequestParams;
import logic.adapter.HttpAdapter.action.OnHttpResponse; import logic.adapter.HttpAdapter.action.OnHttpResponse;
import logic.adapter.HttpAdapter.action.SimpleHttpAction; import logic.adapter.HttpAdapter.action.SimpleHttpAction;
import logic.adapter.HttpAdapter.model.HttpFlow;
import logic.adapter.HttpAdapter.model.HttpRequestActionParams;
import logic.adapter.HttpAdapter.model.OnResponse;
import logic.adapter.action.BaseAction;
import java.util.ArrayList;
/** /**
* Created by eli on 11/16/16. * Created by eli on 11/16/16.
*/ */
//@JsonTypeInfo(
// use = JsonTypeInfo.Id.CLASS,
// include = JsonTypeInfo.As.PROPERTY,
// property = "metaDataClassFlow")
//@JsonSubTypes({
// @JsonSubTypes.Type(value = HttpFlow.class)
//})
//HttpRequestActionParams, RequestParams,SimpleHttpResponse //HttpRequestActionParams, RequestParams,SimpleHttpResponse
public abstract class BaseFlow implements ModelValidator{ public abstract class BaseFlow implements ModelValidator{
@JsonProperty("action") @JsonProperty("action")
...@@ -93,6 +48,7 @@ public abstract class BaseFlow implements ModelValidator{ ...@@ -93,6 +48,7 @@ public abstract class BaseFlow implements ModelValidator{
return null; return null;
} }
public SimpleHttpResponse execute(RequestParams input) throws Exception { public SimpleHttpResponse execute(RequestParams input) throws Exception {
// action.getRunTimeVariables();
SimpleHttpResponse actionResp = action.apply(input); SimpleHttpResponse actionResp = action.apply(input);
try { try {
return onResponse.execute(actionResp); return onResponse.execute(actionResp);
......
package logic.adapter.model;
import com.fasterxml.jackson.databind.JsonNode;
import logic.adapter.HttpAdapter.model.ComputeVariable;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Created by eli on 12/15/16.
*/
public abstract class DynamicVariablesParams extends BaseActionParams{
private Map<String, ComputeVariable> mapVariableToValueComputation;
public DynamicVariablesParams(Map<String, ComputeVariable> mapVariableToValueComputation) {
this.mapVariableToValueComputation = mapVariableToValueComputation;
}
public Map<String, ComputeVariable> getMapVariableToValueComputation() {
return mapVariableToValueComputation;
}
public Map<String, String> computeVariables(JsonNode node) throws Exception {
HashMap<String, String> map = new HashMap<>();
for (Map.Entry<String,ComputeVariable> entry : mapVariableToValueComputation.entrySet()){
String str=entry.getValue().execute(node);
if (str!=null)
map.put(entry.getKey(),str);
}
return map;
}
}
package logic.adapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by eli on 12/18/16.
*/
public class ExtractSubStringParams extends BaseActionParams{
private ExtractValueActionParams extractParams;
private SubStringActionParams subStringParams;
@JsonCreator
public ExtractSubStringParams(@JsonProperty("extract") ExtractValueActionParams extractParams,
@JsonProperty("subString") SubStringActionParams subStringParams) {
this.extractParams = extractParams;
this.subStringParams = subStringParams;
}
@Override
public String getId() {
return null;
}
@Override
public boolean isValid() {
return false;
}
}
...@@ -31,8 +31,8 @@ public class JsonConvertActionParams extends BaseActionParams { ...@@ -31,8 +31,8 @@ public class JsonConvertActionParams extends BaseActionParams {
@JsonCreator @JsonCreator
public JsonConvertActionParams(@JsonProperty("intermediateOperations") List<IntermediateOperation> intermediateOperations, public JsonConvertActionParams(@JsonProperty("intermediateOperations") List<IntermediateOperation> intermediateOperations,
@JsonProperty("terminateOperation") TerminateOperation terminateOperation) { @JsonProperty("terminateOperation") TerminateOperation terminateOperation) {
this.terminateOperation = terminateOperation;
this.intermediateOperations = intermediateOperations; this.intermediateOperations = intermediateOperations;
this.terminateOperation = terminateOperation;
} }
@Override @Override
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
//import com.fasterxml.jackson.annotation.JsonProperty; //import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.core.JsonPointer; //import com.fasterxml.jackson.core.JsonPointer;
//import com.fasterxml.jackson.databind.JsonNode; //import com.fasterxml.jackson.databind.JsonNode;
//import com.google.api.client.json.Json; //import com.google.api.client.zjsonpatch.Json;
// //
///** ///**
// * Created by eli on 11/15/16. // * Created by eli on 11/15/16.
......
...@@ -2,11 +2,14 @@ package logic.adapter.model; ...@@ -2,11 +2,14 @@ package logic.adapter.model;
import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import logic.adapter.HttpAdapter.model.ComputeVariable;
import java.util.Map;
/** /**
* Created by eli on 12/1/16. * Created by eli on 12/1/16.
*/ */
public class JsonPatchActionParams extends BaseActionParams{ public class JsonPatchActionParams extends DynamicVariablesParams{
@JsonProperty("fileInput") @JsonProperty("fileInput")
private String fileJsonInput; private String fileJsonInput;
...@@ -14,7 +17,8 @@ public class JsonPatchActionParams extends BaseActionParams{ ...@@ -14,7 +17,8 @@ public class JsonPatchActionParams extends BaseActionParams{
private String fileJsonPatch; private String fileJsonPatch;
@JsonCreator @JsonCreator
public JsonPatchActionParams(@JsonProperty("fileInput") String fileJsonInput, @JsonProperty("filePatch") String fileJsonPatch) { public JsonPatchActionParams(@JsonProperty("variables") Map<String, ComputeVariable> variableMap, @JsonProperty("fileInput") String fileJsonInput, @JsonProperty("filePatch") String fileJsonPatch) {
super(variableMap);
this.fileJsonInput = fileJsonInput; this.fileJsonInput = fileJsonInput;
this.fileJsonPatch = fileJsonPatch; this.fileJsonPatch = fileJsonPatch;
} }
......
package logic.adapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* Created by eli on 12/8/16.
*/
public class SubStringActionParams extends BaseActionParams{
@JsonProperty("from")
private WithinStringPointer from;
@JsonProperty("to")
private WithinStringPointer to;
@JsonCreator
public SubStringActionParams(@JsonProperty("from") WithinStringPointer from,
@JsonProperty("to") WithinStringPointer to) {
this.from = from;
this.to = to;
}
public WithinStringPointer getFrom() { return this.from;}
public WithinStringPointer getTo() { return this.to;}
@Override
public String getId() {
return null;
}
@Override
public boolean isValid() {
return ((from!=null && from.isValid()) && ((to== null) || to.isValid()));
}
}
package logic.adapter.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import defs.Enums;
/**
* Created by eli on 12/8/16.
*/
public class WithinStringPointer implements ModelValidator{
private static final int MAX_INDEX_VALUE = 200;
@JsonProperty("str")
private String prefix;
@JsonProperty("location")
private Enums.eSubStringLocation eLocationType;
@JsonProperty("index")
private String strIndex;
private int index;
@JsonCreator
public WithinStringPointer(@JsonProperty("str") String prefix,
@JsonProperty("location") Enums.eSubStringLocation eLocationType,
@JsonProperty("index") String strIndex) {
this.prefix = prefix;
this.eLocationType = eLocationType;
this.strIndex = strIndex;
}
@JsonGetter("str")
public String getPrefix() {
return prefix;
}
@JsonGetter("location")
public String geteLocation() {
return eLocationType.getName();
}
@JsonGetter("index")
public String getStrIndex() {
return strIndex;
}
@JsonIgnore
public int getIndex(){
return index;
}
@JsonIgnore
public Enums.eSubStringLocation geteLocationType() {
return eLocationType;
}
@Override
public boolean isValid() {
//for index "state" prefix must be null
boolean ret = true;
switch (eLocationType){
case FIRST:
case LAST:
if (strIndex!=null)
ret=false;
break;
case INDEX:
//XXX-th is the state that the index indicate which appearance of the prefix to look for.
// (i.e: 1-th, 2-th, 3-th etc.)
case XXX_th:
try {
this.index = Integer.valueOf(strIndex);
ret = ( index>0 && index < MAX_INDEX_VALUE);
}
catch (NumberFormatException e){
ret = false;
}
break;
}
return ret;
}
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("prefix=").append((prefix!=null)?prefix:"null");
sb.append(", locationType=").append(eLocationType.getName());
sb.append(", index=").append((strIndex!=null)?strIndex:"null");
return sb.toString();
}
}
package logic.adapter.normalizer; package logic.adapter.normalizer;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.flipkart.zjsonpatch.JsonPatch; //import com.flipkart.zjsonpatch.ZJsonPatch;
//import com.google.api.client.json.Json; //import com.google.api.client.zjsonpatch.Json;
import defs.Constants; import defs.Constants;
import org.apache.commons.lang.text.StrTokenizer;
import util.Utils; import util.Utils;
import common.JsonHandler; import common.JsonHandler;
import util.zjsonpatch.ZJsonPatch;
import java.io.File;
import static util.Utils.readJsonNodeFromFile;
/** /**
* Created by eli on 7/13/16. * Created by eli on 7/13/16.
...@@ -26,7 +22,7 @@ public class JsonConverterNormalizer implements INormalizer { ...@@ -26,7 +22,7 @@ public class JsonConverterNormalizer implements INormalizer {
JsonNode fileJsonNode = format.get("jsonPatchfile"); JsonNode fileJsonNode = format.get("jsonPatchfile");
if (fileJsonNode != null && !fileJsonNode.isNull()) { if (fileJsonNode != null && !fileJsonNode.isNull()) {
JsonNode jsonPatch = Utils.readJsonNodeFromFile(JSON_PATCH_LOCATION + fileJsonNode.asText()); JsonNode jsonPatch = Utils.readJsonNodeFromFile(JSON_PATCH_LOCATION + fileJsonNode.asText());
JsonNode jsonTarget = JsonPatch.apply(jsonPatch, jsonNodeToNormalize); JsonNode jsonTarget = ZJsonPatch.apply(jsonPatch, jsonNodeToNormalize);
strToNormalize = JsonHandler.getObjectAsJsonString(jsonTarget); strToNormalize = JsonHandler.getObjectAsJsonString(jsonTarget);
}} }}
catch (Exception e){ catch (Exception e){
......
package logic.adapter.normalizer; //package logic.adapter.normalizer;
//
//import org.json.XML ////import org.zjsonpatch.XML
//
import com.fasterxml.jackson.databind.JsonNode; //import com.fasterxml.jackson.databind.JsonNode;
import org.json.JSONException; //import org.json.JSONException;
import org.json.JSONObject; //import org.json.JSONObject;
import org.json.XML; //import org.json.XML;
//
/** ///**
* Created by eli on 7/11/16. // * Created by eli on 7/11/16.
*/ // */
public class Xml2jsonNormalizer implements INormalizer { //public class Xml2jsonNormalizer implements INormalizer {
//
/** // /**
* convert xml data string to Json string // * convert xml data string to Json string
* @param data - xml string to convert // * @param data - xml string to convert
* @return // * @return
*/ // */
/** // /**
* convert xml data string to Json string // * convert xml data string to Json string
* @param strToNormalize - xml string to convert // * @param strToNormalize - xml string to convert
* @param format format may hold format data that needed for the normalizer for the activate // * @param format format may hold format data that needed for the normalizer for the activate
* currently, this normalizer doesn't need any data // * currently, this normalizer doesn't need any data
* @return normalized String, null on failure // * @return normalized String, null on failure
*/ // */
@Override // @Override
public String activate(String strToNormalize, JsonNode format) { // public String activate(String strToNormalize, JsonNode format) {
JSONObject jsonObject; // JSONObject jsonObject;
String retString=null; // String retString=null;
try { // try {
jsonObject=XML.toJSONObject(strToNormalize); // jsonObject=XML.toJSONObject(strToNormalize);
retString=jsonObject.toString(); // retString=jsonObject.toString();
} // }
catch(JSONException | NullPointerException e){ // catch(JSONException | NullPointerException e){
e.printStackTrace(); // e.printStackTrace();
} // }
//
return retString; // return retString;
} // }
//
} //}
...@@ -25,7 +25,7 @@ public class AdaptersRepository { ...@@ -25,7 +25,7 @@ public class AdaptersRepository {
this.logger = logger; this.logger = logger;
adapterList = new HashMap<>(); adapterList = new HashMap<>();
} }
public void load() {//have to throw exception public void load() throws Exception {//have to throw exception
ArrayNode adaptersArray; ArrayNode adaptersArray;
JsonNode jsonNode=null; JsonNode jsonNode=null;
try { try {
...@@ -41,7 +41,7 @@ public class AdaptersRepository { ...@@ -41,7 +41,7 @@ public class AdaptersRepository {
} }
} }
private void loadAdapters(ArrayNode adaptersArray) { private void loadAdapters(ArrayNode adaptersArray) throws Exception {
if ( adaptersArray!= null && !adaptersArray.isNull() && adaptersArray.isArray()) { if ( adaptersArray!= null && !adaptersArray.isNull() && adaptersArray.isArray()) {
for (int i = 0; i < adaptersArray.size(); i++) { for (int i = 0; i < adaptersArray.size(); i++) {
JsonNode jsonAdapter = adaptersArray.get(i); JsonNode jsonAdapter = adaptersArray.get(i);
...@@ -61,14 +61,15 @@ public class AdaptersRepository { ...@@ -61,14 +61,15 @@ public class AdaptersRepository {
logger.error(Thread.currentThread().getStackTrace()[1].getMethodName()+" Failed to load adapters"); logger.error(Thread.currentThread().getStackTrace()[1].getMethodName()+" Failed to load adapters");
} }
private void addHttpAdapter(String adapterId) { private void addHttpAdapter(String adapterId) throws Exception {
HttpAdapter httpAdapter; HttpAdapter httpAdapter;
try { try {
httpAdapter = new HttpAdapter(logger, adapterId); httpAdapter = new HttpAdapter(logger, adapterId);
adapterList.put(adapterId, httpAdapter); adapterList.put(adapterId, httpAdapter);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
logger.error("failed to load adapter: " + adapterId+ ", Exception:" + e.toString()); throw new Exception("failed to load adapter: " + adapterId+ ", Exception:" + e);
} }
} }
......
package logic.service.model; package logic.service.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import static defs.Constants.compiledRegEx;
import static defs.Constants.compiledRegExWord;
/** /**
* Created by eli on 7/18/16. * Created by eli on 7/18/16.
*/ */
public class Api { public class Api {
public String getMethod() { public String getMethod() {
return method; return method;
} }
public void setMethod(String method) { public void setMethod(String method) {
this.method = method; this.method = method;
} }
@JsonProperty("method") @JsonProperty("method")
private String method; private String method;
@JsonProperty("apiIn") @JsonProperty("apiIn")
private String apiIn; private ApiInRegEx apiIn;
@JsonProperty("actions") @JsonProperty("actions")
private List<Action> actions = new ArrayList<>(); private List<Action> actions = new ArrayList<>();
@JsonIgnore
public Map<String, Integer> getMapKeyToParamIndex() {
return apiIn.getMapKeyToParamIndex();
}
/** /**
* *
* @return * @return
* The apiIn * The apiIn
*/ */
@JsonProperty("apiIn") @JsonProperty("apiIn")
public String getApiIn() { public ApiInRegEx getApiIn() {
return apiIn; return apiIn;
} }
/**
*
* @param apiIn
* The apiIn
*/
@JsonProperty("apiIn") @JsonProperty("apiIn")
public void setApiIn(String apiIn) { public void setApiIn(ApiInRegEx apiIn) {
this.apiIn = apiIn; this.apiIn = apiIn;
} }
private boolean isUserKey(String param) {
Matcher matcher = compiledRegExWord.matcher(param);
return (matcher.find());
}
/** /**
* *
...@@ -57,7 +64,6 @@ public class Api { ...@@ -57,7 +64,6 @@ public class Api {
public List<Action> getActions() { public List<Action> getActions() {
return actions; return actions;
} }
/** /**
* *
* @param actions * @param actions
...@@ -67,6 +73,16 @@ public class Api { ...@@ -67,6 +73,16 @@ public class Api {
public void setActions(List<Action> actions) { public void setActions(List<Action> actions) {
this.actions = actions; this.actions = actions;
} }
public boolean isMatched(String[] apiId) {
boolean ret;
ret = apiIn.isMatch(apiId);
return ret;
}
public void setOffSet(int offSet) {
apiIn.setOffSet(offSet);
}
} }
package logic.service.model;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import defs.Enums;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.stream.Collectors;
import static defs.Constants.compiledRegExWord;
import static defs.Enums.ePreDefinedRegexTypes.REGEX_DIGITS;
import static defs.Enums.ePreDefinedRegexTypes.STRING_EQUALS;
/**
* Created by eli on 12/20/16.
*/
public class ApiInRegEx {
@JsonProperty("name")
private String name;
@JsonProperty("paramsTypes")
private List<Enums.ePreDefinedRegexTypes> listOfParamsTypes;
@JsonCreator
public ApiInRegEx(@JsonProperty("name") String name, @JsonProperty("paramsTypes") List<Enums.ePreDefinedRegexTypes> listOfParamsTypes) {
this.name = name;
this.listOfParamsTypes = listOfParamsTypes;
try {
this.build();
} catch (Exception e) {
e.printStackTrace();
}
}
@JsonIgnore
private ArrayList<ParamType> listOfBuildedParams;
@JsonIgnore
private Map<String, Integer> mapKeyToParamIndex=new HashMap<>();
@JsonIgnore
public Map<String, Integer> getMapKeyToParamIndex() {
return mapKeyToParamIndex;
}
@JsonIgnore
public boolean isMatch(String[] apiId){
if(apiId==null || apiId.length!=listOfBuildedParams.size())
return false;
else{
for (int i = 0; i< apiId.length; i++){
if (!listOfBuildedParams.get(i).isMatch(apiId[i]))
return false;
}
}
return true;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append("API:[name=").append((name!=null)?name:"null").append(", paramsType=");
sb.append((listOfParamsTypes!=null)?listOfParamsTypes.toString():"null").append("]");
return sb.toString();
}
private void build() throws Exception {
Enums.ePreDefinedRegexTypes currType=null;
int currIndex=0;
listOfBuildedParams = new ArrayList<>(5);
String[] params=name.split("/");
if (listOfParamsTypes!=null && listOfParamsTypes.size()>currIndex)
currType=listOfParamsTypes.get(currIndex++);
for (String param :
params) {
if ( !param.startsWith("$")){
ParamType paramType = new ParamType(param, STRING_EQUALS);
listOfBuildedParams.add(paramType);
}
else
{
if (isValidKeyPattern(param) && currType!=null){
ParamType paramType = new ParamType(param.substring(1), currType);
listOfBuildedParams.add(paramType);
if (listOfParamsTypes!=null && listOfParamsTypes.size()>currIndex)
currType=listOfParamsTypes.get(currIndex++);
}
else if(currType==null){
String error="ApiInRegEx "+this.toString()+" FAILED TO BUILD, reason: paramsTypes length mismatch";
System.out.println(error);
throw new Exception(error);
}
else{//not valid key pattern
String error="ApiInRegEx "+this.toString()+" FAILED TO BUILD, reason: key pattern is not valid";
System.out.println(error);
throw new Exception(error);
}
}
}
if (listOfBuildedParams.size()>0){
mapKeyToParamIndex=listOfBuildedParams.stream().
filter((param)-> param.getType()!=STRING_EQUALS).
collect(Collectors.toMap(param->param.getName(),param->listOfBuildedParams.indexOf(param)));
}
}
private boolean isValidKeyPattern(String param) {
Matcher matcher = compiledRegExWord.matcher(param);
return (matcher.find());
}
public void setOffSet(int offSet) {
for (Map.Entry<String, Integer> entry: mapKeyToParamIndex.entrySet()) {
mapKeyToParamIndex.replace(entry.getKey(), entry.getValue() + offSet);
}
}
private class ParamType {
private String name;
private Enums.ePreDefinedRegexTypes type;
public String getName() {
return name;
}
public Enums.ePreDefinedRegexTypes getType() {
return type;
}
public ParamType(String name, Enums.ePreDefinedRegexTypes type) {
this.name = name;
this.type = type;
}
public boolean isMatch(String param){
boolean ret=false;
switch (type){
case STRING_EQUALS:
ret = name.equals(param);
break;
case REGEX_NO_CHECK:
ret = true;
break;
case REGEX_DIGITS:
Matcher matcher = REGEX_DIGITS.getPattern().matcher(param);
ret = matcher.find();
break;
}
return ret;
}
}
}
...@@ -36,11 +36,18 @@ public class Service { ...@@ -36,11 +36,18 @@ public class Service {
this.apiList = apiList; this.apiList = apiList;
} }
public Api getApi(String apiId){ public Api matchApi(String[] apiId){
for (Api api : apiList) { for (Api api : apiList) {
if (api.getApiIn().startsWith(apiId)) if (api.isMatched(apiId))
return api; return api;
} }
return null; return null;
} }
public void setOffSet(int offSet) {
for (Api api :
apiList) {
api.setOffSet(offSet);
}
}
} }
...@@ -4,8 +4,6 @@ import com.fasterxml.jackson.databind.JsonNode; ...@@ -4,8 +4,6 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode; import com.fasterxml.jackson.databind.node.ArrayNode;
import common.JsonHandler; import common.JsonHandler;
import defs.Constants; import defs.Constants;
import logic.adapter.BaseAdapter;
import logic.adapter.HttpAdapter.HttpAdapter;
import logic.service.model.Api; import logic.service.model.Api;
import logic.service.model.Service; import logic.service.model.Service;
import microservice.io.iface.ILogger; import microservice.io.iface.ILogger;
...@@ -66,6 +64,9 @@ public class ServicesRepository { ...@@ -66,6 +64,9 @@ public class ServicesRepository {
e.printStackTrace(); e.printStackTrace();
} }
Service service = (Service)JsonHandler.getNodeAsObject(serviceNode,Service.class); Service service = (Service)JsonHandler.getNodeAsObject(serviceNode,Service.class);
String[] split = serviceId.split("\\.");
int offSet = split.length;
service.setOffSet(offSet);
if (serviceList.putIfAbsent(serviceId,service) != null) if (serviceList.putIfAbsent(serviceId,service) != null)
logger.debug("service " +serviceId + " was loaded successfully"); logger.debug("service " +serviceId + " was loaded successfully");
} }
...@@ -76,10 +77,10 @@ public class ServicesRepository { ...@@ -76,10 +77,10 @@ public class ServicesRepository {
public Api getApi(String serviceId, String apiId) { public Api getApi(String serviceId, String[] apiIdAsParams) {
Service service = serviceList.get(serviceId); Service service = serviceList.get(serviceId);
if (service!=null){ if (service!=null){
return service.getApi(apiId); return service.matchApi(apiIdAsParams);
} }
else else
return null; return null;
......
package logic.webSocket; package logic.webSocket;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonPointer; import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.flipkart.zjsonpatch.JsonPatch; //import com.flipkart.zjsonpatch.ZJsonPatch;
import com.google.api.client.json.Json;
import com.google.api.client.util.DateTime; import com.google.api.client.util.DateTime;
import com.neovisionaries.ws.client.*; import com.neovisionaries.ws.client.*;
import defs.Constants;
import http.simpleHttpClient.SimpleHttpClient; import http.simpleHttpClient.SimpleHttpClient;
import http.simpleHttpClient.SimpleHttpRequest; import http.simpleHttpClient.SimpleHttpRequest;
import http.simpleHttpClient.SimpleHttpResponse; import http.simpleHttpClient.SimpleHttpResponse;
import logic.MdeManager; import logic.MdeManager;
import logic.adapter.action.JsonPatchAction;
import logic.adapter.model.ExtractValueActionParams;
import microservice.io.iface.ILogger; import microservice.io.iface.ILogger;
import util.Utils; import util.Utils;
import util.zjsonpatch.ZJsonPatch;
import java.io.IOException; import java.io.IOException;
import java.io.InterruptedIOException; import java.io.InterruptedIOException;
...@@ -356,7 +351,7 @@ public class WebSocketEventListener implements WebSocketListener { ...@@ -356,7 +351,7 @@ public class WebSocketEventListener implements WebSocketListener {
jsonPatchStr = jsonPatchStr.replaceFirst("\\$uid", details.getAppKey()); jsonPatchStr = jsonPatchStr.replaceFirst("\\$uid", details.getAppKey());
try { try {
JsonNode newJsonPatch = Utils.getJsonNodeFromString(jsonPatchStr); JsonNode newJsonPatch = Utils.getJsonNodeFromString(jsonPatchStr);
jsonEvent = JsonPatch.apply(newJsonPatch, jsonEvent); jsonEvent = ZJsonPatch.apply(newJsonPatch, jsonEvent);
this.sendHttpPost(details.getCallBackUrl(), jsonEvent); this.sendHttpPost(details.getCallBackUrl(), jsonEvent);
} catch (IOException e) { } catch (IOException e) {
logging(connectionId+ " #1 sendEvent failed to send event error: "+e, eTraceLevel.eERROR, false); logging(connectionId+ " #1 sendEvent failed to send event error: "+e, eTraceLevel.eERROR, false);
......
...@@ -29,13 +29,10 @@ public class WebSocketManager { ...@@ -29,13 +29,10 @@ public class WebSocketManager {
this.defaultHeaders = defaultHeaders; this.defaultHeaders = defaultHeaders;
this.auth2Client = oAuth2Client; this.auth2Client = oAuth2Client;
} }
public boolean isConnected( String connectionId, String uid){ public boolean isConnected( String connectionId, String uid){
StringBuilder sb = new StringBuilder();
sb.append(connectionId).append(":").append(uid);
String key = sb.toString();
if (webSocketConnections.containsKey(connectionId)){ if (webSocketConnections.containsKey(connectionId)){
WebSocketConnection connection = webSocketConnections.get(connectionId); WebSocketConnection connection = webSocketConnections.get(connectionId);
if (connection!=null ){ if (connection!=null ){
......
...@@ -17,6 +17,8 @@ import java.util.Map; ...@@ -17,6 +17,8 @@ import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import static defs.Constants.*;
import static defs.Constants.compiledRegEx;
import static defs.Enums.eKeyWord; import static defs.Enums.eKeyWord;
...@@ -26,12 +28,12 @@ import static defs.Enums.eKeyWord; ...@@ -26,12 +28,12 @@ import static defs.Enums.eKeyWord;
public class HttpRequestResolver { public class HttpRequestResolver {
//this regexQueryParamValue means string starting with '$' followed with word (1-15 chars length) followed by period, ending with //this regexQueryParamValue means string starting with '$' followed with word (1-15 chars length) followed by period, ending with
//another word (1-15 chars) //another word (1-15 chars)
private final static String regexQueryParamValue = "^\\$[a-zA-Z]{1,15}\\.[a-zA-Z]{1,15}$"; // private final static String regexQueryParamValue = "^\\$[a-zA-Z]{1,15}\\.[a-zA-Z]{1,15}$";
private final static Pattern patternFullMatchValue = Pattern.compile(regexQueryParamValue); // private final static Pattern patternFullMatchValue = Pattern.compile(regexQueryParamValue);
private final static String regexPathParamValue = "^\\$[a-zA-Z]{1,15}\\.[a-zA-Z]{1,15}$"; // private final static String regexPathParamValue = "^\\$[a-zA-Z]{1,15}\\.[a-zA-Z]{1,15}$";
private final static Pattern patternPathParamValue = Pattern.compile(regexPathParamValue); // private final static Pattern patternPathParamValue = Pattern.compile(regexPathParamValue);
private final static String regexPathKeyWord= "^\\$[a-zA-Z0-9]{1,15}\\.[a-zA-Z]{1,15}$"; // private final static String regexPathKeyWord= "^\\$[a-zA-Z0-9]{1,15}\\.[a-zA-Z]{1,15}$";
private final static Pattern patternPathKeyWord = Pattern.compile(regexPathKeyWord); // private final static Pattern patternPathKeyWord = Pattern.compile(regexPathKeyWord);
// private final String tokenAccess; // private final String tokenAccess;
// //
// private RequestContext srcRequest; // private RequestContext srcRequest;
...@@ -108,24 +110,16 @@ public class HttpRequestResolver { ...@@ -108,24 +110,16 @@ public class HttpRequestResolver {
{ {
name = header.getName(); name = header.getName();
value = header.getValue(); value = header.getValue();
value = value.replaceFirst("\\$token",tokenAccess);
request.addHeader(name,value); request.addHeader(name,value);
} }
Map<String, String> variables; if (tokenAccess!=null) {
path = dstRequestParamsPattern.getPath(); request.addHeader("Authorization", "Bearer " + tokenAccess);
Enums.EnumCrudMethod enumCrudMethod = srcRequest.getEnumCrudMethod();
if (enumCrudMethod == Enums.EnumCrudMethod.E_CREATE){
if (dstRequestParamsPattern.getId().equals("subscribe")) {
variables = new HashMap<>();
String[] params = srcRequest.getParams();
if (params.length>3) {
variables.put("mdeKey", (srcRequest.getParams())[3]);
path = replaceMatchedKeysByItsValues(path, variables);
}
} }
} path = dstRequestParamsPattern.getPath();
else if (srcRequest.getVariablesValues()!=null && srcRequest.getVariablesValues().size()>0)
path = replaceMatchedKeysByItsValues(path, srcRequest.getVariablesValues());
if (runTimeVariables!=null && runTimeVariables.size()>0)
path = replaceMatchedKeysByItsValues(path, runTimeVariables); path = replaceMatchedKeysByItsValues(path, runTimeVariables);
request.setPath(path); request.setPath(path);
...@@ -144,8 +138,8 @@ public class HttpRequestResolver { ...@@ -144,8 +138,8 @@ public class HttpRequestResolver {
{ {
if (keyVals== null) return target; if (keyVals== null) return target;
final String regex = "\\$[a-zA-Z0-9]{1,15}"; // /*final String*/ regex = "\\$[a-zA-Z0-9]{1,15}";
final Pattern compiledRegEx = Pattern.compile(regex); // /*final Pattern*/ compiledRegEx = Pattern.compile(regex);
String result=target; String result=target;
Matcher matcher = compiledRegEx.matcher(target); Matcher matcher = compiledRegEx.matcher(target);
......
...@@ -12,6 +12,16 @@ public class Utils { ...@@ -12,6 +12,16 @@ public class Utils {
public static final ObjectMapper SORTED_MAPPER = new ObjectMapper(); public static final ObjectMapper SORTED_MAPPER = new ObjectMapper();
public static String myTypeOf(Object obj){
int end_index = obj.toString().indexOf('@');
String type=obj.toString().substring(0,end_index);
int startIndex = type.lastIndexOf(".");
startIndex++;
return type.substring(startIndex,end_index);
}
public static Object readObjectFromString1(String jsonStr, Class<?> ObjClass) throws IOException { public static Object readObjectFromString1(String jsonStr, Class<?> ObjClass) throws IOException {
Object obj = null; Object obj = null;
...@@ -47,6 +57,8 @@ public class Utils { ...@@ -47,6 +57,8 @@ public class Utils {
return objectReader.readValue(jsonNode); return objectReader.readValue(jsonNode);
} catch (Exception var4) { } catch (Exception var4) {
var4.printStackTrace(); var4.printStackTrace();
// com.fasterxml.jackson.databind.JsonMappingException: Could not find creator property with name 'operationParams' (in class logic.adapter.HttpAdapter.model.IntermediateOperation)
// at [Source: N/A; line: -1, column: -1] (through reference chain: logic.adapter.model.AdapterModel["flows"]->java.util.ArrayList[0]->java.util.ArrayList[1])
} }
} }
else else
......
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.node.ArrayNode;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.github.fge.jackson.jsonpointer.ReferenceToken;
//import com.github.fge.jackson.jsonpointer.TokenResolver;
//import com.google.common.collect.Iterables;
//
//
///**
// * JSON Patch {@code add} operation
// *
// * <p>For this operation, {@code path} is the JSON Pointer where the value
// * should be added, and {@code value} is the value to add.</p>
// *
// * <p>Note that if the target value pointed to by {@code path} already exists,
// * it is replaced. In this case, {@code add} is equivalent to {@code replace}.
// * </p>
// *
// * <p>Note also that a value will be created at the target path <b>if and only
// * if</b> the immediate parent of that value exists (and is of the correct
// * type).</p>
// *
// * <p>Finally, if the last reference token of the JSON Pointer is {@code -} and
// * the immediate parent is an array, the given value is added at the end of the
// * array. For instance, applying:</p>
// *
// * <pre>
// * { "op": "add", "path": "/-", "value": 3 }
// * </pre>
// *
// * <p>to:</p>
// *
// * <pre>
// * [ 1, 2 ]
// * </pre>
// *
// * <p>will give:</p>
// *
// * <pre>
// * [ 1, 2, 3 ]
// * </pre>
// */
//public final class AddOperation
// extends PathValueOperation
//{
// private static final ReferenceToken LAST_ARRAY_ELEMENT
// = ReferenceToken.fromRaw("-");
//
// @JsonCreator
// public AddOperation(@JsonProperty("path") final JsonPointer path,
// @JsonProperty("value") final JsonNode value)
// {
// super("add", path, value);
// }
//
// @Override
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// if (path.isEmpty())
// return value;
//
// /*
// * Check the parent node: it must exist and be a container (ie an array
// * or an object) for the add operation to work.
// */
// final JsonNode parentNode = path.parent().path(node);
// if (parentNode.isMissingNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchParent"));
// if (!parentNode.isContainerNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.parentNotContainer"));
// return parentNode.isArray()
// ? addToArray(path, node)
// : addToObject(path, node);
// }
//
// private JsonNode addToArray(final JsonPointer path, final JsonNode node)
// throws JsonPatchException
// {
// final JsonNode ret = node.deepCopy();
// final ArrayNode target = (ArrayNode) path.parent().get(ret);
// final TokenResolver<JsonNode> token = Iterables.getLast(path);
//
// if (token.getToken().equals(LAST_ARRAY_ELEMENT)) {
// target.add(value);
// return ret;
// }
//
// final int size = target.size();
// final int index;
// try {
// index = Integer.parseInt(token.toString());
// } catch (NumberFormatException ignored) {
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.notAnIndex"));
// }
//
// if (index < 0 || index > size)
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchIndex"));
//
// target.insert(index, value);
// return ret;
// }
//
// private JsonNode addToObject(final JsonPointer path, final JsonNode node)
// {
// final JsonNode ret = node.deepCopy();
// final ObjectNode target = (ObjectNode) path.parent().get(ret);
// target.put(Iterables.getLast(path).getToken().getRaw(), value);
// return ret;
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//
///**
// * JSON Patch {@code copy} operation
// *
// * <p>For this operation, {@code from} is the JSON Pointer of the value to copy,
// * and {@code path} is the destination where the value should be copied.</p>
// *
// * <p>As for {@code add}:</p>
// *
// * <ul>
// * <li>the value at the destination path is either created or replaced;</li>
// * <li>it is created only if the immediate parent exists;</li>
// * <li>{@code -} appends at the end of an array.</li>
// * </ul>
// *
// * <p>It is an error if {@code from} fails to resolve to a JSON value.</p>
// */
//public final class CopyOperation
// extends DualPathOperation
//{
// @JsonCreator
// public CopyOperation(@JsonProperty("from") final JsonPointer from,
// @JsonProperty("path") final JsonPointer path)
// {
// super("copy", from, path);
// }
//
// @Override
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// final JsonNode dupData = from.path(node).deepCopy();
// if (dupData.isMissingNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchPath"));
// return new AddOperation(path, dupData).apply(node);
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.core.JsonGenerator;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.SerializerProvider;
//import com.fasterxml.jackson.databind.annotation.JsonSerialize;
//import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
//import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//
//import java.io.IOException;
//
///**
// * Base class for JSON Patch operations taking two JSON Pointers as arguments
// */
//public abstract class DualPathOperation
// extends JsonPatchOperation
//{
// @JsonSerialize(using = ToStringSerializer.class)
// protected final JsonPointer from;
//
// /**
// * Protected constructor
// *
// * @param op operation name
// * @param from source path
// * @param path destination path
// */
// protected DualPathOperation(final String op, final JsonPointer from,
// final JsonPointer path)
// {
// super(op, path);
// this.from = from;
// }
//
// @Override
// public final void serialize(final JsonGenerator jgen,
// final SerializerProvider provider)
// throws IOException, JsonProcessingException
// {
// jgen.writeStartObject();
// jgen.writeStringField("op", op);
// jgen.writeStringField("path", path.toString());
// jgen.writeStringField("from", from.toString());
// jgen.writeEndObject();
// }
//
// @Override
// public final void serializeWithType(final JsonGenerator jgen,
// final SerializerProvider provider, final TypeSerializer typeSer)
// throws IOException, JsonProcessingException
// {
// serialize(jgen, provider);
// }
//
// @Override
// public final String toString()
// {
// return "op: " + op + "; from: \"" + from + "\"; path: \"" + path + '"';
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.core.JsonGenerator;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.JsonSerializable;
//import com.fasterxml.jackson.databind.SerializerProvider;
//import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
//import com.github.fge.jackson.JacksonUtils;
//import com.github.fge.msgsimple.bundle.MessageBundle;
//import com.github.fge.msgsimple.load.MessageBundles;
//import com.google.common.collect.ImmutableList;
//
//import java.io.IOException;
//import java.util.List;
//
///**
// * Implementation of JSON Patch
// *
// * <p><a href="http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-10">JSON
// * Patch</a>, as its name implies, is an IETF draft describing a mechanism to
// * apply a patch to any JSON value. This implementation covers all operations
// * according to the specification; however, there are some subtle differences
// * with regards to some operations which are covered in these operations'
// * respective documentation.</p>
// *
// * <p>An example of a JSON Patch is as follows:</p>
// *
// * <pre>
// * [
// * {
// * "op": "add",
// * "path": "/-",
// * "value": {
// * "productId": 19,
// * "name": "Duvel",
// * "type": "beer"
// * }
// * }
// * ]
// * </pre>
// *
// * <p>This patch contains a single operation which adds an item at the end of
// * an array. A JSON Patch can contain more than one operation; in this case, all
// * operations are applied to the input JSON value in their order of appearance,
// * until all operations are applied or an error condition is encountered.</p>
// *
// * <p>The main point where this implementation differs from the specification
// * is initial JSON parsing. The draft says:</p>
// *
// * <pre>
// * Operation objects MUST have exactly one "op" member
// * </pre>
// *
// * <p>and:</p>
// *
// * <pre>
// * Additionally, operation objects MUST have exactly one "path" member.
// * </pre>
// *
// * <p>However, obeying these to the letter forces constraints on the JSON
// * <b>parser</b>. Here, these constraints are not enforced, which means:</p>
// *
// * <pre>
// * [ { "op": "add", "op": "remove", "path": "/x" } ]
// * </pre>
// *
// * <p>is parsed (as a {@code remove} operation, since it appears last).</p>
// *
// * <p><b>IMPORTANT NOTE:</b> the JSON Patch is supposed to be VALID when the
// * constructor for this class ({@link JsonPatch#fromJson(JsonNode)} is used.</p>
// */
//public final class JsonPatch
// implements JsonSerializable
//{
// private static final MessageBundle BUNDLE
// = MessageBundles.getBundle(JsonPatchMessages.class);
//
// /**
// * List of operations
// */
// private final List<JsonPatchOperation> operations;
//
// /**
// * Constructor
// *
// * <p>Normally, you should never have to use it.</p>
// *
// * @param operations the list of operations for this patch
// * @see JsonPatchOperation
// */
// @JsonCreator
// public JsonPatch(final List<JsonPatchOperation> operations)
// {
// this.operations = ImmutableList.copyOf(operations);
// }
//
// /**
// * Static factory method to build a JSON Patch out of a JSON representation
// *
// * @param node the JSON representation of the generated JSON Patch
// * @return a JSON Patch
// * @throws IOException input is not a valid JSON patch
// * @throws NullPointerException input is null
// */
// public static JsonPatch fromJson(final JsonNode node)
// throws IOException
// {
// BUNDLE.checkNotNull(node, "jsonPatch.nullInput");
// return JacksonUtils.getReader().withType(JsonPatch.class)
// .readValue(node);
// }
//
// /**
// * Apply this patch to a JSON value
// *
// * @param node the value to apply the patch to
// * @return the patched JSON value
// * @throws JsonPatchException failed to apply patch
// * @throws NullPointerException input is null
// */
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// BUNDLE.checkNotNull(node, "jsonPatch.nullInput");
// JsonNode ret = node;
// for (final JsonPatchOperation operation: operations)
// ret = operation.apply(ret);
//
// return ret;
// }
//
// @Override
// public String toString()
// {
// return operations.toString();
// }
//
// @Override
// public void serialize(final JsonGenerator jgen,
// final SerializerProvider provider)
// throws IOException
// {
// jgen.writeStartArray();
// for (final JsonPatchOperation op: operations)
// op.serialize(jgen, provider);
// jgen.writeEndArray();
// }
//
// @Override
// public void serializeWithType(final JsonGenerator jgen,
// final SerializerProvider provider, final TypeSerializer typeSer)
// throws IOException
// {
// serialize(jgen, provider);
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//public final class JsonPatchException
// extends Exception
//{
// public JsonPatchException(final String message)
// {
// super(message);
// }
//
// public JsonPatchException(final String message, final Throwable cause)
// {
// super(message, cause);
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.github.fge.msgsimple.bundle.MessageBundle;
//import com.github.fge.msgsimple.bundle.PropertiesBundle;
//import com.github.fge.msgsimple.load.MessageBundleLoader;
//
//public final class JsonPatchMessages
// implements MessageBundleLoader
//{
// @Override
// public MessageBundle getBundle()
// {
// return PropertiesBundle.forPath("/com/github/fge/jsonpatch/messages");
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
//import com.fasterxml.jackson.annotation.JsonSubTypes;
//import com.fasterxml.jackson.annotation.JsonTypeInfo;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.JsonSerializable;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.github.fge.msgsimple.bundle.MessageBundle;
//import com.github.fge.msgsimple.load.MessageBundles;
//
//import static com.fasterxml.jackson.annotation.JsonSubTypes.Type;
//import static com.fasterxml.jackson.annotation.JsonTypeInfo.As;
//import static com.fasterxml.jackson.annotation.JsonTypeInfo.Id;
//
//@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "op")
//
//@JsonSubTypes({
// @Type(name = "add", value = AddOperation.class),
// @Type(name = "copy", value = CopyOperation.class),
// @Type(name = "move", value = MoveOperation.class),
// @Type(name = "remove", value = RemoveOperation.class),
// @Type(name = "replace", value = ReplaceOperation.class),
// @Type(name = "test", value = TestOperation.class)
//})
//
///**
// * Base abstract class for one patch operation
// *
// * <p>Two more abstract classes extend this one according to the arguments of
// * the operation:</p>
// *
// * <ul>
// * <li>{@link DualPathOperation} for operations taking a second pointer as
// * an argument ({@code copy} and {@code move});</li>
// * <li>{@link PathValueOperation} for operations taking a value as an
// * argument ({@code add}, {@code replace} and {@code test}).</li>
// * </ul>
// */
//@JsonIgnoreProperties(ignoreUnknown = true)
//public abstract class JsonPatchOperation
// implements JsonSerializable
//{
// protected static final MessageBundle BUNDLE
// = MessageBundles.getBundle(JsonPatchMessages.class);
//
// protected final String op;
//
// /*
// * Note: no need for a custom deserializer, Jackson will try and find a
// * constructor with a single string argument and use it.
// *
// * However, we need to serialize using .toString().
// */
// protected final JsonPointer path;
//
// /**
// * Constructor
// *
// * @param op the operation name
// * @param path the JSON Pointer for this operation
// */
// protected JsonPatchOperation(final String op, final JsonPointer path)
// {
// this.op = op;
// this.path = path;
// }
//
// /**
// * Apply this operation to a JSON value
// *
// * @param node the value to patch
// * @return the patched value
// * @throws JsonPatchException operation failed to apply to this value
// */
// public abstract JsonNode apply(final JsonNode node)
// throws JsonPatchException;
//
// @Override
// public abstract String toString();
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//
///**
// * JSON Patch {@code move} operation
// *
// * <p>For this operation, {@code from} points to the value to move, and {@code
// * path} points to the new location of the moved value.</p>
// *
// * <p>As for {@code add}:</p>
// *
// * <ul>
// * <li>the value at the destination path is either created or replaced;</li>
// * <li>it is created only if the immediate parent exists;</li>
// * <li>{@code -} appends at the end of an array.</li>
// * </ul>
// *
// * <p>It is an error condition if {@code from} does not point to a JSON value.
// * </p>
// *
// * <p>The specification adds another rule that the {@code from} path must not be
// * an immediate parent of {@code path}. Unfortunately, that doesn't really work.
// * Consider this patch:</p>
// *
// * <pre>
// * { "op": "move", "from": "/0", "path": "/0/x" }
// * </pre>
// *
// * <p>Even though {@code /0} is an immediate parent of {@code /0/x}, when this
// * patch is applied to:</p>
// *
// * <pre>
// * [ "victim", {} ]
// * </pre>
// *
// * <p>it actually succeeds and results in the patched value:</p>
// *
// * <pre>
// * [ { "x": "victim" } ]
// * </pre>
// */
//public final class MoveOperation
// extends DualPathOperation
//{
// @JsonCreator
// public MoveOperation(@JsonProperty("from") final JsonPointer from,
// @JsonProperty("path") final JsonPointer path)
// {
// super("move", from, path);
// }
//
// @Override
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// if (from.equals(path))
// return node.deepCopy();
// final JsonNode movedNode = from.path(node);
// if (movedNode.isMissingNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchPath"));
// final JsonPatchOperation remove = new RemoveOperation(from);
// final JsonPatchOperation add = new AddOperation(path, movedNode);
// return add.apply(remove.apply(node));
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.core.JsonGenerator;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.SerializerProvider;
//import com.fasterxml.jackson.databind.annotation.JsonSerialize;
//import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//
//import java.io.IOException;
//
///**
// * Base class for patch operations taking a value in addition to a path
// */
//public abstract class PathValueOperation
// extends JsonPatchOperation
//{
// @JsonSerialize
// protected final JsonNode value;
//
// /**
// * Protected constructor
// *
// * @param op operation name
// * @param path affected path
// * @param value JSON value
// */
// protected PathValueOperation(final String op, final JsonPointer path,
// final JsonNode value)
// {
// super(op, path);
// this.value = value.deepCopy();
// }
//
// @Override
// public final void serialize(final JsonGenerator jgen,
// final SerializerProvider provider)
// throws IOException, JsonProcessingException
// {
// jgen.writeStartObject();
// jgen.writeStringField("op", op);
// jgen.writeStringField("path", path.toString());
// jgen.writeFieldName("value");
// jgen.writeTree(value);
// jgen.writeEndObject();
// }
//
// @Override
// public final void serializeWithType(final JsonGenerator jgen,
// final SerializerProvider provider, final TypeSerializer typeSer)
// throws IOException, JsonProcessingException
// {
// serialize(jgen, provider);
// }
//
// @Override
// public final String toString()
// {
// return "op: " + op + "; path: \"" + path + "\"; value: " + value;
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.core.JsonGenerator;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.SerializerProvider;
//import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
//import com.fasterxml.jackson.databind.node.ArrayNode;
//import com.fasterxml.jackson.databind.node.MissingNode;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.google.common.collect.Iterables;
//
//import java.io.IOException;
//
///**
// * JSON Path {@code remove} operation
// *
// * <p>This operation only takes one pointer ({@code path}) as an argument. It
// * is an error condition if no JSON value exists at that pointer.</p>
// */
//public final class RemoveOperation
// extends JsonPatchOperation
//{
// @JsonCreator
// public RemoveOperation(@JsonProperty("path") final JsonPointer path)
// {
// super("remove", path);
// }
//
// @Override
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// if (path.isEmpty())
// return MissingNode.getInstance();
// if (path.path(node).isMissingNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchPath"));
// final JsonNode ret = node.deepCopy();
// final JsonNode parentNode = path.parent().get(ret);
// final String raw = Iterables.getLast(path).getToken().getRaw();
// if (parentNode.isObject())
// ((ObjectNode) parentNode).remove(raw);
// else
// ((ArrayNode) parentNode).remove(Integer.parseInt(raw));
// return ret;
// }
//
// @Override
// public void serialize(final JsonGenerator jgen,
// final SerializerProvider provider)
// throws IOException, JsonProcessingException
// {
// jgen.writeStartObject();
// jgen.writeStringField("op", "remove");
// jgen.writeStringField("path", path.toString());
// jgen.writeEndObject();
// }
//
// @Override
// public void serializeWithType(final JsonGenerator jgen,
// final SerializerProvider provider, final TypeSerializer typeSer)
// throws IOException, JsonProcessingException
// {
// serialize(jgen, provider);
// }
//
// @Override
// public String toString()
// {
// return "op: " + op + "; path: \"" + path + '"';
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.node.ArrayNode;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.google.common.collect.Iterables;
//
///**
// * JSON Patch {@code replace} operation
// *
// * <p>For this operation, {@code path} points to the value to replace, and
// * {@code value} is the replacement value.</p>
// *
// * <p>It is an error condition if {@code path} does not point to an actual JSON
// * value.</p>
// */
//public final class ReplaceOperation
// extends PathValueOperation
//{
// @JsonCreator
// public ReplaceOperation(@JsonProperty("path") final JsonPointer path,
// @JsonProperty("value") final JsonNode value)
// {
// super("replace", path, value);
// }
//
// @Override
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// /*
// * FIXME cannot quite be replaced by a remove + add because of arrays.
// * For instance:
// *
// * { "op": "replace", "path": "/0", "value": 1 }
// *
// * with
// *
// * [ "x" ]
// *
// * If remove is done first, the array is empty and add rightly complains
// * that there is no such index in the array.
// */
// if (path.path(node).isMissingNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchPath"));
// final JsonNode replacement = value.deepCopy();
// if (path.isEmpty())
// return replacement;
// final JsonNode ret = node.deepCopy();
// final JsonNode parent = path.parent().get(ret);
// final String rawToken = Iterables.getLast(path).getToken().getRaw();
// if (parent.isObject())
// ((ObjectNode) parent).put(rawToken, replacement);
// else
// ((ArrayNode) parent).set(Integer.parseInt(rawToken), replacement);
// return ret;
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch;
//
//import com.fasterxml.jackson.annotation.JsonCreator;
//import com.fasterxml.jackson.annotation.JsonProperty;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.github.fge.jackson.JsonNumEquals;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.google.common.base.Equivalence;
//
///**
// * JSON Patch {@code test} operation
// *
// * <p>The two arguments for this operation are the pointer containing the value
// * to test ({@code path}) and the value to test equality against ({@code
// * value}).</p>
// *
// * <p>It is an error if no value exists at the given path.</p>
// *
// * <p>Also note that equality as defined by JSON Patch is exactly the same as it
// * is defined by JSON Schema itself. As such, this operation reuses {@link
// * JsonNumEquals} for testing equality.</p>
// */
//public final class TestOperation
// extends PathValueOperation
//{
// private static final Equivalence<JsonNode> EQUIVALENCE
// = JsonNumEquals.getInstance();
//
// @JsonCreator
// public TestOperation(@JsonProperty("path") final JsonPointer path,
// @JsonProperty("value") final JsonNode value)
// {
// super("test", path, value);
// }
//
// @Override
// public JsonNode apply(final JsonNode node)
// throws JsonPatchException
// {
// final JsonNode tested = path.path(node);
// if (tested.isMissingNode())
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.noSuchPath"));
// if (!EQUIVALENCE.equivalent(tested, value))
// throw new JsonPatchException(BUNDLE.getMessage(
// "jsonPatch.valueTestFailure"));
// return node.deepCopy();
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch.diff;
//
//import com.fasterxml.jackson.databind.JsonNode;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.github.fge.jsonpatch.*;
//
//final class DiffOperation
//{
// private final Type type;
// /* An op's "from", if any */
// private final JsonPointer from;
// /* Value displaced by this operation, if any */
// private final JsonNode oldValue;
// /* An op's "path", if any */
// private final JsonPointer path;
// /* An op's "value", if any */
// private final JsonNode value;
//
// static DiffOperation add(final JsonPointer path,
// final JsonNode value)
// {
// return new DiffOperation(Type.ADD, null, null, path, value);
// }
//
// static DiffOperation copy(final JsonPointer from,
// final JsonPointer path, final JsonNode value)
// {
// return new DiffOperation(Type.COPY, from, null, path,
// value);
// }
//
// static DiffOperation move(final JsonPointer from,
// final JsonNode oldValue, final JsonPointer path,
// final JsonNode value)
// {
// return new DiffOperation(Type.MOVE, from, oldValue, path,
// value);
// }
//
// static DiffOperation remove(final JsonPointer from,
// final JsonNode oldValue)
// {
// return new DiffOperation(Type.REMOVE, from, oldValue, null, null);
// }
//
// static DiffOperation replace(final JsonPointer from,
// final JsonNode oldValue, final JsonNode value)
// {
// return new DiffOperation(Type.REPLACE, from, oldValue, null,
// value);
// }
//
// private DiffOperation(final Type type, final JsonPointer from,
// final JsonNode oldValue, final JsonPointer path,
// final JsonNode value)
// {
// this.type = type;
// this.from = from;
// this.oldValue = oldValue;
// this.path = path;
// this.value = value;
// }
//
// Type getType()
// {
// return type;
// }
//
// JsonPointer getFrom()
// {
// return from;
// }
//
// JsonNode getOldValue()
// {
// return oldValue;
// }
//
// JsonPointer getPath()
// {
// return path;
// }
//
// JsonNode getValue()
// {
// return value;
// }
//
// JsonPatchOperation asJsonPatchOperation()
// {
// return type.toOperation(this);
// }
//
// enum Type {
// ADD
// {
// @Override
// JsonPatchOperation toOperation(final DiffOperation op)
// {
// return new AddOperation(op.path, op.value);
// }
// },
// COPY
// {
// @Override
// JsonPatchOperation toOperation(final DiffOperation op)
// {
// return new CopyOperation(op.from, op.path);
// }
// },
// MOVE
// {
// @Override
// JsonPatchOperation toOperation(final DiffOperation op)
// {
// return new MoveOperation(op.from, op.path);
// }
// },
// REMOVE
// {
// @Override
// JsonPatchOperation toOperation(final DiffOperation op)
// {
// return new RemoveOperation(op.from);
// }
// },
// REPLACE
// {
// @Override
// JsonPatchOperation toOperation(final DiffOperation op)
// {
// return new ReplaceOperation(op.from, op.value);
// }
// },
// ;
//
// abstract JsonPatchOperation toOperation(final DiffOperation op);
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch.diff;
//
//import com.fasterxml.jackson.databind.JsonNode;
//import com.github.fge.jackson.JsonNumEquals;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.github.fge.jsonpatch.JsonPatch;
//import com.github.fge.jsonpatch.JsonPatchOperation;
//import com.google.common.base.Equivalence;
//import com.google.common.base.Predicate;
//import com.google.common.collect.ImmutableMap;
//import com.google.common.collect.Lists;
//
//import javax.annotation.Nullable;
//import java.util.List;
//import java.util.Map;
//
//// TODO: cleanup
//final class DiffProcessor
//{
// private static final Equivalence<JsonNode> EQUIVALENCE
// = JsonNumEquals.getInstance();
//
// private final Map<JsonPointer, JsonNode> unchanged;
//
// private final List<DiffOperation> diffs = Lists.newArrayList();
//
// DiffProcessor(final Map<JsonPointer, JsonNode> unchanged)
// {
// this.unchanged = ImmutableMap.copyOf(unchanged);
// }
//
// void valueReplaced(final JsonPointer pointer, final JsonNode oldValue,
// final JsonNode newValue)
// {
// diffs.add(DiffOperation.replace(pointer, oldValue, newValue));
// }
//
// void valueRemoved(final JsonPointer pointer, final JsonNode value)
// {
// diffs.add(DiffOperation.remove(pointer, value));
// }
//
// void valueAdded(final JsonPointer pointer, final JsonNode value)
// {
// final int removalIndex = findPreviouslyRemoved(value);
// if (removalIndex != -1) {
// final DiffOperation removed = diffs.get(removalIndex);
// diffs.remove(removalIndex);
// diffs.add(DiffOperation.move(removed.getFrom(),
// value, pointer, value));
// return;
// }
// final JsonPointer ptr = findUnchangedValue(value);
// final DiffOperation op = ptr != null
// ? DiffOperation.copy(ptr, pointer, value)
// : DiffOperation.add(pointer, value);
//
// diffs.add(op);
// }
//
// JsonPatch getPatch()
// {
// final List<JsonPatchOperation> list = Lists.newArrayList();
//
// for (final DiffOperation op: diffs)
// list.add(op.asJsonPatchOperation());
//
// return new JsonPatch(list);
// }
//
// @Nullable
// private JsonPointer findUnchangedValue(final JsonNode value)
// {
// final Predicate<JsonNode> predicate = EQUIVALENCE.equivalentTo(value);
// for (final Map.Entry<JsonPointer, JsonNode> entry: unchanged.entrySet())
// if (predicate.apply(entry.getValue()))
// return entry.getKey();
// return null;
// }
//
// private int findPreviouslyRemoved(final JsonNode value)
// {
// final Predicate<JsonNode> predicate = EQUIVALENCE.equivalentTo(value);
//
// DiffOperation op;
//
// for (int i = 0; i < diffs.size(); i++) {
// op = diffs.get(i);
// if (op.getType() == DiffOperation.Type.REMOVE
// && predicate.apply(op.getOldValue()))
// return i;
// }
// return -1;
// }
//}
///*
// * Copyright (c) 2014, Francis Galiegue (fgaliegue@gmail.com)
// *
// * This software is dual-licensed under:
// *
// * - the Lesser General Public License (LGPL) version 3.0 or, at your option, any
// * later version;
// * - the Apache Software License (ASL) version 2.0.
// *
// * The text of this file and of both licenses is available at the root of this
// * project or, if you have the jar distribution, in directory META-INF/, under
// * the names LGPL-3.0.txt and ASL-2.0.txt respectively.
// *
// * Direct link to the sources:
// *
// * - LGPL 3.0: https://www.gnu.org/licenses/lgpl-3.0.txt
// * - ASL 2.0: http://www.apache.org/licenses/LICENSE-2.0.txt
// */
//
//package util.fgeJsonPatch.mergepatch;
//
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.JsonSerializable;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
//import com.github.fge.jackson.JacksonUtils;
//import com.github.fge.jsonpatch.JsonPatch;
//import com.github.fge.jsonpatch.JsonPatchException;
//import com.github.fge.jsonpatch.JsonPatchMessages;
//import com.github.fge.msgsimple.bundle.MessageBundle;
//import com.github.fge.msgsimple.load.MessageBundles;
//
//import javax.annotation.ParametersAreNonnullByDefault;
//import java.io.IOException;
//
///**
// * Implementation of JSON Merge Patch (RFC 7386)
// *
// * <p><a href="http://tools.ietf.org/html/rfc7386">JSON Merge Patch</a> is a
// * "toned down" version of JSON Patch. However, it covers a very large number of
// * use cases for JSON value modifications; its focus is mostly on patching
// * JSON Objects, which are by far the most common type of JSON texts exchanged
// * on the Internet.</p>
// *
// * <p>Applying a JSON Merge Patch is defined by a single, pseudo code function
// * as follows (quoted from the RFC; indentation fixed):</p>
// *
// * <pre>
// * define MergePatch(Target, Patch):
// * if Patch is an Object:
// * if Target is not an Object:
// * Target = {} # Ignore the contents and set it to an empty Object
// * for each Name/Value pair in Patch:
// * if Value is null:
// * if Name exists in Target:
// * remove the Name/Value pair from Target
// * else:
// * Target[Name] = MergePatch(Target[Name], Value)
// * return Target
// * else:
// * return Patch
// * </pre>
// */
//@ParametersAreNonnullByDefault
//@JsonDeserialize(using = JsonMergePatchDeserializer.class)
//public abstract class JsonMergePatch
// implements JsonSerializable
//{
// private static final ObjectMapper MAPPER = JacksonUtils.newMapper();
// protected static final MessageBundle BUNDLE
// = MessageBundles.getBundle(JsonPatchMessages.class);
//
// /**
// * Build an instance from a JSON input
// *
// * @param node the input
// * @return a JSON Merge Patch instance
// * @throws JsonPatchException failed to deserialize
// * @throws NullPointerException node is null
// */
// public static JsonMergePatch fromJson(final JsonNode node)
// throws JsonPatchException
// {
// BUNDLE.checkNotNull(node, "jsonPatch.nullInput");
// try {
// return MAPPER.readValue(node.traverse(), JsonMergePatch.class);
// } catch (IOException e) {
// throw new JsonPatchException(
// BUNDLE.getMessage("jsonPatch.deserFailed"), e);
// }
// }
//
// /**
// * Apply the patch to a given JSON value
// *
// * @param input the value to patch
// * @return the patched value
// * @throws JsonPatchException never thrown; only for consistency with
// * {@link JsonPatch}
// * @throws NullPointerException value is null
// */
// public abstract JsonNode apply(final JsonNode input)
// throws JsonPatchException;
//}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment