Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unmarshal json in spring xml #543

Closed
jstakun opened this issue Dec 13, 2019 · 10 comments
Closed

Unmarshal json in spring xml #543

jstakun opened this issue Dec 13, 2019 · 10 comments
Assignees

Comments

@jstakun
Copy link

jstakun commented Dec 13, 2019

I'm trying to migrate spring xml route to quarkus camel. Everything works except for json unmarshaling.

In original version I've configured data format in camel context:

<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
        <dataFormats>
            <json id="transform-game" library="Jackson" unmarshalTypeName="com.openshift.wildwest.models.Game"/>
            <json id="transform-platform-object" library="Jackson" unmarshalTypeName="com.openshift.wildwest.models.PlatformObject"/>
        </dataFormats>

...
and the I'm calling it in the route:

<unmarshal ref="transform-game"/>

In quarkus version I don't know how to declare dataFormats beacuse in the example camel context is declared in application.properties and not in the xml hence I'm declaring it in the route:

<unmarshal>
       <json library="Jackson" unmarshalTypeName="com.openshift.wildwest.models.Game" id="transform-game"/>
</unmarshal>

However this doesn't seem to unmarshal json body to pojo.
Can you advice proper syntax?

@lburgazzoli
Copy link
Contributor

We don't support defining routes through spring xml at least at this stage so I'd recommend to use "routes fragments" (see the example https://github.com/apache/camel-quarkus/tree/master/examples/timer-log-xml).

@jstakun
Copy link
Author

jstakun commented Dec 13, 2019

Yes. That's exactly what I did. Unfortunetaly I can't create data formats in route fragment and hence I used

<unmarshal>
        <json library="Jackson" unmarshalTypeName="com.openshift.wildwest.models.Game" id="transform-game"/>
</unmarshal>

But this doesn't work correctly. Is that the right way to unmarshal json to pojo in spring xml, or should I try something else?

@lburgazzoli
Copy link
Contributor

You can create data formats programmatically using java i.e. CDI/Spring beans but what you wrote should work, what is the error ?

@jstakun
Copy link
Author

jstakun commented Dec 13, 2019

Object is created but all fields are not populated with data from json.
If this is correct I'll try to debug it further.

@lburgazzoli
Copy link
Contributor

does this happen in JVM or native mode ?

@jstakun
Copy link
Author

jstakun commented Dec 14, 2019

This happens in JVM

Here is the route:

<route id="start-game">
           <from uri="direct:start-game"/>
           <log id="init-game-log" message="Starting new game"/>
           <to id="_toD1" uri="netty-http:http://{{backend.service}}/createGame"/>
           <log id="_log22" message="Received ${body}"/>
           <unmarshal>
                <json library="Jackson" id="transform-game" unmarshalTypeName="com.openshift.wildwest.models.Game"/>
           </unmarshal>
           <log id="_log12" message="Transformed ${body}"/>
           <setHeader name="gameID" id="_setHeader1">
                <simple>${body.score.gameID}</simple>
           </setHeader>
           <log id="_log1" message="New game started ${header.gameID}"/>
           <removeHeaders id="_removeHeaders1" pattern="CamelHttp*"/>
        </route>  

POJO:

package com.openshift.wildwest.models;

import io.quarkus.runtime.annotations.RegisterForReflection;

@RegisterForReflection
public class Game {
	
	private Score score;
	private String mode;
	private String gameMode;
	
	
	public Game() {
	    
	}
	
	public Score getScore() {
		return score;
	}
	public void setScore(Score score) {
		this.score = score;
	}
	public String getMode() {
		return mode;
	}
	public void setMode(String mode) {
		this.mode = mode;
	}
	public String getGameMode() {
		return gameMode;
	}
	public void setGameMode(String gameMode) {
		this.gameMode = gameMode;
	}
}

and stacktrace:

2019-12-14 10:13:10,238 INFO  [org.apa.cam.mai.BaseMainSupport] (main) Using properties from classpath:application.properties

2019-12-14 10:13:10,275 INFO  [org.apa.cam.mai.BaseMainSupport] (main) Auto-configuration summary:

2019-12-14 10:13:10,275 INFO  [org.apa.cam.mai.BaseMainSupport] (main) 	camel.main.xmlroutes=classpath:/spring/camel-routes.xml

2019-12-14 10:13:10,275 INFO  [org.apa.cam.mai.BaseMainSupport] (main) 	camel.context.name=wildwest-bot

2019-12-14 10:13:10,277 INFO  [org.apa.cam.mai.DefaultRoutesCollector] (main) Loading additional Camel XML routes from: classpath:/spring/camel-routes.xml

2019-12-14 10:13:10,668 INFO  [org.apa.cam.qua.cor.FastCamelContext] (main) Apache Camel 3.0.0 (CamelContext: wildwest-bot) is starting

2019-12-14 10:13:10,669 INFO  [org.apa.cam.imp.eng.DefaultManagementStrategy] (main) JMX is disabled

2019-12-14 10:13:10,855 INFO  [org.apa.cam.qua.cor.FastCamelContext] (main) StreamCaching is not in use. If using streams then its recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html

2019-12-14 10:13:10,879 WARN  [org.apa.cam.com.jac.JacksonDataFormat] (main) The option autoDiscoverObjectMapper is set to false, Camel won't search in the registry

2019-12-14 10:13:10,927 DEBUG [org.apa.cam.com.jac.JacksonDataFormat] (main) Creating new ObjectMapper to use: com.fasterxml.jackson.databind.ObjectMapper@74ea46e2

2019-12-14 10:13:10,928 DEBUG [org.apa.cam.com.jac.JacksonDataFormat] (main) Registering JaxbAnnotationModule: com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule@1b956cfa

2019-12-14 10:13:10,939 INFO  [org.apa.cam.qua.cor.FastCamelContext] (main) Route: simple-route started and consuming from: timer://wildwest-bot?period=30s

2019-12-14 10:13:10,941 INFO  [org.apa.cam.qua.cor.FastCamelContext] (main) Route: start-game started and consuming from: direct://start-game

2019-12-14 10:13:10,943 INFO  [org.apa.cam.qua.cor.FastCamelContext] (main) Total 2 routes, of which 2 are started

2019-12-14 10:13:10,944 INFO  [org.apa.cam.qua.cor.FastCamelContext] (main) Apache Camel 3.0.0 (CamelContext: wildwest-bot) started in 0.276 seconds

2019-12-14 10:13:10,946 INFO  [io.quarkus] (main) Quarkus 1.0.1.Final started in 2.107s. 

2019-12-14 10:13:10,947 INFO  [io.quarkus] (main) Profile dev activated. Live Coding activated.

2019-12-14 10:13:10,948 INFO  [io.quarkus] (main) Installed features: [camel-core, camel-direct, camel-jackson, camel-log, camel-netty, camel-netty-http, camel-support-common, camel-support-xml, camel-timer, camel-xml, cdi]

2019-12-14 10:13:11,954 INFO  [start-game] (Camel (camel-1) thread #1 - timer://wildwest-bot) Starting new game

2019-12-14 10:13:12,068 INFO  [start-game] (Camel Thread #2 - NettyClientTCPWorker) Received {"score":{"score":0,"gameID":"PD4OVUOF66GSRL9IRM"},"mode":"OPENSHIFT","gameMode":"OPENSHIFT"}

2019-12-14 10:13:12,112 INFO  [start-game] (Camel Thread #2 - NettyClientTCPWorker) Transformed to com.openshift.wildwest.models.Game@3296d85b

2019-12-14 10:13:12,115 ERROR [org.apa.cam.pro.err.DefaultErrorHandler] (Camel Thread #2 - NettyClientTCPWorker) Failed delivery for (MessageId: CCEECE4183014C7-0000000000000001 on ExchangeId: CCEECE4183014C7-0000000000000000). Exhausted after delivery attempt: 1 caught: java.lang.IllegalArgumentException: Failed to set property bean on null. Reason: java.lang.NullPointerException

 

Message History

---------------------------------------------------------------------------------------------------------------------------------------

RouteId              ProcessorId          Processor                                                                        Elapsed (ms)

[simple-route      ] [simple-route      ] [from[timer://wildwest-bot?period=30s]                                         ] [       170]

[simple-route      ] [_filter1          ] [filter[simple{${exchangeProperty.CamelTimerCounter} == 1}]                    ] [         0]

[simple-route      ] [to1               ] [direct:start-game                                                             ] [         0]

[start-game        ] [init-game-log     ] [log                                                                           ] [         0]

[start-game        ] [_toD1             ] [netty-http:http://{{backend.service}}/createGame              ] [       113]

[start-game        ] [_log22            ] [log                                                                           ] [         0]

[start-game        ] [unmarshal2        ] [unmarshal[org.apache.camel.model.dataformat.JsonDataFormat@6441c486]          ] [        44]

[start-game        ] [_log12            ] [log                                                                           ] [         1]

[start-game        ] [_setHeader1       ] [setHeader[gameID]                                                             ] [         0]

 

Stacktrace

---------------------------------------------------------------------------------------------------------------------------------------: java.lang.IllegalArgumentException: Failed to set property bean on null. Reason: java.lang.NullPointerException

	at org.apache.camel.support.builder.ExpressionBuilder.setProperty(ExpressionBuilder.java:1417)

	at org.apache.camel.support.builder.ExpressionBuilder$56.evaluate(ExpressionBuilder.java:1292)

	at org.apache.camel.support.ExpressionAdapter.evaluate(ExpressionAdapter.java:36)

	at org.apache.camel.language.simple.SimpleExpressionBuilder$29.evaluate(SimpleExpressionBuilder.java:668)

	at org.apache.camel.support.ExpressionAdapter.evaluate(ExpressionAdapter.java:36)

	at org.apache.camel.builder.SimpleBuilder.evaluate(SimpleBuilder.java:102)

	at org.apache.camel.processor.SetHeaderProcessor.process(SetHeaderProcessor.java:46)

	at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryState.run(RedeliveryErrorHandler.java:476)

	at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:185)

	at org.apache.camel.impl.engine.DefaultReactiveExecutor.schedule(DefaultReactiveExecutor.java:67)

	at org.apache.camel.spi.ReactiveExecutor.schedule(ReactiveExecutor.java:32)

	at org.apache.camel.impl.engine.DefaultReactiveExecutor.callback(DefaultReactiveExecutor.java:100)

	at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryState.lambda$run$1(RedeliveryErrorHandler.java:480)

	at org.apache.camel.processor.SendProcessor$1.done(SendProcessor.java:146)

	at org.apache.camel.component.netty.http.NettyHttpProducer$NettyHttpProducerCallback.done(NettyHttpProducer.java:148)

	at org.apache.camel.component.netty.NettyProducer$NettyProducerCallback.done(NettyProducer.java:544)

	at org.apache.camel.component.netty.handlers.ClientChannelHandler.channelRead0(ClientChannelHandler.java:217)

	at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:105)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)

	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)

	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)

	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)

	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:306)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)

	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)

	at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)

	at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:328)

	at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:302)

	at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)

	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352)

	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1422)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374)

	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360)

	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:931)

	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163)

	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:700)

	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:635)

	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:552)

	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:514)

	at io.netty.util.concurrent.SingleThreadEventExecutor$6.run(SingleThreadEventExecutor.java:1044)

	at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)

	at java.lang.Thread.run(Thread.java:748)

