use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class BuildCQL method buildCQL.
@SuppressWarnings("unchecked")
public String buildCQL() throws UnsupportedEncodingException {
StringBuilder sb = new StringBuilder();
StringBuilder prefix = new StringBuilder();
if (addQuestionMark) {
prefix.append("?");
} else {
prefix.append("&");
}
prefix.append(queryParamName).append("=");
JsonPathParser jpp = new JsonPathParser(r.getBody());
Object o = jpp.getValueAt(pathToExtractFrom);
List<Object> paths = null;
/*if(o instanceof JsonArray){
paths = ((JsonArray)o).getList();
}*/
if (o instanceof List) {
// assume list
paths = (List<Object>) o;
} else {
// single value
paths = new ArrayList<>();
paths.add(o);
}
int size = paths.size();
for (int i = 0; i < size; i++) {
if (paths.get(i) == null) {
continue;
}
sb.append(cqlPath).append(cqlStatementOperator).append(URLEncoder.encode(paths.get(i).toString(), "UTF-8"));
if (i < size - 1) {
sb.append("+").append(operatorBetweenArgs).append("+");
}
}
if (sb.length() > 0) {
return prefix.append(sb.toString()).toString();
}
return "";
}
use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class HttpModuleClient2 method chainedRequest.
/**
* A request that should be used within a thenCompose() completable future call and receive as
* input a Response object from the previous request.
* The chainedRequest will
* 1. callback to the passed in Consumer with the Response of the previous request for handling
* 2. if the passed in Response contains errors - the current request will not be sent and a
* completable future will be returned indicating that the request was not run
* 3. replace placeholder in the url {a.b[0]} with actual values appearing in the json passed in
* by the thenCompose(). For example: passing in:
* http://localhost:9130/users/{users[0].username}
* will look in the passed in json for the value found in the first user in a json array[].username
* NOTE that if a template has a placeholder, and the path indicated in the placeholder does not
* exist in the passed in Response - the current request will not be sent and a completeable future
* with a Response (containing the error) will be returned
* 4. build a cql via values in the passed in json
* 5. Send the request
* @param urlTempate
* @param headers
* @param inheritOkapiHeaders - take all okapi headers in passed in Response and over write / add to this request
* @param cql
* @param processPassedInResponse
* @return
*/
@Override
public Function<Response, CompletableFuture<Response>> chainedRequest(String urlTempate, Map<String, String> headers, boolean inheritOkapiHeaders, boolean cache, BuildCQL cql, Consumer<Response> processPassedInResponse) {
try {
List<String> replace = getTagValues(urlTempate);
return (resp) -> {
// create a new request based on the content of the passed in response (resp)//
try {
// response for errors / exceptions and return accordingly if found//
if (processPassedInResponse != null) {
processPassedInResponse.accept(resp);
}
if (resp.getError() != null || resp.getException() != null) {
CompletableFuture<Response> cf = new CompletableFuture<>();
PreviousRequestException pre = new PreviousRequestException("for template, " + urlTempate);
cf.complete(createResponse(urlTempate, pre));
return cf;
}
int size = replace.size();
String newURL = urlTempate;
if (size > 0) {
JsonPathParser jpp = new JsonPathParser(resp.getBody());
for (int i = 0; i < size; i++) {
String val = (String) jpp.getValueAt(replace.get(i));
if (val == null) {
log.error("Unable to replace {" + replace.get(i) + "} with content from received json result, does the json contain this field? Endpoint: " + resp.endpoint);
PopulateTemplateException pe = new PopulateTemplateException("Missing {" + replace.get(i) + "} value from results received from endpoint " + resp.endpoint);
CompletableFuture<Response> cf = new CompletableFuture<>();
cf.complete(createResponse(urlTempate, pe));
return cf;
}
newURL = urlTempate.replace("{" + replace.get(i) + "}", val);
}
}
if (cql != null) {
cql.setResponse(resp);
}
// call request//
if (inheritOkapiHeaders) {
mergeHeaders(headers, resp.headers, resp.endpoint);
}
return request(newURL, headers, cache, cql);
} catch (Exception e) {
CompletableFuture<Response> cf = new CompletableFuture<>();
cf.complete(createResponse(urlTempate, e));
return cf;
}
};
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class DemoRamlRestTest method postData.
/**
* for POST
*/
private void postData(TestContext context, String url, Buffer buffer, int errorCode, int mode, String contenttype, String tenant, boolean userIdHeader) {
// save stacktrace for async handler
Exception stacktrace = new RuntimeException();
Async async = context.async();
HttpClient client = vertx.createHttpClient();
HttpClientRequest request = null;
if (mode == 0) {
request = client.putAbs(url);
} else if (mode == 1) {
request = client.postAbs(url);
} else {
request = client.deleteAbs(url);
}
request.exceptionHandler(error -> {
async.complete();
context.fail(new RuntimeException(error.getMessage(), stacktrace));
}).handler(response -> {
int statusCode = response.statusCode();
// is it 2XX
log.info(statusCode + ", " + errorCode + " expected status at " + System.currentTimeMillis() + " mode " + mode + " for " + url);
if (statusCode == errorCode) {
if (statusCode == 422) {
String str = response.getHeader("Content-type");
if (str != null && str.contains("application/json")) {
context.assertTrue(true);
} else {
context.fail(new RuntimeException("422 response code should contain a content type header of application/json", stacktrace));
}
} else if (statusCode == 201) {
response.bodyHandler(responseData -> {
String date = (String) new JsonPathParser(responseData.toJsonObject()).getValueAt("metadata.createdDate");
if (date == null && userIdHeader) {
context.fail(new RuntimeException("metaData schema createdDate missing from returned json", stacktrace));
}
});
}
context.assertTrue(true);
} else {
response.bodyHandler(responseData -> {
context.fail(new RuntimeException("got unexpected response code, expected: " + errorCode + ", received code: " + statusCode + " mode " + mode + " for url " + url + "\ndata:" + responseData.toString(), stacktrace));
});
}
if (!async.isCompleted()) {
async.complete();
}
});
request.setChunked(true);
request.putHeader("X-Okapi-Request-Id", "999999999999");
if (tenant != null) {
request.putHeader("x-okapi-tenant", tenant);
}
request.putHeader("Accept", "application/json,text/plain");
if (userIdHeader) {
request.putHeader("X-Okapi-User-Id", "af23adf0-61ba-4887-bf82-956c4aae2260");
}
if (contenttype != null) {
request.putHeader("Content-type", contenttype);
} else {
if (mode == 0 || mode == 2) {
request.putHeader("Content-type", "application/json");
} else {
request.putHeader("Content-type", "multipart/form-data; boundary=MyBoundary");
}
}
if (buffer != null) {
request.write(buffer);
}
request.end();
}
use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class ResponseTest method check.
@Test
public void check() {
JsonObject j1 = null;
JsonObject j2 = null;
try {
j1 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
j2 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
Response test1 = new Response();
test1.setBody(j1);
Response test2 = new Response();
test2.setBody(j2);
// replace value at c.a1 with the value at c.arr[1] and check
JsonPathParser jpp = new JsonPathParser(test1.joinOn("c.a1", test2, "a", "c.arr[1]").getBody());
assertEquals("true", jpp.getValueAt("c.a1.ignore"));
// ///////////////////////////////////////////////////////////
// non existent path creation test - when passing in a Response as the first parameter
// we are asking to use the two response parameters as the values to join on, and then populate
// the response object with a specific value from from the 2nd response parameter
Response testSetNonExistPath1 = new Response();
Response r1 = new Response();
JsonObject j3 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
testSetNonExistPath1.setBody(j3);
// populate r1 with the content from c.arr[1] - this will be the only content in r1
r1.joinOn(testSetNonExistPath1, "c.a1", test2, "a", "c.arr[1]");
assertEquals(new JsonObject("{\"c\":{\"a1\":{\"ignore\":\"true\"}}}").encode(), r1.getBody().encode());
// //////////////////////////////////////////////////////////////
// try to replace value at c.a1 with a value from a non existent field (c.a[5]) with the
// param allowNulls set to false so that the value is not updated
new JsonPathParser(test1.joinOn("c.a1", test2, "a", "c.arr[5]", false).getBody());
assertEquals(jpp.getValueAt("c.a1.ignore"), "true");
// non existent insertField with allowNulls set to true (default)
Response r2 = new Response();
r2.setBody(j1);
assertNull(new JsonPathParser(r2.joinOn("c.a1", test2, "a", "c.arr[5]").getBody()).getValueAt("c.a1"));
// //////////////////////////////////////////////////////////////////
// check non existent path
assertNull(jpp.getValueAt("c.a1.ignores!SA"));
// do not allow nulls , so that the c.a9 field which does not exist
// will not be added since the c.arr[5] is null
assertFalse(test1.joinOn("c.a9", test2, "a", "c.arr[5]", false).getBody().getJsonObject("c").containsKey("a9"));
assertTrue(test1.joinOn("c.a9", test2, "a", "c.arr[5]", true).getBody().getJsonObject("c").containsKey("a9"));
// pass all params to joinOn
r2.joinOn("b", test2, "c.arr[0].a2.arr2[1].a30", "c.arr[0].a2.arr2[2].arr3[0]", "a", false);
assertEquals("5", r2.getBody().getJsonObject("a").getString("a32"));
String val = (String) new JsonPathParser(r2.joinOn("b", test2, "c.arr[0].a2.arr2[1].a30", "c.arr[0]", "a", false).getBody()).getValueAt("a.a3");
assertEquals("a23", val);
// one to many join (a json with one object joined with an array of jsons - where the one json
// matches multiple entries in the array.
// json to join on has the same id multiple times with different values for each id.
// match with this json so that all values are inserted as an array
j2 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("joinTest.json"), "UTF-8"));
j1 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
Response resp1 = new Response();
resp1.setBody(j1);
Response resp2 = new Response();
resp2.setBody(j2);
JsonArray arr = (JsonArray) new JsonPathParser(resp1.joinOn("a", resp2, "arr2[*].id", "../a31", "b", false).getBody()).getValueAt("b");
assertEquals(3, arr.size());
// test non existent paths (populate new response with array content) one to many
Response r = new Response();
r.joinOn(resp1, "a", resp2, "arr2[*].id", "../a31", "b", false);
JsonArray arr2 = (JsonArray) new JsonPathParser(r.getBody()).getValueAt("b");
assertEquals(new JsonObject("{\"b\":[\"1\",\"2\",\"3\"]}").encode(), r.getBody().encode());
// ///////////////////////////////////////////////////////////////////////
// test many to many -
// in the case below will create an array of values for every joined match
j2 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("joinTest.json"), "UTF-8"));
j1 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("joinTest.json"), "UTF-8"));
resp1 = new Response();
resp1.setBody(j1);
resp2 = new Response();
resp2.setBody(j2);
JsonObject jo1 = resp1.joinOn("arr2[*].id", resp2, "arr2[*].id", "../a31", "../id", false).getBody();
// will produce (notice that the a31 field value is pushed into the id field for every entry
// {"arr2":[
// {"id":["1","2","3"],"a31":"1"},
// {"id":["1","2","3"],"a31":"2"},
// {"id":["1","2","3"],"a31":"3"},
// {"id":["1","2","3"],"a32":"4"},
// {"id":"4","a31":"4","a32":"5"}
// ]}
System.out.println(jo1.encode());
List<?> listOfVals = (List<?>) new JsonPathParser(jo1).getValueAt("arr2[*].id");
assertEquals(5, listOfVals.size());
assertEquals("4", jo1.getJsonArray("arr2").getJsonObject(4).getString("id"));
// test with numbers / boolean
j2 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
j1 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
resp1 = new Response();
resp1.setBody(j1);
resp2 = new Response();
resp2.setBody(j2);
resp1.joinOn("number", resp2, "number", "boolean", "number", false);
assertTrue(resp1.getBody().getBoolean("number"));
resp1.joinOn("boolean", resp2, "boolean", "number", "number", false);
assertTrue(99 == resp1.getBody().getInteger("number"));
/* j1 = new JsonObject(
IOUtils.toString(JsonPathParser.class.getClassLoader().
getResourceAsStream("compositeTest1.json"), "UTF-8"));*/
// resp2.setBody(j1);
Response r2d2 = new Response();
r2d2.mapFrom(resp1, "c.arr[*]", "compositeUsers.compositeUser", "users", true);
r2d2.joinOn(r2d2, "compositeUsers.compositeUser[*].users.a3", resp1, "c.arr[*].a3", "c.a1", "../../groups", true);
assertNull(new JsonPathParser(r2d2.getBody()).getValueAt("compositeUsers.compositeUser[2].groups"));
Response testMap1 = new Response();
testMap1.mapFrom(resp1, "c.arr[0].a2", "mapped", null, true);
assertEquals("aaa.bbb", new JsonPathParser(testMap1.getBody()).getValueAt("mapped.'aaa.ccc'"));
} catch (Exception e) {
e.printStackTrace();
assertTrue(false);
}
}
use of org.folio.rest.tools.parser.JsonPathParser in project raml-module-builder by folio-org.
the class JsonParserTest method check.
@Test
public void check() {
JsonObject j1 = null;
try {
j1 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("pathTest.json"), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
JsonPathParser jp = new JsonPathParser(j1);
List<StringBuilder> o = jp.getAbsolutePaths("c.arr[*].a2.'aaa.ccc'");
assertEquals(o.size(), 2);
List<StringBuilder> o2 = jp.getAbsolutePaths("c.arr[*].a2.arr2[*]");
assertEquals(o2.size(), 5);
List<StringBuilder> o3 = jp.getAbsolutePaths("c.arr[*].a2.arr2[*].arr3[*]");
assertEquals(o3.size(), 2);
List<StringBuilder> o4 = jp.getAbsolutePaths("c.arr[*]");
assertEquals(o4.size(), 3);
List<StringBuilder> o5 = jp.getAbsolutePaths("c.arr[0].a2.'aaa.ccc'");
assertEquals("c.arr[0].a2.'aaa.ccc'", o5.get(0).toString());
List<StringBuilder> o6 = jp.getAbsolutePaths("c.a1");
assertEquals(o6.size(), 1);
List<StringBuilder> o7 = jp.getAbsolutePaths("c.arr[*].a2.arr2[*].arr3[*].a32");
assertEquals(o7.size(), 2);
// fix
Pairs p = jp.getValueAndParentPair("c.arr[0].a2.'aaa.ccc'");
assertEquals("aaa.bbb", p.getRequestedValue());
assertTrue(((JsonObject) p.getRootNode()).containsKey("a"));
Pairs p2 = jp.getValueAndParentPair("c.arr[3].a2.arr2[2].arr3[1]");
assertNull(p2);
Pairs p3 = jp.getValueAndParentPair("c.arr[0]");
assertEquals(p3.getRequestedValue(), jp.getValueAt("c.arr[0]"));
assertEquals("2", ((JsonObject) p3.getRootNode()).getString("b"));
assertEquals(new JsonArray("[{\"a32\":\"5\"}, {\"a32\":\"6\"}]").encode().replace(" ", ""), (new JsonArray(((List) jp.getValueAt("c.arr[*].a2.arr2[*].arr3[*]"))).encode().replaceAll(" ", "")));
String v1 = (String) ((List) jp.getValueAt("c.arr[*].a2.'aaa.ccc'")).get(0);
assertEquals("aaa.bbb", v1);
jp.setValueAt("c.arr[0].a2.'aaa.ccc'", "aaa.ccc");
jp.setValueAt("c.arr[2].a2.'aaa.ccc'", "aaa.ddd");
String v2 = (String) ((List) jp.getValueAt("c.arr[*].a2.'aaa.ccc'")).get(0);
assertEquals("aaa.ccc", v2);
String v3 = (String) ((List) jp.getValueAt("c.arr[*].a2.'aaa.ccc'")).get(2);
assertEquals("aaa.ddd", v3);
assertEquals(((List) jp.getValueAt("c.arr[*].a2.arr2[*]")).size(), 5);
jp.setValueAt("c.arr[0].a2.arr2[0]", "yyy");
String v4 = (String) ((List) jp.getValueAt("c.arr[*].a2.arr2[*]")).get(0);
assertEquals("yyy", v4);
// check nulls
assertNull(jp.getValueAt("c.arr[1].a2.'aaa.ccc'"));
// set value of non existent path will create that path
jp.setValueAt("c.arr[1].a2.'aaa.ccc'", "aaa.ddd");
assertEquals("aaa.ddd", jp.getValueAt("c.arr[1].a2.'aaa.ccc'"));
assertEquals("aaa.ccc", jp.getValueAt("c.arr[0].a2.'aaa.ccc'"));
assertTrue((Boolean) jp.getValueAt("boolean"));
assertEquals(99, jp.getValueAt("number"));
assertEquals(2, ((JsonObject) jp.getValueAt("c.arr[0].a2.arr2[2]")).getJsonArray("arr3").size());
jp.setValueAt("c.arr[0].a2", new JsonObject("{\"xqq\":\"xaa\"}"));
assertEquals("{\"xqq\":\"xaa\"}", ((JsonObject) jp.getValueAt("c.arr[0].a2")).encode());
jp.setValueAt("c.arr[*]", new JsonObject());
// schema test
JsonObject j22 = null;
try {
j22 = new JsonObject(IOUtils.toString(JsonPathParser.class.getClassLoader().getResourceAsStream("userdata.json"), "UTF-8"));
} catch (IOException e) {
e.printStackTrace();
}
JsonPathParser jp2 = new JsonPathParser(j22, true);
assertEquals("string", jp2.getValueAt("personal.preferredContact.desc.type"));
assertNull(jp2.getValueAt("personals.preferredContact.desc.type"));
assertNull(jp2.getValueAt("personal.properties.preferredContact.properties.desc.type"));
assertEquals("personal.preferredContact.desc.type", jp2.getAbsolutePaths("personal.preferredContact.desc.type").get(0).toString());
assertEquals("string", jp2.getValueAndParentPair("personal.preferredContact.desc.type").getRequestedValue());
assertNull(jp2.getValueAndParentPair("personal2.preferredContact.desc.type"));
}
Aggregations