How to validate message body with json schema using apache camel in spring boot application - json

I am learning apache camel, I have created one spring boot project in which i want to validate the message body with json schema. In my project, I have create route in which i am fetching file from the location in my computer and then passing it to next endpoint where i have applied json validator component and then passed to seda endpoint where i consumed the output.
The code is as follow :
#SpringBootApplication
public class ExampleCamelDemoApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(ExampleCamelDemoApplication.class, args);
CamelContext context = new DefaultCamelContext();
context.addRoutes(new RouteBuilder() {
public void configure() throws Exception {
//
from("file:C:\\sourceFolder?fileName=test.json&noop=true").convertBodyTo(String.class).to("json-validator:classpath:myschema.json")
.to("seda:end");
}
});
context.start();
ConsumerTemplate ct = context.createConsumerTemplate();
System.out.println(ct.receiveBody("seda:end"));
Thread.sleep(10000);
context.stop();
}
}
the test.json file content is :
{
"id" :1
}
and myschema.json file content is :
{
"id" :1
}
I placed the myschema.json file in src/main/resources folder
I am getting error :
Message History (complete message history is disabled)
RouteId ProcessorId Processor Elapsed (ms)
[route1 ] [route1 ] [from[file://C:%5CsourceFolder?fileName=test.json&noop=true] ] [ 2]
...
[route1 ] [to1 ] [json-validator:classpath:myschema.json ] [ 0]
Stacktrace
java.lang.NullPointerException: null
at com.networknt.schema.JsonSchema.combineCurrentUriWithIds(JsonSchema.java:87) ~[json-schema-validator-1.0.29.jar:na]
at com.networknt.schema.JsonSchema.(JsonSchema.java:75) ~[json-schema-validator-1.0.29.jar:na]
at com.networknt.schema.JsonSchema.(JsonSchema.java:62) ~[json-schema-validator-1.0.29.jar:na]
at com.networknt.schema.JsonSchema.(JsonSchema.java:57) ~[json-schema-validator-1.0.29.jar:na]
at com.networknt.schema.JsonSchemaFactory.newJsonSchema(JsonSchemaFactory.java:253) ~[json-schema-validator-1.0.29.jar:na]

Either this is a copy/paste mistake or your schema file is not a JSON schema, but the same as your json data.
Take a look at the Camel docs for an example of a JSON schema file that can be used with the validator.

Related

GCP Dataflow pipeline no json rows being read/processed

Based on the WordCount Example, I am trying to read my own json data (instead of the shakespear txts).
I am running the pipeline with:
mvn compile exec:java -Dexec.mainClass=myPkg.myClass -Dexec.args=" \
--project=myProj \
--stagingLocation=gs://myBkt/stage \
--runner=BlockingDataflowPipelineRunner \
--output=gs://myBkt/output/out \
--defaultWorkerLogLevel=DEBUG"
the output from the console is as follows:
<date> com.google.cloud.dataflow.sdk.runners.DataflowPipelineRunner fromOptions
INFO: PipelineOptions.filesToStage was not specified. Defaulting to files from the classpath: will stage 68 files. Enable logging at DEBUG level to see which files will be staged.
<date> myPkg$GroupPublished apply
<date> myPkg$GroupPublished apply
INFO: GroupPublished/JsonToDatePosPlatKeyFn.out [PCollection]
<date> myPkg main
main
static void main(String[] args) {
...
Pipeline p = Pipeline.create(options);
p.apply(TextIO.Read.named("ReadJson").from(options.getInputFile()))
.apply(new GroupPublished())
.apply(ParDo.of(new FormatAsStringFn()))
.apply(TextIO.Write.named("WriteCounts").to(options.getOutput()));
}
GroupPublished transformation
static class GroupPublished extends PTransform<PCollection<String>,
PCollection<KV<DatePosPlatKey, Long>>> {
#Override
public PCollection<KV<DatePosPlatKey, Long>> apply(PCollection<String> lines) {
PCollection<DatePosPlatKey> keyList
= lines.apply(ParDo.of(new JsonToDatePosPlatKeyFn()));
PCollection<KV<DatePosPlatKey, Long>> keysCounted =
keyList.apply(Count.<DatePosPlatKey>perElement());
return keysCounted;
}
}
json row processing
static class JsonToDatePosPlatKeyFn extends DoFn<String, DatePosPlatKey>{
#Override
public void processElement(ProcessContext c) throws Exception {
JsonNode root = mapper.readTree(c.element());
for (JsonNode jsonFact : root) {
DatePosPlatKey key = new DatePosPlatKey(...construct...);
...manipulate...
c.output(key);
}
}
}
data class
#DefaultCoder(AvroCoder.class)
public static class DatePosPlatKey { ... }
stuff I've checked so far:
adding defaultWorkerLogLevel doesn't seem to make any difference to the console output
renaming the json file throws an error, so I know its been seen by TextIO
the json files have data in the format: {...}\n{...}\n...
no logging or dataflow job appears in the google cloud console
how can I better debug a complete lack of data?
can you see what I've done wrong?
Upon offline discussion it turned out the code was missing a call to p.run(), so the pipeline was only constructed but not executed.

Print Spring Http Response with log4j to console

How can I configure log4j.properties to automatically pretty print the servlet response body(json) to eclipse/terminal console (wire to DEBUG).
This is a Spring(4.3.3) Rest project which produces JSON response. Have jackson-databind(2.5.0) in pom.xml, to convert a model object to json string.
Controller
#RestController
public class ControllerClass {
public final static Logger logger = Logger.getLogger(ControllerClass.class);
#Postmapping("link")
ResponseModel method (#RequestBody ....){
ResponseModel model ;
// other code
return model;
}
}
log4j.properties (log4j 1.2.17)
log4j.rootCategory=INFO, ERROR, stdout, DEBUG
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %t %c{2}:%L - %m%n
Need to wire HTTP response to log4j DEBUG so that the response can be automatically printed ( not by calling logger.debug() )
Note : There is a filter which extends UsernamePasswordAuthenticationFilter as part of Spring security in my project. If no other option, is it good way to put command to print Response body after chain.doFilter()?

XML to JSON in Camel Routing not working

I am trying to convert the XML message to JSON using camel router and save it into a file. Getting the XML message from the source and saving it to destination file etc are working. But when I try to convert to JSON, it did not work. I did not even throw any error/exception in logs. I am running on OSGI container
public class CamelRouter extends RouteBuilder {
#Override
public void configure() throws Exception {
from("file://C:/test/Sample.xml")
.routeId("file-to-file")
.log(LoggingLevel.INFO,"RouteID file-to-file !!!!! starting")
//From XML to JSON
.bean(CamelRouter.class, "convertXmlToJson")
.log(LoggingLevel.INFO,"From XML to JSON !!!!! Done")
.to("file://C:/test/JSONMessages")
.log(LoggingLevel.INFO,"Converted Message Saved successfully");
The bean method to convert XML to JSON convertXmlToJson is shown below
public String convertXmlToJson(String msg) {
log.info("NOW calling JSON conversion");
String jsonStr = null;
log.info("MESSAGE conversion starting : "); //After this message nothing happened
XMLSerializer xmlReader = new XMLSerializer();
log.info("MESSAGE before conversion : " + msg);
jsonStr = xmlReader.read(msg).toString();
log.info("JSON data : " + jsonObj.toString());
return jsonObj.toString();
}
Is anyone know why it is not executing the XMLSerializer portion. I tried this approach because the camel-xmljson's marshal().xmljson() call also give me the same results. Nothing happened after the xmljson() call in my camel routing.
Things that I checked are:
camel-xmljson feature up and running in OSGI
Dependencies mentioned in the Apache XmlJSON website added in my pom file, xom, camel-xmljson etc.
Am I missing anything here? Please help
The problem with your code route is that your bean component handler method resides within your route builder class, plus you invoke the bean component in a way that triggers another instantiation of that route builder class.
Personally, I would move convertXmlToJson to an appropriate utility class. That way you reduce mix of concern in the route builder and the bean component should work fine.
Alternatively, your route might work, if you invoke the bean component like this:
.bean(this, "convertXmlToJson")

JSON, JAXB,JSON Rest

I created a Rest Service which has is working fine in XML request ( Rest Service input JAXB generated class ). When I am trying to send a Json Request, It's throwing an exception.
SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
org.codehaus.jackson.map.JsonMappingException: Can not instantiate value of type [simple type, class Transaction] from JSON String; no single-String constructor/factory method (through reference chain:
class Transaction which is inner class .
My Request class is generated from schema using JAXB, My getter method is like below but no setter method.
public List<Transaction> getORIG() {
if (origtrans == null) {
origtrans = new ArrayList<Transaction>();
}
return this.origtrans;
}
My Json Request below
{
"LOB_CD": "42424"
"ORIGINALTRANSACTION" : [
"LOGON_ID" : "TEST"
]
}
When I am addiong original Transaction it's throwing an error otherwise it's working fine.
Can you please help me out with this.
Thanks in advance.
First of all make sure you are using a valid JSON, like:
{
"LOB_CD": "42424",
"ORIGINALTRANSACTION": {
"LOGON_ID": "TEST"
}
}
Also, it would be nice if you could show us the Transaction class.
It works.
I did following steps
1) Added an empty constructor
2) Added this annotation for the list
#JsonDeserialize(as=ArrayList.class, contentAs=Transaction.class)
3) change a Json Object to
{ "LOB_CD": "42424" "ORIGINALTRANSACTION" : [ { "LOGON_ID" : "TEST" } ] }
Thanks a lot,
Patel

as3 Thrift Client and its return type

i wrote a following '.thrift' file
service retriveService {
binary getImageContent(1: string strImgName);
}
I generated 2 clients one in java and other in as3 (using latest thrift-0.9.0.exe) .
my generated 'retriveService.java' file has following method
public ByteBuffer getImageContent(String strImgName) with return type as 'ByteBuffer'
where as my 'retriveService.as' file has following method
function getImageContent(strImgName:String, onError:Function, onSuccess:Function):void;
with return type as 'void'
i am not able to get the file content in as3 implementation since the return type is void.
Any ideas what I'm missing here?
Method result will be received as a parameter of onSuccess function. So, the client code might look like this:
var s : retriveService = ....
s. getImageContent("imageName",
function(e : Error) : void {
//Handle error
},
function(r : ByteArray) : void {
//Handle result
},