Caused by: java.lang.NullPointerException

	at org.apache.camel.support.IntrospectionSupport.setProperty(IntrospectionSupport.java:661)

	at org.apache.camel.support.IntrospectionSupport.setProperty(IntrospectionSupport.java:795)

	at org.apache.camel.impl.engine.DefaultBeanIntrospection.setProperty(DefaultBeanIntrospection.java:170)

	at org.apache.camel.support.builder.ExpressionBuilder.setProperty(ExpressionBuilder.java:1415)

	... 47 more

@lburgazzoli
Copy link
Contributor

Do you have a repository/reproducer we can have a look at ?

@jstakun
Copy link
Author

jstakun commented Dec 16, 2019

https://github.com/jstakun/wildwest-bot/

After you pull/fork:

  • delete org.mycompany.Application.java and pom.xml
  • rename quarkus-pom.xml to pom.xml
  • specify backend host:port in application.properties

For backend creation on Openshift you can use following commands:

oc new-project wildwest-shooter
oc policy add-role-to-user edit -z default
oc new-app quay.io/jstakun/wildwest-shooter-backend-quarkus:0.1 --name backend
oc expose service backend

@lburgazzoli lburgazzoli self-assigned this Jan 2, 2020
lburgazzoli added a commit to lburgazzoli/apache-camel-quarkus that referenced this issue Jan 2, 2020
@lburgazzoli
Copy link
Contributor

@jstakun

I'vre created some tests:
#581

And an example:
https://github.com/lburgazzoli/camel-quarkus-examples/tree/master/json-unmarshal

If you clone the example repo, then:

  1. in one shell run mvn clean compile quarkus:dev
  2. in another shell run echo '{ "score": { "gameID": "myid" } }' | http :8081/game

the log should show something like:

INFO  [route1] (Camel (camel-1) thread #5 - NettyEventExecutorGroup) myid

The issue is that, to use OGNL like paths you also need camel-quarkus-bean in the classpath

lburgazzoli added a commit to lburgazzoli/apache-camel-quarkus that referenced this issue Jan 2, 2020
lburgazzoli added a commit to lburgazzoli/apache-camel-quarkus that referenced this issue Jan 2, 2020
@jstakun
Copy link
Author

jstakun commented Jan 2, 2020

Thanks. Adding camel-quarkus-bean to the pom deps solved this issue

@jstakun jstakun closed this as completed Jan 2, 2020
oscerd added a commit that referenced this issue Jan 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants