Commit d3bb1794 by Eli Ben Baruch

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

parent dcc59bb1
Showing with 5059 additions and 808 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'
///json-patch end
// <dependency>
// <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 fileTree(dir: '../ds/lib/external/sap', include: '*.jar')
// testCompile 'com.neovisionaries:nv-websocket-client:1.30'
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,11 +31,10 @@ ...@@ -34,11 +31,10 @@
}, { }, {
"name": "q", "name": "q",
"value": "location-type:PARKING_SPOT" "value": "location-type:PARKING_SPOT"
}, }, {
{ "name": "size",
"name": "size", "value": "30"
"value": "30" }],
}],
"headers": [], "headers": [],
"content": null "content": null
} }
...@@ -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",
"operationParams": {
"action": {
"metaDataActionClass": "logic.adapter.action.ExtractValueAction",
"params": {
"path": "/_links/self/href",
"valueType": "STRING"
}
}
}
}, {
"metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapStringToJsonOperation", "metaDataOperationClass": "logic.adapter.HttpAdapter.model.MapStringToJsonOperation",
"operationParams": { "operationParams": {
"action": { "action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": { "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", "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,47 +143,58 @@ ...@@ -125,47 +143,58 @@
"actions": [] "actions": []
} }
} }
}, }, {
{ "action": {
"action": { "metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction", "params": {
"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": "PKIN,PKOUT"
"value": "PKIN,PKOUT" }],
"headers": [],
"content": null
}
},
"onResponse": {
"onSuccess": {
"actionsInput": "CONTENT",
"actions": [{
"metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": {
"variables": {
"webSocket": {
"action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/url",
"valueType": "STRING"
},
"subString": {
"from": null,
"to": null
}
}
}
},
"headers": [{
"name": "predix-zone-id",
"value": "c54e3e63-8dc6-425e-a533-64e061f64023"
}],
"webSocket": "$webSocket",
"mdeKey": "$mdeKey",
"uid": "$uid"
} }
], }]
"headers": [],
"content": null
}
}, },
"onResponse": { "onError": {
"onSuccess": { "actionsInput": "CONTENT",
"actionsInput": "CONTENT", "actions": []
"actions": [{
"metaDataActionClass": "logic.adapter.action.ExtractValueAction",
"params": {
"path": "/url",
"valueType": "STRING"
}
},
{
"metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": {
"headers":[{
"name": "predix-zone-id",
"value": "c54e3e63-8dc6-425e-a533-64e061f64023"
}]
}
}]
},
"onError": {
"actionsInput": "CONTENT",
"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,14 +23,19 @@ ...@@ -26,14 +23,19 @@
"action": { "action": {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.SimpleHttpAction",
"params": { "params": {
"id": "subscribe", "id": "GetAllTrafficLanes",
"httpMethod": "GET", "httpMethod": "GET",
"path": "assets/$mdeKey/live-events", "path": "locations/search",
"queryParams": [{ "queryParams": [{
"name": "event-types", "name": "bbox",
"value": "TFEVT" "value": "32.123:-117,32.723179:-117.172655"
} }, {
], "name": "q",
"value": "location-type:TRAFFIC_LANE"
}, {
"name": "size",
"value": "30"
}],
"headers": [], "headers": [],
"content": null "content": null
} }
...@@ -44,19 +46,157 @@ ...@@ -44,19 +46,157 @@
"actions": [{ "actions": [{
"metaDataActionClass": "logic.adapter.action.ExtractValueAction", "metaDataActionClass": "logic.adapter.action.ExtractValueAction",
"params": { "params": {
"path": "/url", "path": "/_embedded/locations",
"valueType": "STRING" "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",
"httpMethod": "GET",
"path": "assets/$mdeKey/live-events",
"queryParams": [
{
"name": "event-types",
"value": "TFEVT"
} }
}, ],
"headers": [],
"content": null
}
},
"onResponse": {
"onSuccess": {
"actionsInput": "CONTENT",
"actions": [
{ {
"metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction", "metaDataActionClass": "logic.adapter.HttpAdapter.action.WebSocketAction",
"params": { "params": {
"headers":[{ "variables": {
"name": "predix-zone-id", "webSocket": {
"value": "b6fc22b6-ad71-423e-867b-a1b197f6cfc2" "action": {
}] "metaDataActionClass": "logic.adapter.HttpAdapter.action.ExtractSubStringAction",
"extract": {
"path": "/url",
"valueType": "STRING"
},
"subString": {
"from": null,
"to": null
}
}
}
},
"headers": [
{
"name": "predix-zone-id",
"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() {
this.mdeManager = new MdeManager(logger); try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
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) {
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; public BaseRestResponse doCreate(RequestContext requestContext, JsonNode content) {
BaseRestResponse brr=null;
String serviceId ;
} 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) {
List<Action> actions = api.getActions(); Api api = servicesRepository.getApi(serviceId, apiIdAsParams);
// TODO: 7/18/16 currently handle one action only if (api != null) {
if (actions.size()==0) List<Action> actions = api.getActions();
error = "failed to find adapter for: "+serviceId+"."+apiId; // TODO: 7/18/16 currently handle one action only
else { if (actions.size() != 0) {
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);
break;//currently only one action
// else }
// error = "failed to find adapter " + action.getAdapterId(); }
} else
break;//currently only one action 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,30 +85,30 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -102,30 +85,30 @@ 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) {
for (BaseAction action : actions = actionsListOnSuccess.getActions();
actions) { for (BaseAction action :
if (myTypeOf(action).equals("WebSocketAction")) { actions) {
httpFlow.addWebSocketAction((WebSocketAction) action); if (myTypeOf(action).equals("WebSocketAction")) {
((WebSocketAction)action).setWebSocetManager(webSocketManager); httpFlow.addWebSocketAction((WebSocketAction) action);
} ((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).contains("Map")) {
if (myTypeOf(operation.getOperationParams()).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); action1.setAdapterReferences(config.getConfigHttpRequestParams(),
action1.setAdapterReferences(config.getConfigHttpRequestParams(), httpClient,
httpClient, authClient);
authClient); }
} }
} }
} }
...@@ -133,30 +116,31 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp ...@@ -133,30 +116,31 @@ public class HttpAdapter extends BaseAdapter<HttpFlow, RequestParams, SimpleHttp
} }
actionsListOnError = onHttpResponse.getOnError(); actionsListOnError = onHttpResponse.getOnError();
actions = actionsListOnError.getActions(); if (actionsListOnError != null) {
for (BaseAction act : actions) { actions = actionsListOnError.getActions();
if (myTypeOf(act).equals("WebSocketAction")) { for (BaseAction act : actions) {
httpFlow.addWebSocketAction((WebSocketAction) act); if (myTypeOf(act).equals("WebSocketAction")) {
((WebSocketAction)act).setWebSocetManager(webSocketManager); httpFlow.addWebSocketAction((WebSocketAction) act);
} ((WebSocketAction) act).setWebSocetManager(webSocketManager);
if (myTypeOf(act).equals("SimpleHttpAction")) { }
httpFlow.addHttpAction((SimpleHttpAction) act); if (myTypeOf(act).equals("SimpleHttpAction")) {
act.setAdapterReferences(config.getConfigHttpRequestParams(), httpFlow.addHttpAction((SimpleHttpAction) act);
httpClient, act.setAdapterReferences(config.getConfigHttpRequestParams(),
authClient); httpClient,
} 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);
action1.setAdapterReferences(config.getConfigHttpRequestParams(), action1.setAdapterReferences(config.getConfigHttpRequestParams(),
httpClient, httpClient,
authClient); authClient);
}
} }
} }
} }
...@@ -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,20 +22,26 @@ public class MapOperationParams extends BaseOperationParams{ ...@@ -22,20 +22,26 @@ 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 String toString(){
public Map<String, String> getAdditionalProperties() { String str="action="+action.toString();
return this.additionalProperties; return str;
} }
@JsonAnySetter // @JsonIgnore
public void setAdditionalProperty(String name, String value) { // private Map<String, String> additionalProperties = new HashMap<String, String>();
this.additionalProperties.put(name, value);
} // @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);
}
}
} }
else
path = dstRequestParamsPattern.getPath();
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.diff;
//
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import com.fasterxml.jackson.databind.node.ArrayNode;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.github.fge.jackson.JacksonUtils;
//import com.github.fge.jackson.JsonNumEquals;
//import com.github.fge.jackson.NodeType;
//import com.github.fge.jackson.jsonpointer.JsonPointer;
//import com.github.fge.jsonpatch.JsonPatch;
//import com.github.fge.jsonpatch.JsonPatchMessages;
//import com.github.fge.msgsimple.bundle.MessageBundle;
//import com.github.fge.msgsimple.load.MessageBundles;
//import com.google.common.annotations.VisibleForTesting;
//import com.google.common.base.Equivalence;
//import com.google.common.collect.Maps;
//import com.google.common.collect.Sets;
//
//import javax.annotation.ParametersAreNonnullByDefault;
//import java.io.IOException;
//import java.util.Iterator;
//import java.util.Map;
//import java.util.Set;
//
///**
// * JSON "diff" implementation
// *
// * <p>This class generates a JSON Patch (as in, an RFC 6902 JSON Patch) given
// * two JSON values as inputs. The patch can be obtained directly as a {@link
// * JsonPatch} or as a {@link JsonNode}.</p>
// *
// * <p>Note: there is <b>no guarantee</b> about the usability of the generated
// * patch for any other source/target combination than the one used to generate
// * the patch.</p>
// *
// * <p>This class always performs operations in the following order: removals,
// * additions and replacements. It then factors removal/addition pairs into
// * move operations, or copy operations if a common element exists, at the same
// * {@link JsonPointer pointer}, in both the source and destination.</p>
// *
// * <p>You can obtain a diff either as a {@link JsonPatch} directly or, for
// * backwards compatibility, as a {@link JsonNode}.</p>
// *
// * @since 1.2
// */
//@ParametersAreNonnullByDefault
//public final class JsonDiff
//{
// private static final MessageBundle BUNDLE
// = MessageBundles.getBundle(JsonPatchMessages.class);
// private static final ObjectMapper MAPPER = JacksonUtils.newMapper();
//
// private static final Equivalence<JsonNode> EQUIVALENCE
// = JsonNumEquals.getInstance();
//
// private JsonDiff()
// {
// }
//
// /**
// * Generate a JSON patch for transforming the source node into the target
// * node
// *
// * @param source the node to be patched
// * @param target the expected result after applying the patch
// * @return the patch as a {@link JsonPatch}
// *
// * @since 1.9
// */
// public static JsonPatch asJsonPatch(final JsonNode source,
// final JsonNode target)
// {
// BUNDLE.checkNotNull(source, "common.nullArgument");
// BUNDLE.checkNotNull(target, "common.nullArgument");
// final Map<JsonPointer, JsonNode> unchanged
// = getUnchangedValues(source, target);
// final DiffProcessor processor = new DiffProcessor(unchanged);
//
// generateDiffs(processor, JsonPointer.empty(), source, target);
// return processor.getPatch();
// }
//
// /**
// * Generate a JSON patch for transforming the source node into the target
// * node
// *
// * @param source the node to be patched
// * @param target the expected result after applying the patch
// * @return the patch as a {@link JsonNode}
// */
// public static JsonNode asJson(final JsonNode source, final JsonNode target)
// {
// final String s;
// try {
// s = MAPPER.writeValueAsString(asJsonPatch(source, target));
// return MAPPER.readTree(s);
// } catch (IOException e) {
// throw new RuntimeException("cannot generate JSON diff", e);
// }
// }
//
// private static void generateDiffs(final DiffProcessor processor,
// final JsonPointer pointer, final JsonNode source, final JsonNode target)
// {
// if (EQUIVALENCE.equivalent(source, target))
// return;
//
// final NodeType firstType = NodeType.getNodeType(source);
// final NodeType secondType = NodeType.getNodeType(target);
//
// /*
// * Node types differ: generate a replacement operation.
// */
// if (firstType != secondType) {
// processor.valueReplaced(pointer, source, target);
// return;
// }
//
// /*
// * If we reach this point, it means that both nodes are the same type,
// * but are not equivalent.
// *
// * If this is not a container, generate a replace operation.
// */
// if (!source.isContainerNode()) {
// processor.valueReplaced(pointer, source, target);
// return;
// }
//
// /*
// * If we reach this point, both nodes are either objects or arrays;
// * delegate.
// */
// if (firstType == NodeType.OBJECT)
// generateObjectDiffs(processor, pointer, (ObjectNode) source,
// (ObjectNode) target);
// else // array
// generateArrayDiffs(processor, pointer, (ArrayNode) source,
// (ArrayNode) target);
// }
//
// private static void generateObjectDiffs(final DiffProcessor processor,
// final JsonPointer pointer, final ObjectNode source,
// final ObjectNode target)
// {
// final Set<String> firstFields
// = Sets.newTreeSet(Sets.newHashSet(source.fieldNames()));
// final Set<String> secondFields
// = Sets.newTreeSet(Sets.newHashSet(target.fieldNames()));
//
// for (final String field: Sets.difference(firstFields, secondFields))
// processor.valueRemoved(pointer.append(field), source.get(field));
//
// for (final String field: Sets.difference(secondFields, firstFields))
// processor.valueAdded(pointer.append(field), target.get(field));
//
// for (final String field: Sets.intersection(firstFields, secondFields))
// generateDiffs(processor, pointer.append(field), source.get(field),
// target.get(field));
// }
//
// private static void generateArrayDiffs(final DiffProcessor processor,
// final JsonPointer pointer, final ArrayNode source,
// final ArrayNode target)
// {
// final int firstSize = source.size();
// final int secondSize = target.size();
// final int size = Math.min(firstSize, secondSize);
//
// /*
// * Source array is larger; in this case, elements are removed from the
// * target; the index of removal is always the original arrays's length.
// */
// for (int index = size; index < firstSize; index++)
// processor.valueRemoved(pointer.append(size), source.get(index));
//
// for (int index = 0; index < size; index++)
// generateDiffs(processor, pointer.append(index), source.get(index),
// target.get(index));
//
// // Deal with the destination array being larger...
// for (int index = size; index < secondSize; index++)
// processor.valueAdded(pointer.append("-"), target.get(index));
// }
//
//
// @VisibleForTesting
// static Map<JsonPointer, JsonNode> getUnchangedValues(final JsonNode source,
// final JsonNode target)
// {
// final Map<JsonPointer, JsonNode> ret = Maps.newHashMap();
// computeUnchanged(ret, JsonPointer.empty(), source, target);
// return ret;
// }
//
// private static void computeUnchanged(final Map<JsonPointer, JsonNode> ret,
// final JsonPointer pointer, final JsonNode first, final JsonNode second)
// {
// if (EQUIVALENCE.equivalent(first, second)) {
// ret.put(pointer, second);
// return;
// }
//
// final NodeType firstType = NodeType.getNodeType(first);
// final NodeType secondType = NodeType.getNodeType(second);
//
// if (firstType != secondType)
// return; // nothing in common
//
// // We know they are both the same type, so...
//
// switch (firstType) {
// case OBJECT:
// computeObject(ret, pointer, first, second);
// break;
// case ARRAY:
// computeArray(ret, pointer, first, second);
// default:
// /* nothing */
// }
// }
//
// private static void computeObject(final Map<JsonPointer, JsonNode> ret,
// final JsonPointer pointer, final JsonNode source,
// final JsonNode target)
// {
// final Iterator<String> firstFields = source.fieldNames();
//
// String name;
//
// while (firstFields.hasNext()) {
// name = firstFields.next();
// if (!target.has(name))
// continue;
// computeUnchanged(ret, pointer.append(name), source.get(name),
// target.get(name));
// }
// }
//
// private static void computeArray(final Map<JsonPointer, JsonNode> ret,
// final JsonPointer pointer, final JsonNode source, final JsonNode target)
// {
// final int size = Math.min(source.size(), target.size());
//
// for (int i = 0; i < size; i++)
// computeUnchanged(ret, pointer.append(i), source.get(i),
// target.get(i));
// }
//}
///*
// * 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;
//}
///*
// * 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.core.JsonParser;
//import com.fasterxml.jackson.core.JsonProcessingException;
//import com.fasterxml.jackson.core.ObjectCodec;
//import com.fasterxml.jackson.databind.DeserializationContext;
//import com.fasterxml.jackson.databind.JsonDeserializer;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.fasterxml.jackson.databind.node.NullNode;
//import com.github.fge.jackson.JacksonUtils;
//import com.google.common.collect.Maps;
//import com.google.common.collect.Sets;
//
//import java.io.IOException;
//import java.util.Iterator;
//import java.util.Map;
//import java.util.Set;
//
//final class JsonMergePatchDeserializer
// extends JsonDeserializer<JsonMergePatch>
//{
// /*
// * FIXME! UGLY! HACK!
// *
// * We MUST have an ObjectCodec ready so that the parser in .deserialize()
// * can actually do something useful -- for instance, deserializing even a
// * JsonNode.
// *
// * Jackson does not do this automatically; I don't know why...
// */
// private static final ObjectCodec CODEC = JacksonUtils.newMapper();
//
// @Override
// public JsonMergePatch deserialize(final JsonParser jp,
// final DeserializationContext ctxt)
// throws IOException, JsonProcessingException
// {
// // FIXME: see comment above
// jp.setCodec(CODEC);
// final JsonNode node = jp.readValueAsTree();
//
// /*
// * Not an object: the simple case
// */
// if (!node.isObject())
// return new NonObjectMergePatch(node);
//
// /*
// * The complicated case...
// *
// * We have to build a set of removed members, plus a map of modified
// * members.
// */
//
// final Set<String> removedMembers = Sets.newHashSet();
// final Map<String, JsonMergePatch> modifiedMembers = Maps.newHashMap();
// final Iterator<Map.Entry<String, JsonNode>> iterator = node.fields();
//
// Map.Entry<String, JsonNode> entry;
//
// while (iterator.hasNext()) {
// entry = iterator.next();
// if (entry.getValue().isNull())
// removedMembers.add(entry.getKey());
// else {
// final JsonMergePatch value
// = deserialize(entry.getValue().traverse(), ctxt);
// modifiedMembers.put(entry.getKey(), value);
// }
// }
//
// return new ObjectMergePatch(removedMembers, modifiedMembers);
// }
//
// /*
// * This method MUST be overriden... The default is to return null, which is
// * not what we want.
// */
// @Override
// public JsonMergePatch getNullValue()
// {
// return new NonObjectMergePatch(NullNode.getInstance());
// }
//}
///*
// * 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.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.github.fge.jsonpatch.JsonPatchException;
//import com.google.common.base.Preconditions;
//
//import javax.annotation.ParametersAreNonnullByDefault;
//import java.io.IOException;
//
//@ParametersAreNonnullByDefault
//final class NonObjectMergePatch
// extends JsonMergePatch
//{
// private final JsonNode node;
//
// NonObjectMergePatch(final JsonNode node)
// {
// this.node = Preconditions.checkNotNull(node);
// }
//
// @Override
// public JsonNode apply(final JsonNode input)
// throws JsonPatchException
// {
// BUNDLE.checkNotNull(input, "jsonPatch.nullValue");
// return node;
// }
//
// @Override
// public void serialize(final JsonGenerator jgen,
// final SerializerProvider provider)
// throws IOException, JsonProcessingException
// {
// jgen.writeTree(node);
// }
//
// @Override
// public void serializeWithType(final JsonGenerator jgen,
// final SerializerProvider provider, final TypeSerializer typeSer)
// throws IOException, JsonProcessingException
// {
// 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.mergepatch;
//
//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.NullNode;
//import com.fasterxml.jackson.databind.node.ObjectNode;
//import com.github.fge.jackson.JacksonUtils;
//import com.github.fge.jsonpatch.JsonPatchException;
//import com.google.common.base.Optional;
//import com.google.common.collect.ImmutableMap;
//import com.google.common.collect.ImmutableSet;
//
//import javax.annotation.ParametersAreNonnullByDefault;
//import java.io.IOException;
//import java.util.Map;
//import java.util.Set;
//
//@ParametersAreNonnullByDefault
//final class ObjectMergePatch
// extends JsonMergePatch
//{
// private final Set<String> removedMembers;
// private final Map<String, JsonMergePatch> modifiedMembers;
//
// ObjectMergePatch(final Set<String> removedMembers,
// final Map<String, JsonMergePatch> modifiedMembers)
// {
// this.removedMembers = ImmutableSet.copyOf(removedMembers);
// this.modifiedMembers = ImmutableMap.copyOf(modifiedMembers);
// }
//
// @Override
// public JsonNode apply(final JsonNode input)
// throws JsonPatchException
// {
// BUNDLE.checkNotNull(input, "jsonPatch.nullValue");
// /*
// * If the input is an object, we make a deep copy of it
// */
// final ObjectNode ret = input.isObject() ? (ObjectNode) input.deepCopy()
// : JacksonUtils.nodeFactory().objectNode();
//
// /*
// * Our result is now a JSON Object; first, add (or modify) existing
// * members in the result
// */
// String key;
// JsonNode value;
// for (final Map.Entry<String, JsonMergePatch> entry:
// modifiedMembers.entrySet()) {
// key = entry.getKey();
// /*
// * FIXME: ugly...
// *
// * We treat missing keys as null nodes; this "works" because in
// * the modifiedMembers map, values are JsonMergePatch instances:
// *
// * * if it is a NonObjectMergePatch, the value is replaced
// * unconditionally;
// * * if it is an ObjectMergePatch, we get back here; the value will
// * be replaced with a JSON Object anyway before being processed.
// */
// value = Optional.fromNullable(ret.get(key))
// .or(NullNode.getInstance());
// ret.put(key, entry.getValue().apply(value));
// }
//
// ret.remove(removedMembers);
//
// return ret;
// }
//
// @Override
// public void serialize(final JsonGenerator jgen,
// final SerializerProvider provider)
// throws IOException, JsonProcessingException
// {
// jgen.writeStartObject();
//
// /*
// * Write removed members as JSON nulls
// */
// for (final String member: removedMembers)
// jgen.writeNullField(member);
//
// /*
// * Write modified members; delegate to serialization for writing values
// */
// for (final Map.Entry<String, JsonMergePatch> entry:
// modifiedMembers.entrySet()) {
// jgen.writeFieldName(entry.getKey());
// entry.getValue().serialize(jgen, provider);
// }
//
// jgen.writeEndObject();
// }
//
// @Override
// public void serializeWithType(final JsonGenerator jgen,
// final SerializerProvider provider, final TypeSerializer typeSer)
// throws IOException, JsonProcessingException
// {
// 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
##
#
#common.nullArgument=argument cannot be null
#jsonPatch.deserFailed=unable to deserialize JSON input
#jsonPatch.nullInput=input cannot be null
#jsonPatch.nullValue=value cannot be null
#jsonPatch.noSuchParent=parent of node to add does not exist
#jsonPatch.notAnIndex=reference token is not an array index
#jsonPatch.noSuchIndex=no such index in target array
#jsonPatch.noSuchPath=no such path in target JSON document
#jsonPatch.parentNotContainer=parent of path to add to is not a container
#jsonPatch.valueTestFailure=value differs from expectations
#mergePatch.notContainer=value is neither an object or an array (found %s)
package util.zjsonpatch;
/**
* Created with IntelliJ IDEA.
* User: gopi.vishwakarma
* Date: 10/07/15
* Time: 10:35 AM
*/
class Constants {
public static String OP = "op";
public static String VALUE = "value";
public static String PATH = "path";
public static String FROM = "from";
}
package util.zjsonpatch;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.List;
/**
* User: gopi.vishwakarma
* Date: 30/07/14
*/
class Diff {
private Operation operation;
private List<Object> path;
private JsonNode value;
private List<Object> toPath; //only to be used in move operation
Diff(Operation operation, List<Object> path, JsonNode value) {
this.operation = operation;
this.path = path;
this.value = value;
}
Diff(Operation operation, List<Object> fromPath, JsonNode value, List<Object> toPath) {
this.operation = operation;
this.path = fromPath;
this.value = value;
this.toPath = toPath;
}
public Operation getOperation() {
return operation;
}
public List<Object> getPath() {
return path;
}
public JsonNode getValue() {
return value;
}
public static Diff generateDiff(Operation replace, List<Object> path, JsonNode target) {
return new Diff(replace, path, target);
}
List<Object> getToPath() {
return toPath;
}
}
package util.zjsonpatch;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeFactory;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.ListUtils;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* User: gopi.vishwakarma
* Date: 30/07/14
*/
public class JsonDiff {
public static final EncodePathFunction ENCODE_PATH_FUNCTION = new EncodePathFunction();
private final static class EncodePathFunction implements Function<Object, String> {
@Override
public String apply(Object object) {
String path = object.toString(); // see http://tools.ietf.org/html/rfc6901#section-4
return path.replaceAll("~", "~0").replaceAll("/", "~1");
}
}
public static JsonNode asJson(final JsonNode source, final JsonNode target) {
final List<Diff> diffs = new ArrayList<Diff>();
List<Object> path = new LinkedList<Object>();
/**
* generating diffs in the order of their occurrence
*/
generateDiffs(diffs, path, source, target);
/**
* Merging remove & add to move operation
*/
compactDiffs(diffs);
return getJsonNodes(diffs);
}
/**
* This method merge 2 diffs ( remove then add, or vice versa ) with same value into one Move operation,
* all the core logic resides here only
*/
private static void compactDiffs(List<Diff> diffs) {
for (int i = 0; i < diffs.size(); i++) {
Diff diff1 = diffs.get(i);
// if not remove OR add, move to next diff
if (!(Operation.REMOVE.equals(diff1.getOperation()) ||
Operation.ADD.equals(diff1.getOperation()))) {
continue;
}
for (int j = i + 1; j < diffs.size(); j++) {
Diff diff2 = diffs.get(j);
if (!diff1.getValue().equals(diff2.getValue())) {
continue;
}
Diff moveDiff = null;
if (Operation.REMOVE.equals(diff1.getOperation()) &&
Operation.ADD.equals(diff2.getOperation())) {
computeRelativePath(diff2.getPath(), i + 1, j - 1, diffs);
moveDiff = new Diff(Operation.MOVE, diff1.getPath(), diff2.getValue(), diff2.getPath());
} else if (Operation.ADD.equals(diff1.getOperation()) &&
Operation.REMOVE.equals(diff2.getOperation())) {
computeRelativePath(diff2.getPath(), i, j - 1, diffs); // diff1's add should also be considered
moveDiff = new Diff(Operation.MOVE, diff2.getPath(), diff1.getValue(), diff1.getPath());
}
if (moveDiff != null) {
diffs.remove(j);
diffs.set(i, moveDiff);
break;
}
}
}
}
//Note : only to be used for arrays
//Finds the longest common Ancestor ending at Array
private static void computeRelativePath(List<Object> path, int startIdx, int endIdx, List<Diff> diffs) {
List<Integer> counters = new ArrayList<Integer>();
resetCounters(counters, path.size());
for (int i = startIdx; i <= endIdx; i++) {
Diff diff = diffs.get(i);
//Adjust relative path according to #ADD and #Remove
if (Operation.ADD.equals(diff.getOperation()) || Operation.REMOVE.equals(diff.getOperation())) {
updatePath(path, diff, counters);
}
}
updatePathWithCounters(counters, path);
}
private static void resetCounters(List<Integer> counters, int size) {
for (int i = 0; i < size; i++) {
counters.add(0);
}
}
private static void updatePathWithCounters(List<Integer> counters, List<Object> path) {
for (int i = 0; i < counters.size(); i++) {
int value = counters.get(i);
if (value != 0) {
Integer currValue = Integer.parseInt(path.get(i).toString());
path.set(i, String.valueOf(currValue + value));
}
}
}
private static void updatePath(List<Object> path, Diff pseudo, List<Integer> counters) {
//find longest common prefix of both the paths
if (pseudo.getPath().size() <= path.size()) {
int idx = -1;
for (int i = 0; i < pseudo.getPath().size() - 1; i++) {
if (pseudo.getPath().get(i).equals(path.get(i))) {
idx = i;
} else {
break;
}
}
if (idx == pseudo.getPath().size() - 2) {
if (pseudo.getPath().get(pseudo.getPath().size() - 1) instanceof Integer) {
updateCounters(pseudo, pseudo.getPath().size() - 1, counters);
}
}
}
}
private static void updateCounters(Diff pseudo, int idx, List<Integer> counters) {
if (Operation.ADD.equals(pseudo.getOperation())) {
counters.set(idx, counters.get(idx) - 1);
} else {
if (Operation.REMOVE.equals(pseudo.getOperation())) {
counters.set(idx, counters.get(idx) + 1);
}
}
}
private static ArrayNode getJsonNodes(List<Diff> diffs) {
JsonNodeFactory FACTORY = JsonNodeFactory.instance;
final ArrayNode patch = FACTORY.arrayNode();
for (Diff diff : diffs) {
ObjectNode jsonNode = getJsonNode(FACTORY, diff);
patch.add(jsonNode);
}
return patch;
}
private static ObjectNode getJsonNode(JsonNodeFactory FACTORY, Diff diff) {
ObjectNode jsonNode = FACTORY.objectNode();
jsonNode.put(Constants.OP, diff.getOperation().rfcName());
jsonNode.put(Constants.PATH, getArrayNodeRepresentation(diff.getPath()));
if (Operation.MOVE.equals(diff.getOperation())) {
jsonNode.put(Constants.FROM, getArrayNodeRepresentation(diff.getPath())); //required {from} only in case of Move Operation
jsonNode.put(Constants.PATH, getArrayNodeRepresentation(diff.getToPath())); // destination Path
}
if (!Operation.REMOVE.equals(diff.getOperation()) && !Operation.MOVE.equals(diff.getOperation())) { // setting only for Non-Remove operation
jsonNode.put(Constants.VALUE, diff.getValue());
}
return jsonNode;
}
private static String getArrayNodeRepresentation(List<Object> path) {
return Joiner.on('/').appendTo(new StringBuilder().append('/'),
Iterables.transform(path, ENCODE_PATH_FUNCTION)).toString();
}
private static void generateDiffs(List<Diff> diffs, List<Object> path, JsonNode source, JsonNode target) {
if (!source.equals(target)) {
final NodeType sourceType = NodeType.getNodeType(source);
final NodeType targetType = NodeType.getNodeType(target);
if (sourceType == NodeType.ARRAY && targetType == NodeType.ARRAY) {
//both are arrays
compareArray(diffs, path, source, target);
} else if (sourceType == NodeType.OBJECT && targetType == NodeType.OBJECT) {
//both are zjsonpatch
compareObjects(diffs, path, source, target);
} else {
//can be replaced
diffs.add(Diff.generateDiff(Operation.REPLACE, path, target));
}
}
}
private static void compareArray(List<Diff> diffs, List<Object> path, JsonNode source, JsonNode target) {
List<JsonNode> lcs = getLCS(source, target);
int srcIdx = 0;
int targetIdx = 0;
int lcsIdx = 0;
int srcSize = source.size();
int targetSize = target.size();
int lcsSize = lcs.size();
int pos = 0;
while (lcsIdx < lcsSize) {
JsonNode lcsNode = lcs.get(lcsIdx);
JsonNode srcNode = source.get(srcIdx);
JsonNode targetNode = target.get(targetIdx);
if (lcsNode.equals(srcNode) && lcsNode.equals(targetNode)) { // Both are same as lcs node, nothing to do here
srcIdx++;
targetIdx++;
lcsIdx++;
pos++;
} else {
if (lcsNode.equals(srcNode)) { // src node is same as lcs, but not targetNode
//addition
List<Object> currPath = getPath(path, pos);
diffs.add(Diff.generateDiff(Operation.ADD, currPath, targetNode));
pos++;
targetIdx++;
} else if (lcsNode.equals(targetNode)) { //targetNode node is same as lcs, but not src
//removal,
List<Object> currPath = getPath(path, pos);
diffs.add(Diff.generateDiff(Operation.REMOVE, currPath, srcNode));
srcIdx++;
} else {
List<Object> currPath = getPath(path, pos);
//both are unequal to lcs node
generateDiffs(diffs, currPath, srcNode, targetNode);
srcIdx++;
targetIdx++;
pos++;
}
}
}
while ((srcIdx < srcSize) && (targetIdx < targetSize)) {
JsonNode srcNode = source.get(srcIdx);
JsonNode targetNode = target.get(targetIdx);
List<Object> currPath = getPath(path, pos);
generateDiffs(diffs, currPath, srcNode, targetNode);
srcIdx++;
targetIdx++;
pos++;
}
pos = addRemaining(diffs, path, target, pos, targetIdx, targetSize);
removeRemaining(diffs, path, pos, srcIdx, srcSize, source);
}
private static Integer removeRemaining(List<Diff> diffs, List<Object> path, int pos, int srcIdx, int srcSize, JsonNode source) {
while (srcIdx < srcSize) {
List<Object> currPath = getPath(path, pos);
diffs.add(Diff.generateDiff(Operation.REMOVE, currPath, source.get(srcIdx)));
srcIdx++;
}
return pos;
}
private static Integer addRemaining(List<Diff> diffs, List<Object> path, JsonNode target, int pos, int targetIdx, int targetSize) {
while (targetIdx < targetSize) {
JsonNode jsonNode = target.get(targetIdx);
List<Object> currPath = getPath(path, pos);
diffs.add(Diff.generateDiff(Operation.ADD, currPath, jsonNode.deepCopy()));
pos++;
targetIdx++;
}
return pos;
}
private static void compareObjects(List<Diff> diffs, List<Object> path, JsonNode source, JsonNode target) {
Iterator<String> keysFromSrc = source.fieldNames();
while (keysFromSrc.hasNext()) {
String key = keysFromSrc.next();
if (!target.has(key)) {
//remove case
List<Object> currPath = getPath(path, key);
diffs.add(Diff.generateDiff(Operation.REMOVE, currPath, source.get(key)));
continue;
}
List<Object> currPath = getPath(path, key);
generateDiffs(diffs, currPath, source.get(key), target.get(key));
}
Iterator<String> keysFromTarget = target.fieldNames();
while (keysFromTarget.hasNext()) {
String key = keysFromTarget.next();
if (!source.has(key)) {
//add case
List<Object> currPath = getPath(path, key);
diffs.add(Diff.generateDiff(Operation.ADD, currPath, target.get(key)));
}
}
}
private static List<Object> getPath(List<Object> path, Object key) {
List<Object> toReturn = new ArrayList<Object>();
toReturn.addAll(path);
toReturn.add(key);
return toReturn;
}
private static List<JsonNode> getLCS(final JsonNode first, final JsonNode second) {
Preconditions.checkArgument(first.isArray(), "LCS can only work on JSON arrays");
Preconditions.checkArgument(second.isArray(), "LCS can only work on JSON arrays");
return ListUtils.longestCommonSubsequence(Lists.newArrayList(first), Lists.newArrayList(second));
}
}
package util.zjsonpatch;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.base.Preconditions;
import java.util.EnumMap;
import java.util.Map;
enum NodeType {
/**
* Array nodes
*/
ARRAY("array"),
/**
* Boolean nodes
*/
BOOLEAN("boolean"),
/**
* Integer nodes
*/
INTEGER("integer"),
/**
* Number nodes (ie, decimal numbers)
*/
NULL("null"),
/**
* Object nodes
*/
NUMBER("number"),
/**
* Null nodes
*/
OBJECT("object"),
/**
* String nodes
*/
STRING("string");
/**
* The name for this type, as encountered in a JSON schema
*/
private final String name;
private static final Map<JsonToken, NodeType> TOKEN_MAP
= new EnumMap<JsonToken, NodeType>(JsonToken.class);
static {
TOKEN_MAP.put(JsonToken.START_ARRAY, ARRAY);
TOKEN_MAP.put(JsonToken.VALUE_TRUE, BOOLEAN);
TOKEN_MAP.put(JsonToken.VALUE_FALSE, BOOLEAN);
TOKEN_MAP.put(JsonToken.VALUE_NUMBER_INT, INTEGER);
TOKEN_MAP.put(JsonToken.VALUE_NUMBER_FLOAT, NUMBER);
TOKEN_MAP.put(JsonToken.VALUE_NULL, NULL);
TOKEN_MAP.put(JsonToken.START_OBJECT, OBJECT);
TOKEN_MAP.put(JsonToken.VALUE_STRING, STRING);
}
NodeType(final String name) {
this.name = name;
}
@Override
public String toString() {
return name;
}
public static NodeType getNodeType(final JsonNode node) {
final JsonToken token = node.asToken();
final NodeType ret = TOKEN_MAP.get(token);
Preconditions.checkNotNull(ret, "unhandled token type " + token);
return ret;
}
}
package util.zjsonpatch;
import com.google.common.collect.ImmutableMap;
import java.util.Map;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* User: gopi.vishwakarma
* Date: 30/07/14
*/
enum Operation {
ADD("add"),
REMOVE("remove"),
REPLACE("replace"),
MOVE("move");
private final static Map<String, Operation> OPS = ImmutableMap.of(
ADD.rfcName, ADD,
REMOVE.rfcName, REMOVE,
REPLACE.rfcName, REPLACE,
MOVE.rfcName, MOVE
);
private String rfcName;
Operation(String rfcName) {
this.rfcName = rfcName;
}
public static Operation fromRfcName(String rfcName) {
checkNotNull(rfcName, "rfcName cannot be null");
return checkNotNull(OPS.get(rfcName.toLowerCase()), "unknown / unsupported operation %s", rfcName);
}
public String rfcName() {
return this.rfcName;
}
}
package util.zjsonpatch;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import java.util.Iterator;
import java.util.List;
/**
* User: gopi.vishwakarma
* Date: 31/07/14
*/
public class ZJsonPatch {
private static final DecodePathFunction DECODE_PATH_FUNCTION = new DecodePathFunction();
private final static class DecodePathFunction implements Function<String, String> {
@Override
public String apply(String path) {
return path.replaceAll("~1", "/").replaceAll("~0", "~"); // see http://tools.ietf.org/html/rfc6901#section-4
}
}
public static JsonNode apply(JsonNode patch, JsonNode source) {
Iterator<JsonNode> operations = patch.iterator();
JsonNode ret = source.deepCopy();
while (operations.hasNext()) {
JsonNode jsonNode = operations.next();
Operation operation = Operation.fromRfcName(jsonNode.get(Constants.OP).toString().replaceAll("\"", ""));
List<String> path = getPath(jsonNode.get(Constants.PATH));
List<String> fromPath = null;
if (Operation.MOVE.equals(operation)) {
fromPath = getPath(jsonNode.get(Constants.FROM));
}
JsonNode value = null;
if (!Operation.REMOVE.equals(operation) && !Operation.MOVE.equals(operation)) {
value = jsonNode.get(Constants.VALUE);
}
switch (operation) {
case REMOVE:
remove(ret, path);
break;
case REPLACE:
ret = replace(ret, path, value);
break;
case ADD:
ret = add(ret, path, value);
break;
case MOVE:
ret = move(ret, fromPath, path);
break;
}
}
return ret;
}
private static JsonNode move(JsonNode node, List<String> fromPath, List<String> toPath) {
JsonNode parentNode = getParentNode(node, fromPath);
String field = fromPath.get(fromPath.size() - 1).replaceAll("\"", "");
JsonNode valueNode = parentNode.isArray() ? parentNode.get(Integer.parseInt(field)) : parentNode.get(field);
remove(node, fromPath);
return add(node, toPath, valueNode);
}
private static JsonNode add(JsonNode node, List<String> path, JsonNode value) {
if (path.isEmpty()) {
throw new RuntimeException("[ADD Operation] path is empty , path : ");
} else {
JsonNode parentNode = getParentNode(node, path);
if (parentNode == null) {
throw new RuntimeException("[ADD Operation] noSuchPath in source, path provided : " + path);
} else {
String fieldToReplace = path.get(path.size() - 1).replaceAll("\"", "");
if (fieldToReplace.equals("") && path.size() == 1) {
return value;
}
if (!parentNode.isContainerNode()) {
throw new RuntimeException("[ADD Operation] parent is not a container in source, path provided : " + path + " | node : " + parentNode);
} else {
if (parentNode.isArray()) {
addToArray(path, value, parentNode);
} else {
addToObject(path, parentNode, value);
}
}
}
}
return node;
}
private static void addToObject(List<String> path, JsonNode node, JsonNode value) {
final ObjectNode target = (ObjectNode) node;
String key = path.get(path.size() - 1).replaceAll("\"", "");
target.put(key, value);
}
private static void addToArray(List<String> path, JsonNode value, JsonNode parentNode) {
final ArrayNode target = (ArrayNode) parentNode;
String idxStr = path.get(path.size() - 1);
if ("-".equals(idxStr)) {
// see http://tools.ietf.org/html/rfc6902#section-4.1
target.add(value);
} else {
Integer idx = Integer.parseInt(idxStr.replaceAll("\"", ""));
if (idx < target.size()) {
target.insert(idx, value);
} else {
if (idx == target.size()) {
target.add(value);
} else {
throw new RuntimeException("[ADD Operation] [addToArray] index Out of bound, index provided is higher than allowed, path " + path);
}
}
}
}
private static JsonNode replace(JsonNode node, List<String> path, JsonNode value) {
if (path.isEmpty()) {
throw new RuntimeException("[Replace Operation] path is empty");
} else {
JsonNode parentNode = getParentNode(node, path);
if (parentNode == null) {
throw new RuntimeException("[Replace Operation] noSuchPath in source, path provided : " + path);
} else {
String fieldToReplace = path.get(path.size() - 1).replaceAll("\"", "");
if (Strings.isNullOrEmpty(fieldToReplace) && path.size() == 1) {
return value;
}
if (parentNode.isObject())
((ObjectNode) parentNode).put(fieldToReplace, value);
else
((ArrayNode) parentNode).set(Integer.parseInt(fieldToReplace), value);
}
return node;
}
}
private static void remove(JsonNode node, List<String> path) {
if (path.isEmpty()) {
throw new RuntimeException("[Remove Operation] path is empty");
} else {
JsonNode parentNode = getParentNode(node, path);
if (parentNode == null) {
throw new RuntimeException("[Remove Operation] noSuchPath in source, path provided : " + path);
} else {
String fieldToRemove = path.get(path.size() - 1).replaceAll("\"", "");
if (parentNode.isObject())
((ObjectNode) parentNode).remove(fieldToRemove);
else
((ArrayNode) parentNode).remove(Integer.parseInt(fieldToRemove));
}
}
}
private static JsonNode getParentNode(JsonNode node, List<String> fromPath) {
List<String> pathToParent = fromPath.subList(0, fromPath.size() - 1); // would never by out of bound, lets see
return getNode(node, pathToParent, 1);
}
private static JsonNode getNode(JsonNode ret, List<String> path, int pos) {
if (pos >= path.size()) {
return ret;
}
String key = path.get(pos);
if (ret.isArray()) {
int keyInt = Integer.parseInt(key.replaceAll("\"", ""));
return getNode(ret.get(keyInt), path, ++pos);
} else if (ret.isObject()) {
if (ret.has(key)) {
return getNode(ret.get(key), path, ++pos);
}
return null;
} else {
return ret;
}
}
private static List<String> getPath(JsonNode path) {
List<String> paths = Splitter.on('/').splitToList(path.toString().replaceAll("\"", ""));
return Lists.newArrayList(Iterables.transform(paths, DECODE_PATH_FUNCTION));
}
}
...@@ -21,8 +21,6 @@ public class App { ...@@ -21,8 +21,6 @@ public class App {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ConfigProperties.getInstance().loadProperties(); ConfigProperties.getInstance().loadProperties();
// for testing
Thread.sleep(10000);
// load rest server parameters // load rest server parameters
Long port = (Long) ConfigProperties.getInstance().addConfigurationPropertyToHash("server.port","9090", EnumPropertyType.E_LONG); Long port = (Long) ConfigProperties.getInstance().addConfigurationPropertyToHash("server.port","9090", EnumPropertyType.E_LONG);
String host = (String) ConfigProperties.getInstance().addConfigurationPropertyToHash("server.host","localhost", EnumPropertyType.E_STRING); String host = (String) ConfigProperties.getInstance().addConfigurationPropertyToHash("server.host","localhost", EnumPropertyType.E_STRING);
......
...@@ -30,7 +30,7 @@ public class TestHttpAdapter { ...@@ -30,7 +30,7 @@ public class TestHttpAdapter {
} }
// /opt/mcx/config/ge.parking.json (No such file or directory) // /opt/mcx/config/ge.parking.zjsonpatch (No such file or directory)
@Test @Test
public void loadAdapterModel(){ public void loadAdapterModel(){
AdapterModel<HttpFlow> model; AdapterModel<HttpFlow> model;
......
...@@ -7,6 +7,9 @@ import util.Utils; ...@@ -7,6 +7,9 @@ import util.Utils;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.function.Function;
import java.util.function.IntSupplier;
import java.util.function.Supplier;
/** /**
...@@ -19,7 +22,7 @@ public class TestJson { ...@@ -19,7 +22,7 @@ public class TestJson {
// { // {
// JsonNode jsonNode = null; // JsonNode jsonNode = null;
// try { // try {
// jsonNode = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/testJson.json"); // jsonNode = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/testJson.zjsonpatch");
// } catch (IOException e) { // } catch (IOException e) {
// e.printStackTrace(); // e.printStackTrace();
// } // }
...@@ -45,7 +48,7 @@ public class TestJson { ...@@ -45,7 +48,7 @@ public class TestJson {
{ {
JsonNode jsonNode = null; JsonNode jsonNode = null;
try { try {
jsonNode = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/adapter.ge.parking.json"); jsonNode = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/adapter.ge.parking.zjsonpatch");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
...@@ -70,14 +73,28 @@ public class TestJson { ...@@ -70,14 +73,28 @@ public class TestJson {
System.out.println(dataFlows.toString()); System.out.println(dataFlows.toString());
} }
@Test
public void testFinal(){
final int x=5;
final String i = ((Supplier<String>)( () -> {
if (x==5)
return "eli";
else
return "amir"; })).get();
System.out.println(i);
}
@Test @Test
public void testSerializeCommon() public void testSerializeCommon()
{ {
JsonNode jsonNode = null; JsonNode jsonNode = null;
try { try {
jsonNode = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/adapter.ge.parking.json"); jsonNode = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/adapter.ge.parking.zjsonpatch");
} catch (IOException e) { } catch (IOException e) {
System.out.println("failed to read json fie, exception: " + e); System.out.println("failed to read jsonpatch file, exception: " + e);
e.printStackTrace(); e.printStackTrace();
} }
// DataModel dataModel = new DataModel(new ArrayList<DataHttpApi>()); // DataModel dataModel = new DataModel(new ArrayList<DataHttpApi>());
......
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonPointer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import org.junit.Test;
import util.Utils;
import java.io.IOException;
/**
* Created by eli on 12/19/16.
*/
public class TestJsonNode {
@Test
public void testJsonNodeAt()
{
JsonPointer pathPointer;
pathPointer = JsonPointer.compile("/_links/self/href");
JsonNode node,transformed;
String toString,asText;
try {
node = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/testParkingSpot.json");
transformed=node.at(pathPointer);
toString=transformed.toString();
asText=transformed.asText();
System.out.println("transformed = "+ transformed);
} catch (IOException e) {
e.printStackTrace();
}
}
}
...@@ -16,7 +16,7 @@ public class TestJsonNodeStream { ...@@ -16,7 +16,7 @@ public class TestJsonNodeStream {
public void testJsonNodeStream(){ public void testJsonNodeStream(){
ArrayNode array = null; ArrayNode array = null;
try { try {
array = (ArrayNode) Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/getLocations_ParkingSpots.json"); array = (ArrayNode) Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/getLocations_ParkingSpots.zjsonpatch");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
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 defs.Constants;
import logic.adapter.normalizer.INormalizer;
import org.junit.Test; import org.junit.Test;
import util.Utils; import util.Utils;
import common.JsonHandler; import util.zjsonpatch.ZJsonPatch;
import java.io.IOException; import java.io.IOException;
...@@ -18,13 +16,13 @@ public class TestJsonPatch { ...@@ -18,13 +16,13 @@ public class TestJsonPatch {
{ {
JsonNode jsonInput = null, jsonInput1=null; JsonNode jsonInput = null, jsonInput1=null;
try { try {
jsonInput = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/OneParkingSpotDetailed.json"); jsonInput = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/OneParkingSpotDetailed.zjsonpatch");
jsonInput1 = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/parkingSpotJsonPatch.json"); jsonInput1 = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/parkingSpotJsonPatch.zjsonpatch");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
// JsonNode jsonPatch = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/jsonPatchExtractString.json"); // JsonNode jsonPatch = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/jsonPatchExtractString.zjsonpatch");
// JsonNode jsonTarget = JsonPatch.apply(jsonPatch, jsonInput); // JsonNode jsonTarget = ZJsonPatch.apply(jsonPatch, jsonInput);
// String strToNormalize = JsonHandler.getObjectAsJsonString(jsonTarget); // String strToNormalize = JsonHandler.getObjectAsJsonString(jsonTarget);
String str1 = "/_links/self/href"; String str1 = "/_links/self/href";
String str2 = "/_embedded/locations"; String str2 = "/_embedded/locations";
...@@ -49,8 +47,11 @@ public class TestJsonPatch { ...@@ -49,8 +47,11 @@ public class TestJsonPatch {
@Test @Test
public void convertWithJsonPatch() public void convertWithJsonPatch()
{ {
String inputFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/OneParkingSpotDetailed.json"; // String inputFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/OneParkingSpotDetailed.zjsonpatch";
String patchFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/parkingSpotJsonPatch.json"; // String patchFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/parkingSpotJsonPatch.zjsonpatch";
String inputFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/allParkingSpotsGE.zjsonpatch";
String patchFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/jsonPatchExtractArray.zjsonpatch";
JsonNode jsonTransformed; JsonNode jsonTransformed;
try { try {
...@@ -72,7 +73,7 @@ public class TestJsonPatch { ...@@ -72,7 +73,7 @@ public class TestJsonPatch {
System.out.println(patch); System.out.println(patch);
System.out.println(textPatch); System.out.println(textPatch);
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;
} }
......
...@@ -12,7 +12,7 @@ public class TestReadJsonFile { ...@@ -12,7 +12,7 @@ public class TestReadJsonFile {
public void testReadJsonFile() public void testReadJsonFile()
{ {
try { try {
JsonNode jsonNode = Utils.readJsonNodeFromFile("/opt/mcx/config/mde/adapters.json"); JsonNode jsonNode = Utils.readJsonNodeFromFile("/opt/mcx/config/mde/adapters.zjsonpatch");
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
<?xml version="1.0" encoding="UTF-8"?><testrun duration="7098" footerText="Generated by IntelliJ IDEA on 12/11/16 9:59 AM" name="TestAES.runTest">
<count name="total" value="1"/>
<count name="passed" value="1"/>
<config nameIsGenerated="true" configId="JUnit" name="TestAES.runTest">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea">
<pattern>
<option name="PATTERN" value="aes128Algorithm.*"/>
<option name="ENABLED" value="true"/>
</pattern>
</extension>
<module name="mde_test"/>
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false"/>
<option name="ALTERNATIVE_JRE_PATH"/>
<option name="PACKAGE_NAME" value="aes128Algorithm"/>
<option name="MAIN_CLASS_NAME" value="aes128Algorithm.TestAES"/>
<option name="METHOD_NAME" value="runTest"/>
<option name="TEST_OBJECT" value="method"/>
<option name="VM_PARAMETERS" value="-ea"/>
<option name="PARAMETERS"/>
<option name="WORKING_DIRECTORY" value="file:///home/eli/git/ipgallery/java/mde"/>
<option name="ENV_VARIABLES"/>
<option name="PASS_PARENT_ENVS" value="true"/>
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule"/>
</option>
<envs/>
<patterns/>
</config>
<root name="TestAES" comment="aes128Algorithm" location="java:suite://aes128Algorithm.TestAES"/>
<test duration="7098" locationUrl="java:test://aes128Algorithm.TestAES.runTest" name="TestAES.runTest" status="passed">
<output type="stdout">runTest AES-128
start time: 2016-12-11T07:54:38.047
encryption #0current time: 2016-12-11T07:54:38.885
encryption #2000current time: 2016-12-11T07:54:39.551
encryption #4000current time: 2016-12-11T07:54:39.784
encryption #6000current time: 2016-12-11T07:54:39.965
encryption #8000current time: 2016-12-11T07:54:40.134
encryption #10000current time: 2016-12-11T07:54:40.295
encryption #12000current time: 2016-12-11T07:54:40.339
encryption #14000current time: 2016-12-11T07:54:40.376
encryption #16000current time: 2016-12-11T07:54:40.400
encryption #18000current time: 2016-12-11T07:54:40.425
encryption #20000current time: 2016-12-11T07:54:40.713
encryption #22000current time: 2016-12-11T07:54:40.944
encryption #24000current time: 2016-12-11T07:54:41.344
encryption #26000current time: 2016-12-11T07:54:41.408
encryption #28000current time: 2016-12-11T07:54:41.476
encryption #30000current time: 2016-12-11T07:54:41.526
encryption #32000current time: 2016-12-11T07:54:41.636
encryption #34000current time: 2016-12-11T07:54:41.684
encryption #36000current time: 2016-12-11T07:54:41.722
encryption #38000current time: 2016-12-11T07:54:41.772
encryption #40000current time: 2016-12-11T07:54:41.817
encryption #42000current time: 2016-12-11T07:54:41.898
encryption #44000current time: 2016-12-11T07:54:42.033
encryption #46000current time: 2016-12-11T07:54:42.118
encryption #48000current time: 2016-12-11T07:54:42.213
encryption #50000current time: 2016-12-11T07:54:42.305
encryption #52000current time: 2016-12-11T07:54:42.410
encryption #54000current time: 2016-12-11T07:54:42.465
encryption #56000current time: 2016-12-11T07:54:42.511
encryption #58000current time: 2016-12-11T07:54:42.568
encryption #60000current time: 2016-12-11T07:54:42.616
encryption #62000current time: 2016-12-11T07:54:42.667
encryption #64000current time: 2016-12-11T07:54:42.722
encryption #66000current time: 2016-12-11T07:54:42.788
encryption #68000current time: 2016-12-11T07:54:42.846
encryption #70000current time: 2016-12-11T07:54:42.900
encryption #72000current time: 2016-12-11T07:54:42.967
encryption #74000current time: 2016-12-11T07:54:43.018
encryption #76000current time: 2016-12-11T07:54:43.064
encryption #78000current time: 2016-12-11T07:54:43.122
encryption #80000current time: 2016-12-11T07:54:43.179
encryption #82000current time: 2016-12-11T07:54:43.198
encryption #84000current time: 2016-12-11T07:54:43.217
encryption #86000current time: 2016-12-11T07:54:43.237
encryption #88000current time: 2016-12-11T07:54:43.256
encryption #90000current time: 2016-12-11T07:54:43.426
encryption #92000current time: 2016-12-11T07:54:43.489
encryption #94000current time: 2016-12-11T07:54:43.536
encryption #96000current time: 2016-12-11T07:54:43.586
encryption #98000current time: 2016-12-11T07:54:43.634
time after 100000 encryptions: 2016-12-11T07:54:43.674
decryption #0current time: 2016-12-11T07:54:43.675
decryption #2000current time: 2016-12-11T07:54:43.781
decryption #4000current time: 2016-12-11T07:54:43.872
decryption #6000current time: 2016-12-11T07:54:43.946
decryption #8000current time: 2016-12-11T07:54:44.041
decryption #10000current time: 2016-12-11T07:54:44.084
decryption #12000current time: 2016-12-11T07:54:44.110
decryption #14000current time: 2016-12-11T07:54:44.133
decryption #16000current time: 2016-12-11T07:54:44.155
decryption #18000current time: 2016-12-11T07:54:44.179
decryption #20000current time: 2016-12-11T07:54:44.201
decryption #22000current time: 2016-12-11T07:54:44.223
decryption #24000current time: 2016-12-11T07:54:44.245
decryption #26000current time: 2016-12-11T07:54:44.268
decryption #28000current time: 2016-12-11T07:54:44.291
decryption #30000current time: 2016-12-11T07:54:44.313
decryption #32000current time: 2016-12-11T07:54:44.336
decryption #34000current time: 2016-12-11T07:54:44.359
decryption #36000current time: 2016-12-11T07:54:44.385
decryption #38000current time: 2016-12-11T07:54:44.411
decryption #40000current time: 2016-12-11T07:54:44.434
decryption #42000current time: 2016-12-11T07:54:44.457
decryption #44000current time: 2016-12-11T07:54:44.480
decryption #46000current time: 2016-12-11T07:54:44.504
decryption #48000current time: 2016-12-11T07:54:44.527
decryption #50000current time: 2016-12-11T07:54:44.550
decryption #52000current time: 2016-12-11T07:54:44.573
decryption #54000current time: 2016-12-11T07:54:44.649
decryption #56000current time: 2016-12-11T07:54:44.673
decryption #58000current time: 2016-12-11T07:54:44.697
decryption #60000current time: 2016-12-11T07:54:44.723
decryption #62000current time: 2016-12-11T07:54:44.744
decryption #64000current time: 2016-12-11T07:54:44.764
decryption #66000current time: 2016-12-11T07:54:44.785
decryption #68000current time: 2016-12-11T07:54:44.805
decryption #70000current time: 2016-12-11T07:54:44.825
decryption #72000current time: 2016-12-11T07:54:44.845
decryption #74000current time: 2016-12-11T07:54:44.866
decryption #76000current time: 2016-12-11T07:54:44.886
decryption #78000current time: 2016-12-11T07:54:44.906
decryption #80000current time: 2016-12-11T07:54:44.928
decryption #82000current time: 2016-12-11T07:54:44.950
decryption #84000current time: 2016-12-11T07:54:44.970
decryption #86000current time: 2016-12-11T07:54:44.991
decryption #88000current time: 2016-12-11T07:54:45.011
decryption #90000current time: 2016-12-11T07:54:45.031
decryption #92000current time: 2016-12-11T07:54:45.052
decryption #94000current time: 2016-12-11T07:54:45.072
decryption #96000current time: 2016-12-11T07:54:45.092
decryption #98000current time: 2016-12-11T07:54:45.117
time after 100000 decryptions: 2016-12-11T07:54:45.138
time after 100000 decryptions: 2016-12-11T07:54:45.138
Plain Text : AmirAharon
Encrypted Text : 4y2NpzhAFXf0Gw5B5qP5oA==
Decrypted Text : AmirAharon
</output>
</test>
</testrun>
package aes128Algorithm;
import com.google.api.client.util.DateTime;
import org.junit.Test;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.util.Date;
/**
* Created by eli on 12/8/16.
*/
public class TestAES {
// package com.simplecode.action;
//
// import java.security.Key;
//
// import javax.crypto.Cipher;
// import javax.crypto.spec.SecretKeySpec;
//
// import sun.misc.*;
// static Key key1;
static Cipher chiper1;
static Cipher chiper2;
private static String currentDate() {
Date date = new Date(System.currentTimeMillis());
DateTime dateTime = new DateTime(date);
return dateTime.toStringRfc3339();
}
private static String algorithm = "AES";
private static byte[] keyValue=new byte[]
{ 'A', 'S', 'e', 'c', 'u', 'r', 'e', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };
// Performs Encryption
public static String encrypt(String plainText) throws Exception
{
Key key = generateKey();
Cipher chiper = Cipher.getInstance(algorithm);
chiper.init(Cipher.ENCRYPT_MODE, key);
byte[] encVal = chiper.doFinal(plainText.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
public static String encrypt1(String plainText) throws Exception
{
byte[] encVal = chiper1.doFinal(plainText.getBytes());
String encryptedValue = new BASE64Encoder().encode(encVal);
return encryptedValue;
}
// Performs decryption
public static String decrypt(String encryptedText) throws Exception
{
// generate key
Key key = generateKey();
Cipher chiper = Cipher.getInstance(algorithm);
chiper.init(Cipher.DECRYPT_MODE, key);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedText);
byte[] decValue = chiper.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
public static String decrypt1(String encryptedText) throws Exception
{
// generate key
byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedText);
byte[] decValue = chiper2.doFinal(decordedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
//generateKey() is used to generate a secret key for AES algorithm
private static Key generateKey() throws Exception
{
Key key = new SecretKeySpec(keyValue, algorithm);
return key;
}
@Test
public void runTest2()
{
try {
Key key1;
key1 = generateKey();
chiper1 = Cipher.getInstance(algorithm);
chiper1.init(Cipher.ENCRYPT_MODE, key1);
chiper2 = Cipher.getInstance(algorithm);
chiper2.init(Cipher.DECRYPT_MODE, key1);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("runTest AES-128");
String plainText = "AmirAharon";
String encryptedText = null;
String decryptedText = null;
System.out.println("start time: "+currentDate());
try {
int i;
for (i=0; i<100000; i++){
encryptedText = TestAES.encrypt1(plainText);
if (i%2000 == 0)
System.out.println("encryption #"+i+ "current time: "+currentDate());
}
System.out.println("time after 100000 encryptions: "+currentDate());
for (i=0; i<100000; i++) {
decryptedText = TestAES.decrypt1(encryptedText);
if (i%2000 == 0)
System.out.println("decryption #"+i+ "current time: "+currentDate());
}
System.out.println("time after 100000 decryptions: "+currentDate());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("time after 100000 decryptions: "+currentDate());
System.out.println("Plain Text : " + plainText);
System.out.println("Encrypted Text : " + encryptedText);
System.out.println("Decrypted Text : " + decryptedText);
}
@Test
public void runTest1()
{
System.out.println("runTest AES-128");
String plainText = "AmirAharon";
String encryptedText = null;
String decryptedText = null;
System.out.println("start time: "+currentDate());
try {
int i;
for (i=0; i<100000; i++){
encryptedText = TestAES.encrypt(plainText);
if (i%2000 == 0)
System.out.println("encryption #"+i+ "current time: "+currentDate());
}
System.out.println("time after 100000 encryptions: "+currentDate());
for (i=0; i<100000; i++) {
decryptedText = TestAES.decrypt(encryptedText);
if (i%2000 == 0)
System.out.println("decryption #"+i+ "current time: "+currentDate());
}
System.out.println("time after 100000 decryptions: "+currentDate());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("time after 100000 decryptions: "+currentDate());
System.out.println("Plain Text : " + plainText);
System.out.println("Encrypted Text : " + encryptedText);
System.out.println("Decrypted Text : " + decryptedText);
}
}
//package testJsonPatch;
//
//
//import com.fasterxml.jackson.core.JsonPointer;
//import com.fasterxml.jackson.databind.JsonNode;
//import com.github.fge.jsonpatch.JsonPatch;
//import org.junit.Test;
//import util.Utils;
//
//import java.io.IOException;
//
///**
// * Created by eli on 12/12/16.
// */
//public class Testgithub_fge_jsonpatchJsonPatch {
// @Test
// public void testJsonPatch()
// {
// JsonNode jsonInput = null, jsonInput1=null;
// try {
// jsonInput = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/OneParkingSpotDetailed.zjsonpatch");
// jsonInput1 = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/parkingSpotJsonPatch.zjsonpatch");
// } catch (IOException e) {
// e.printStackTrace();
// }
//// JsonNode jsonPatch = Utils.readJsonNodeFromFile("/home/eli/git/ipgallery/java/mde/cfg/Myfiles/jsonPatchExtractString.zjsonpatch");
//// JsonNode jsonTarget = ZJsonPatch.apply(jsonPatch, jsonInput);
//// String strToNormalize = JsonHandler.getObjectAsJsonString(jsonTarget);
// String str1 = "/_links/self/href";
// String str2 = "/_embedded/locations";
// JsonPointer jsonPointer1 = JsonPointer.compile(str1);
// JsonPointer jsonPointer2 = JsonPointer.compile(str2);
// JsonNode value = jsonInput.at(jsonPointer1);
// if (value != null){
// if (value.isTextual())
// System.out.println("textual" + value.asText());
// else if (value.isArray())
// System.out.println("textual" + value.asText());
// }
// JsonNode value1 = jsonInput1.at(jsonPointer2);
// if (value1 != null){
// if (value1.isTextual())
// System.out.println("textual" + value1.asText());
// else if (value1.isArray())
// System.out.println("Array" + value1.asText());
// }
//// System.out.println(strToNormalize);
// }
// @Test
// public void convertWithJsonPatch()
// {
//// String inputFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/OneParkingSpotDetailed.zjsonpatch";
//// String patchFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/parkingSpotJsonPatch.zjsonpatch";
// String inputFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/allParkingSpotsGE.zjsonpatch";
// String patchFile="/home/eli/git/ipgallery/java/mde/cfg/Myfiles/jsonPatchExtractArray.zjsonpatch";
//
//
// JsonNode jsonTransformed;
// try {
// jsonTransformed=jsonPatchApply(patchFile,inputFile);
//
// } catch (IOException e) {
// e.printStackTrace();
// }
//
// }
//
//
//
// private JsonNode jsonPatchApply(String jsonPatchfile, String jsonInputfile ) throws IOException {
// JsonNode jsonPatch = Utils.readJsonNodeFromFile(jsonPatchfile);
// JsonNode jsonInput = Utils.readJsonNodeFromFile(jsonInputfile);
// String patch = jsonPatch.toString();
// String textPatch = jsonPatch.asText();
// System.out.println(patch);
// System.out.println(textPatch);
// if (jsonPatch!=null && !jsonPatch.isNull() && jsonInput!=null && !jsonInput.isNull()){
// return JsonPatch.apply(jsonPatch, jsonInput);
// }
// return null;
// }
//
//
//
//
//
//
//
//}
package testOauth2Client; //package testOauth2Client;
//
//
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;
import com.google.api.client.auth.oauth2.*; //import com.google.api.client.auth.oauth2.*;
//import com.google.api.client.http.*; ////import com.google.api.client.http.*;
import com.google.api.client.http.javanet.NetHttpTransport; //import com.google.api.client.http.javanet.NetHttpTransport;
//import com.google.api.client.json.JsonFactory; ////import com.google.api.client.zjsonpatch.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory; //import com.google.api.client.json.jackson.JacksonFactory;
import common.JsonHandler; //import common.JsonHandler;
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 http.simpleRestClient.SimpleRestClient; //import http.simpleRestClient.SimpleRestClient;
import org.apache.http.HttpResponse; //import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair; //import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException; //import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient; //import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity; //import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost; //import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient; //import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair; //import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException; //import org.json.JSONException;
import org.junit.Test; //import org.junit.Test;
import util.MDEResult; //import util.MDEResult;
import util.Utils; //import util.Utils;
//
//
import java.io.IOException; //import java.io.IOException;
import java.io.UnsupportedEncodingException; //import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; //import java.math.BigDecimal;
import java.util.ArrayList; //import java.util.ArrayList;
import java.util.Base64; //import java.util.Base64;
import java.util.Collections; //import java.util.Collections;
import java.util.List; //import java.util.List;
//
/** ///**
* Created by eli on 10/30/16. // * Created by eli on 10/30/16.
*/ // */
public class TestGoogleOauth2Client { //public class TestGoogleOauth2Client {
static String UAA_SERVER = "https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token"; // static String UAA_SERVER = "https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token";
static String UAA_DOMAIN = "9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token"; // static String UAA_DOMAIN = "9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token";
@JsonInclude(JsonInclude.Include.NON_NULL) // @JsonInclude(JsonInclude.Include.NON_NULL)
@JsonPropertyOrder({ // @JsonPropertyOrder({
"access_token", // "access_token",
"token_type", // "token_type",
"expires_in", // "expires_in",
"scope", // "scope",
"jti" // "jti"
}) // })
private static class CredentialResponse { // private static class CredentialResponse {
private String token; // private String token;
private String tokenType; // private String tokenType;
private Integer expiresInSec; // private Integer expiresInSec;
private String scope; // private String scope;
private String jti; // private String jti;
//
@JsonProperty("access_token") // @JsonProperty("access_token")
public String getToken() { return token;} // public String getToken() { return token;}
public void setToken(String token) {this.token = token;} // public void setToken(String token) {this.token = token;}
//
@JsonProperty("token_type") // @JsonProperty("token_type")
public String getTokenType() { return tokenType;} // public String getTokenType() { return tokenType;}
public void setTokenType(String tokenType) { this.tokenType = tokenType; } // public void setTokenType(String tokenType) { this.tokenType = tokenType; }
//
@JsonProperty("expires_in") // @JsonProperty("expires_in")
public Integer getExpiresInSec() {return expiresInSec;} // public Integer getExpiresInSec() {return expiresInSec;}
public void setExpiresInSec(Integer expiresInSec) {this.expiresInSec = expiresInSec;} // public void setExpiresInSec(Integer expiresInSec) {this.expiresInSec = expiresInSec;}
//
@JsonProperty("scope") // @JsonProperty("scope")
public String getScope() { // public String getScope() {
return scope; // return scope;
} // }
public void setScope(String scope) {this.scope = scope;} // public void setScope(String scope) {this.scope = scope;}
//
@JsonProperty("jti") // @JsonProperty("jti")
public String getJti() { // public String getJti() {
return jti; // return jti;
} // }
public void setJti(String jti) {this.jti = jti;} // public void setJti(String jti) {this.jti = jti;}
//
//
} // }
//
// "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiJjMTBjNDA0YTJkNTg0NjEzYjgzYjZmMGVlMWNhMmI5MyIsInN1YiI6ImlwZ2FsbGVyeSIsInNjb3BlIjpbInVhYS5yZXNvdXJjZSIsImllLXBhcmtpbmcuem9uZXMuYzU0ZTNlNjMtOGRjNi00MjVlLWE1MzMtNjRlMDYxZjY0MDIzLnVzZXIiLCJvcGVuaWQiLCJ1YWEubm9uZSIsImllLXRyYWZmaWMuem9uZXMuYjZmYzIyYjYtYWQ3MS00MjNlLTg2N2ItYTFiMTk3ZjZjZmMyLnVzZXIiLCJpZS1wdWJsaWMtc2FmZXR5LnpvbmVzLjY4YjhkNjM5LWNjMzktNDcwOS05NTJlLTMyN2M5YzIwNzEyYS51c2VyIiwiaWUtcGVkZXN0cmlhbi56b25lcy5jMWUwMTJkMy02NTNmLTRmNzEtYjAzZC03NjgxMGRiOGQ0OGUudXNlciJdLCJjbGllbnRfaWQiOiJpcGdhbGxlcnkiLCJjaWQiOiJpcGdhbGxlcnkiLCJhenAiOiJpcGdhbGxlcnkiLCJncmFudF90eXBlIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwicmV2X3NpZyI6IjdjODlkYjBjIiwiaWF0IjoxNDc4NDM3MzQ4LCJleHAiOjE0Nzg0ODA1NDgsImlzcyI6Imh0dHBzOi8vOWRlYWNjNjQtN2M1My00NzkwLTlhNmMtYzlkZTBmZGViY2RmLnByZWRpeC11YWEucnVuLmF3cy11c3cwMi1wci5pY2UucHJlZGl4LmlvL29hdXRoL3Rva2VuIiwiemlkIjoiOWRlYWNjNjQtN2M1My00NzkwLTlhNmMtYzlkZTBmZGViY2RmIiwiYXVkIjpbInVhYSIsImllLXBhcmtpbmcuem9uZXMuYzU0ZTNlNjMtOGRjNi00MjVlLWE1MzMtNjRlMDYxZjY0MDIzIiwib3BlbmlkIiwiaWUtdHJhZmZpYy56b25lcy5iNmZjMjJiNi1hZDcxLTQyM2UtODY3Yi1hMWIxOTdmNmNmYzIiLCJpcGdhbGxlcnkiLCJpZS1wZWRlc3RyaWFuLnpvbmVzLmMxZTAxMmQzLTY1M2YtNGY3MS1iMDNkLTc2ODEwZGI4ZDQ4ZSIsImllLXB1YmxpYy1zYWZldHkuem9uZXMuNjhiOGQ2MzktY2MzOS00NzA5LTk1MmUtMzI3YzljMjA3MTJhIl19.UkmGVfjCb6H-hcV-H-enG4osGCamS0vE6SGMYBjQWwyJitWO90KKNaDRA_GO2s66mqFU7oa89wmO6b35U5OGdcxhC3mJiH7PTDFWmE3JCjbyG0xAcHmZjalP48aFPhEqy5FX66ghCrlKsuTS4v_Dqf4YcaQTR3lGT3oc21794Hl92Pkmec55WCXN4OU_OqjY2bs7PQwBxJSQ109xOZJXiBc-aKk2qpdC7wfDO8Vk92rJGRClBRDoyINlkPO5Wd2nUmVX4Cx8dJEs76aca5DXgcGVAEroGhOdjWal9Qgu8NXpxgtJcWCOT6FTSKvv4_Hsxw7w5jSOXVs2TWKP5P7liQ", //// "access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImxlZ2FjeS10b2tlbi1rZXkiLCJ0eXAiOiJKV1QifQ.eyJqdGkiOiJjMTBjNDA0YTJkNTg0NjEzYjgzYjZmMGVlMWNhMmI5MyIsInN1YiI6ImlwZ2FsbGVyeSIsInNjb3BlIjpbInVhYS5yZXNvdXJjZSIsImllLXBhcmtpbmcuem9uZXMuYzU0ZTNlNjMtOGRjNi00MjVlLWE1MzMtNjRlMDYxZjY0MDIzLnVzZXIiLCJvcGVuaWQiLCJ1YWEubm9uZSIsImllLXRyYWZmaWMuem9uZXMuYjZmYzIyYjYtYWQ3MS00MjNlLTg2N2ItYTFiMTk3ZjZjZmMyLnVzZXIiLCJpZS1wdWJsaWMtc2FmZXR5LnpvbmVzLjY4YjhkNjM5LWNjMzktNDcwOS05NTJlLTMyN2M5YzIwNzEyYS51c2VyIiwiaWUtcGVkZXN0cmlhbi56b25lcy5jMWUwMTJkMy02NTNmLTRmNzEtYjAzZC03NjgxMGRiOGQ0OGUudXNlciJdLCJjbGllbnRfaWQiOiJpcGdhbGxlcnkiLCJjaWQiOiJpcGdhbGxlcnkiLCJhenAiOiJpcGdhbGxlcnkiLCJncmFudF90eXBlIjoiY2xpZW50X2NyZWRlbnRpYWxzIiwicmV2X3NpZyI6IjdjODlkYjBjIiwiaWF0IjoxNDc4NDM3MzQ4LCJleHAiOjE0Nzg0ODA1NDgsImlzcyI6Imh0dHBzOi8vOWRlYWNjNjQtN2M1My00NzkwLTlhNmMtYzlkZTBmZGViY2RmLnByZWRpeC11YWEucnVuLmF3cy11c3cwMi1wci5pY2UucHJlZGl4LmlvL29hdXRoL3Rva2VuIiwiemlkIjoiOWRlYWNjNjQtN2M1My00NzkwLTlhNmMtYzlkZTBmZGViY2RmIiwiYXVkIjpbInVhYSIsImllLXBhcmtpbmcuem9uZXMuYzU0ZTNlNjMtOGRjNi00MjVlLWE1MzMtNjRlMDYxZjY0MDIzIiwib3BlbmlkIiwiaWUtdHJhZmZpYy56b25lcy5iNmZjMjJiNi1hZDcxLTQyM2UtODY3Yi1hMWIxOTdmNmNmYzIiLCJpcGdhbGxlcnkiLCJpZS1wZWRlc3RyaWFuLnpvbmVzLmMxZTAxMmQzLTY1M2YtNGY3MS1iMDNkLTc2ODEwZGI4ZDQ4ZSIsImllLXB1YmxpYy1zYWZldHkuem9uZXMuNjhiOGQ2MzktY2MzOS00NzA5LTk1MmUtMzI3YzljMjA3MTJhIl19.UkmGVfjCb6H-hcV-H-enG4osGCamS0vE6SGMYBjQWwyJitWO90KKNaDRA_GO2s66mqFU7oa89wmO6b35U5OGdcxhC3mJiH7PTDFWmE3JCjbyG0xAcHmZjalP48aFPhEqy5FX66ghCrlKsuTS4v_Dqf4YcaQTR3lGT3oc21794Hl92Pkmec55WCXN4OU_OqjY2bs7PQwBxJSQ109xOZJXiBc-aKk2qpdC7wfDO8Vk92rJGRClBRDoyINlkPO5Wd2nUmVX4Cx8dJEs76aca5DXgcGVAEroGhOdjWal9Qgu8NXpxgtJcWCOT6FTSKvv4_Hsxw7w5jSOXVs2TWKP5P7liQ",
// "token_type": "bearer", //// "token_type": "bearer",
// "expires_in": 43199, //// "expires_in": 43199,
// "scope": "uaa.resource ie-parking.zones.c54e3e63-8dc6-425e-a533-64e061f64023.user openid uaa.none ie-traffic.zones.b6fc22b6-ad71-423e-867b-a1b197f6cfc2.user ie-public-safety.zones.68b8d639-cc39-4709-952e-327c9c20712a.user ie-pedestrian.zones.c1e012d3-653f-4f71-b03d-76810db8d48e.user", //// "scope": "uaa.resource ie-parking.zones.c54e3e63-8dc6-425e-a533-64e061f64023.user openid uaa.none ie-traffic.zones.b6fc22b6-ad71-423e-867b-a1b197f6cfc2.user ie-public-safety.zones.68b8d639-cc39-4709-952e-327c9c20712a.user ie-pedestrian.zones.c1e012d3-653f-4f71-b03d-76810db8d48e.user",
// "jti": "c10c404 //// "jti": "c10c404
//
//
// JsonFactory jsonFactory = new JacksonFactory(); // // JsonFactory jsonFactory = new JacksonFactory();
// HttpTransport httpTransport = new NetHttpTransport(); //// HttpTransport httpTransport = new NetHttpTransport();
// ////
// AuthorizationCodeFlow flow = new AuthorizationCodeFlow.Builder( //// AuthorizationCodeFlow flow = new AuthorizationCodeFlow.Builder(
// BearerToken.authorizationHeaderAccessMethod(), //// BearerToken.authorizationHeaderAccessMethod(),
// httpTransport, jsonFactory, //// httpTransport, jsonFactory,
// new GenericUrl("https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token?grant_type=client_credentials"), //// new GenericUrl("https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token?grant_type=client_credentials"),
// new ClientParametersAuthentication("ipgallery" ,"1PGall3ry") //// new ClientParametersAuthentication("ipgallery" ,"1PGall3ry")
// "https://github.com/login/oauth/authorize").build(); //// "https://github.com/login/oauth/authorize").build();
// ////
// TokenResponse tokenResponse = flow //// TokenResponse tokenResponse = flow
// .newTokenRequest(code) //// .newTokenRequest(code)
// .setScopes(Collections.singletonList("user:email")) //// .setScopes(Collections.singletonList("user:email"))
// .setRequestInitializer(new HttpRequestInitializer() { //// .setRequestInitializer(new HttpRequestInitializer() {
// @Override //// @Override
// public void initialize(HttpRequest request) throws IOException { //// public void initialize(HttpRequest request) throws IOException {
// request.getHeaders().setAccept("application/json"); //// request.getHeaders().setAccept("application/zjsonpatch");
// } //// }
// }).execute(); //// }).execute();
//
//
@Test // @Test
public void testSimpleClient() // public void testSimpleClient()
{ // {
SimpleHttpClient httpClient = new SimpleHttpClient(); // SimpleHttpClient httpClient = new SimpleHttpClient();
httpClient.Initialize(100);
SimpleHttpRequest request = new SimpleHttpRequest();
request.setProtocol("https");
request.setMethod(SimpleHttpRequest.Method.POST);
request.setDomain(UAA_DOMAIN);
request.addHeader("Pragma", "no-cache");
request.addHeader("content-type", "application/x-www-form-urlencoded");
request.addHeader("Cache-Control", "no-cache");
String str = new String("ipgallery:1PGall3ry");
byte[] encodedBytes = Base64.getEncoder().encode(str.getBytes());
String authorization = "Basic " + new String(encodedBytes);
request.addHeader("Authorization", authorization);
request.setContent("client_id=ipgallery&grant_type=client_credentials");
SimpleHttpResponse httpResp = null;
try {
httpResp = httpClient.processRequest(request);
if (httpResp.getStatusCode() == 401) {
System.out.println("401 unauthorized");
}
else if (httpResp.getStatusCode() == 200) {
System.out.println("200 ok: parse access_token");
parseContent(httpResp.getContent());
}
else
System.out.println("status code is: " + httpResp.getStatusCode());
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
}
private void parseContent(String content) {
// CredentialResponse tokenResp = (CredentialResponse) Utils.readObjectFromString1(content, CredentialResponse.class);
// System.out.println(tokenResp.toString());
}
@Test
public void test() {
// try {
SimpleHttpClient httpClient = new SimpleHttpClient();
// httpClient.Initialize(100); // httpClient.Initialize(100);
// SimpleHttpRequest request = new SimpleHttpRequest();
// curl 'https://your-uaa-instance.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token' //
// -H 'Pragma: no-cache' -H 'content-type: application/x-www-form-urlencoded' -H // request.setProtocol("https");
// 'Cache-Control: no-cache' -H 'authorization: Basic aXBnYWxsZXJ5OjFQR2FsbDNyeQ==' // request.setMethod(SimpleHttpRequest.Method.POST);
// --data 'client_id=ipgallery&grant_type=client_credentials' // request.setDomain(UAA_DOMAIN);
// request.addHeader("Pragma", "no-cache");
// request.addHeader("content-type", "application/x-www-form-urlencoded");
// request.addHeader("Cache-Control", "no-cache");
// String str = new String("ipgallery:1PGall3ry");
// byte[] encodedBytes = Base64.getEncoder().encode(str.getBytes());
// String authorization = "Basic " + new String(encodedBytes);
// request.addHeader("Authorization", authorization);
// request.setContent("client_id=ipgallery&grant_type=client_credentials");
//
//
// SimpleHttpResponse httpResp = null;
// try {
HttpClient httpclient = new DefaultHttpClient(); // httpResp = httpClient.processRequest(request);
HttpPost httppost = new HttpPost(UAA_SERVER); // if (httpResp.getStatusCode() == 401) {
httppost.setHeader("Pragma", "no-cache"); // System.out.println("401 unauthorized");
httppost.setHeader("content-type", "application/x-www-form-urlencoded"); // }
httppost.setHeader("Cache-Control", "no-cache"); // else if (httpResp.getStatusCode() == 200) {
httppost.setHeader("authorization", "Basic aXBnYWxsZXJ5OjFQR2FsbDNyeQ=="); // System.out.println("200 ok: parse access_token");
// parseContent(httpResp.getContent());
try { // }
List<NameValuePair> nameValuePairs = new ArrayList<>(); // else
nameValuePairs.add(new BasicNameValuePair("grant_type", "client_credentials")); // System.out.println("status code is: " + httpResp.getStatusCode());
nameValuePairs.add(new BasicNameValuePair("client_id", "ipgallery")); //
// } catch (UnsupportedEncodingException e1) {
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs)); // e1.printStackTrace();
// }
//
// Execute HTTP Post Request //
HttpResponse response = httpclient.execute(httppost); //
if (response != null) // }
System.out.println("say hi"); //
// JSONObject json_auth = new JSONObject(EntityUtils.toString(response.getEntity())); // private void parseContent(String content) {
// String token = json_auth.getString("access_token"); //// CredentialResponse tokenResp = (CredentialResponse) Utils.readObjectFromString1(content, CredentialResponse.class);
//// System.out.println(tokenResp.toString());
} catch (ClientProtocolException e) { // }
e.printStackTrace(); //
} catch (IOException e) { // @Test
e.printStackTrace(); // public void test() {
} catch (JSONException e) { //// try {
e.printStackTrace(); // SimpleHttpClient httpClient = new SimpleHttpClient();
} //// httpClient.Initialize(100);
//
//// curl 'https://your-uaa-instance.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token'
// SimpleRestClient restClient = new SimpleRestClient("https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/","443"); //// -H 'Pragma: no-cache' -H 'content-type: application/x-www-form-urlencoded' -H
// restClient.post("oauth/token",null,null,"dfgdfg"); //// 'Cache-Control: no-cache' -H 'authorization: Basic aXBnYWxsZXJ5OjFQR2FsbDNyeQ=='
//// --data 'client_id=ipgallery&grant_type=client_credentials'
// TokenResponse response = //
// new ClientCredentialsTokenRequest(new NetHttpTransport(), new JacksonFactory(), //
// new GenericUrl("https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token")).setClientAuthentication( //
// new BasicAuthentication("ipgallery", "1PGall3ry")).execute(); //
// System.out.println(response); //
// } catch (IOException e) { //
// e.printStackTrace(); //
//
//
//
//
//
// HttpClient httpclient = new DefaultHttpClient();
// HttpPost httppost = new HttpPost(UAA_SERVER);
// httppost.setHeader("Pragma", "no-cache");
// httppost.setHeader("content-type", "application/x-www-form-urlencoded");
// httppost.setHeader("Cache-Control", "no-cache");
// httppost.setHeader("authorization", "Basic aXBnYWxsZXJ5OjFQR2FsbDNyeQ==");
//
// try {
// List<NameValuePair> nameValuePairs = new ArrayList<>();
// nameValuePairs.add(new BasicNameValuePair("grant_type", "client_credentials"));
// nameValuePairs.add(new BasicNameValuePair("client_id", "ipgallery"));
//
// httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//
//
// // Execute HTTP Post Request
// HttpResponse response = httpclient.execute(httppost);
// if (response != null)
// System.out.println("say hi");
//// JSONObject json_auth = new JSONObject(EntityUtils.toString(response.getEntity()));
//// String token = json_auth.getString("access_token");
//
// } catch (ClientProtocolException e) {
// e.printStackTrace();
// } catch (IOException e) {
// e.printStackTrace();
// } catch (JSONException e) {
// e.printStackTrace();
// }
//
//
//// SimpleRestClient restClient = new SimpleRestClient("https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/","443");
//// restClient.post("oauth/token",null,null,"dfgdfg");
//
//// TokenResponse response =
//// new ClientCredentialsTokenRequest(new NetHttpTransport(), new JacksonFactory(),
//// new GenericUrl("https://9deacc64-7c53-4790-9a6c-c9de0fdebcdf.predix-uaa.run.aws-usw02-pr.ice.predix.io/oauth/token")).setClientAuthentication(
//// new BasicAuthentication("ipgallery", "1PGall3ry")).execute();
//// System.out.println(response);
//// } catch (IOException e) {
//// e.printStackTrace();
//// }
////}
//
// } // }
//} //}
}
}
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