If you look at the test, it says: if (!(exchange instanceof InOnly)) Note the negation of the test.
The exception that happens when logging the message certainly is because ServiceMix expects either a 200 or 202 status code or a response. What does the 201 means in your case ? Are you expecting a response later ? On Thu, Apr 3, 2008 at 10:26 PM, Tom Purcell <[EMAIL PROTECTED]> wrote: > > Guillaume > > I've done some looking into the response issue. I added debugs to the > handleResponse method of my RestProviderMarshaler to figure out what was > happening. This is what the beginning of that method looks like. I only > included up to where things appear to go wrong. The only difference is the > debugs: > > public void handleResponse(MessageExchange exchange, SmxHttpExchange > httpExchange) throws Exception { > int response = httpExchange.getResponseStatus(); > logger.debug("*** Response Status: " + response); > > if (response != HttpStatus.SC_OK && response != HttpStatus.SC_ACCEPTED) > { > if (!(exchange instanceof InOnly)) { > logger.debug("*** InOnly"); > > Now in the log I get the following: > 15:12:52,646 - DEBUG - RestProviderMarshaler - *** Response > Status: > 201 > 15:12:52,647 - DEBUG - RestProviderMarshaler - *** InOnly > 15:12:52,647 - DEBUG - DeliveryChannelImpl - Send > ID:127.0.0.2-1191563e603-3:10 in DeliveryChannel{servicemix-http} > 15:12:52,652 - TRACE - DeliveryChannelImpl - Sent: InOut[ > id: ID:127.0.0.2-1191563e603-3:10 > status: Active > role: provider > service: > {http://www.abc.com/wile}wileRestService<http://www.abc.com/wile%7DwileRestService> > endpoint: wileRestCreate > in: <?xml version="1.0" > encoding="UTF-8"?><assetRequest><perspective>asset</perspective><asset... > NOTE: DOTS BY ME TO SHORTEN EMAIL > ...</assetRequest> > fault: Unable to display: java.io.IOException: No input stream or reader > available > ] > > It starts out good. We get a 201. But why are we in the InOnly code? The > subsequent TRACE - DeliveryChannelImpl message says we are InOut. I'm not > sure what to do here. > > Thanks > Tom > > > > Tom Purcell wrote: > > > > Guillaume > > > > I've made some progress. This is what I did. > > > > First, I switched to JAXP instead of Jaxen. The ONLY reason for this is > > I'm on a corporate network and they will not allow access to any URL > with > > the "jaxen" in it thus making research difficult. (not your problem, > just > > venting). > > > > I understood what you were saying about using a SourceTransformer > instead > > of toString() but the problem is that by the time my getContentToSend() > > gets the result of the XPath evaluation it is already a String with the > > XML tags stripped out. > > > > In the SMX JAXPXPathExpression class the evaluateXPath(Object object) > > method calls the javax.xml.xpath.XPathExpression evaluate(object) > method. > > There are four implementations of that method in XPathExpression. The > one > > being called in the SMX JAXPXPathExpression class returns a String. This > > String contains the VALUEs only, not the tags. This is great when you > need > > a value to build a URL but not when you need the actual XML. > > > > I need the NodeSet. Another version of the XPathExpression evaluate > > method, evaluate(object, returnType), allows you to control the return > > type but the SMX JAXPXPathExpression does not expose a way to call it. I > > went into the SMX JAXPXPathExpression class and did the following: > > > > Changed: > > protected Object evaluateXPath(Object object) throws > > XPathExpressionException > > To: > > protected Object evaluateXPath(Object object, QName returnType) throws > > XPathExpressionException > > > > Added: > > public Object evaluate(MessageExchange exchange, NormalizedMessage > > message, QName returnType) throws MessagingException > > > > Changed: > > public Object evaluate(MessageExchange exchange, NormalizedMessage > > message) throws MessagingException > > To call the new version above. It passes in XPathConstants.STRING as the > > QName to provide backward compatibility. > > > > In my new RestProviderMarshaler: > > protected String getContentToSend(MessageExchange exchange, > > NormalizedMessage inMsg) throws Exception { > > String content = null; > > > > if (contentExpression != null) { > > logger.debug("*** Evaluate toString: " + > > contentExpression.evaluate(exchange, inMsg)); > > Node node = (Node)contentExpression.evaluate(exchange, inMsg, > > XPathConstants.NODE); > > content = transformer.toString(new DOMSource(node)); > > logger.debug("*** Content toString: " + content); > > } > > > > if (content == null) { > > throw new IllegalStateException("Unable to find Content for > > exchange"); > > } > > return content; > > } > > > > NOTE: > > I have two calls to contentExpression.evaluate() method in > > JAXPXPathExpression. The first is just in the debug and is there to > > demonstrate the backward compatibility call. This is what it produces in > > the log (No XML Tags): > > > > 14:21:31,263 - DEBUG - RestProviderMarshaler - *** Evaluate > > toString: ServerAsset This is a Test ServerAsset, created from > > TestAssetPersistenceTwo. SGNS-0202 true true REDHAT LINUX > > testserverassetc092803e-f2bd-9cb4-1f34-1da6f42053f1 sgns.net OS64 5.0.1 > > 001 2048 2 > > > > With the call to the new version (contentExpression.evaluate(exchange, > > inMsg, XPathConstants.NODE)) produces this (A nice healthy chunk of > XML): > > > > 14:21:31,268 - DEBUG - RestProviderMarshaler - *** Content > > toString: <?xml version="1.0" encoding="UTF-8"?><asset > > name="TestServerAsset1207250490590"> > <class_type>ServerAsset</class_type> > > <description>This is a Test ServerAsset, created from > > TestAssetPersistenceTwo.</description> > > <serial_number>SGNS-0202</serial_number> <enabled>true</enabled> > > <managed>true</managed> <category > > guid="42E213B8-3F31-E288-05A7-7D855CF32329" value="Default"/> <type > > guid="30E6FD81-2D8E-B45B-CA53-703ADEDA3BDB" value="Default"/> <state > > guid="26BC358E-9F90-FE7F-5199-01DB9FBB72FE" value="Default"/> <mfgName/> > > <os>REDHAT LINUX</os> > > > <host_name>testserverassetc092803e-f2bd-9cb4-1f34-1da6f42053f1</host_name> > > <domain_name>sgns.net</domain_name> <platform>OS64</platform> > > <os_version>5.0.1</os_version> <os_patch_level>001</os_patch_level> > > <memory>2048</memory> <cpus>2</cpus> </asset> > > > > I'm not out of the woods yet. My POST is getting to the webapp and the > > webapp is updating the database but things fall apart on the response. > I'm > > not certain at this point whether its an issue with the wepapp's > response > > or SMX's handling it or a little of both. I'll let you know what I find > > out. > > > > On the JAXPXPathExpression code, if there is another approach you think > I > > should take or you'd like to get the code let me know. > > > > Thanks > > Tom > > > > > > > > > > > > > > > > > > > > Tom Purcell wrote: > >> > >> Guillaume > >> > >> Thabnks for the input. Responses inline > >> > >> gnodet wrote: > >>> > >>> Have you tried using the JaxenXPathExpression instead of the > >>> JaxenStringXPathExpression ? > >>> > >>> Yes, I got the same result. > >>> > >>> Also, I think you need to change the getContentToSend() method because > >>> using > >>> toString() on the result won't work. Try using the > >>> org.apache.servicemix.jbi.jaxp.*SourceTransformer* to convert the DOM > >>> node > >>> to a String instead. > >>> > >>> Okay, I'll play with this but the call to contentExpression.evaluate() > >>> in getContentToSend() returns a String object. At any rate I'll give > it > >>> a shot and let you know how it goes. > >>> > >>> Thanks > >>> Tom > >>> > >>> On Wed, Apr 2, 2008 at 11:27 PM, Tom Purcell > >>> <[EMAIL PROTECTED]> > >>> wrote: > >>> > >>>> > >>>> Guillaume > >>>> > >>>> Below is all of what I'm doing. Notice in the logs at the bottom that > >>>> what > >>>> comes in on the NM is of type DOMSource but the object returned by > the > >>>> contentExpression.evaluate() method is of type String. I think it > want > >>>> I > >>>> want is for that to be a DOMSource too. I also see the "Content is > not > >>>> allowed in prolog" meesage but I think that is caused by the fact > that > >>>> my > >>>> content is just the values and not the XML. > >>>> > >>>> Here's the xbean config: > >>>> > >>>> <http:provider service="wile:wileRestService" > >>>> interfaceName="wileCreate" > >>>> endpoint="wileRestCreate" > >>>> marshaler="#createMarshaler"/> > >>>> > >>>> <bean id="createMarshaler" > >>>> class="jbi.marshal.RestProviderMarshaler"> > >>>> <property name="locationURIExpression"> > >>>> <bean > >>>> class="org.apache.servicemix.expression.JaxenStringXPathExpression"> > >>>> <constructor-arg > >>>> value="concat(' > >>>> http://localhost:8080/wile-www/assetmanagement/assetservice/ > >>>> ',/assetRequest/perspective)"/> > >>>> </bean> > >>>> </property> > >>>> <property name="method" > >>>> value="POST"/> > >>>> <property name="contentType" > >>>> value="application/x-www-form-urlencoded"/> > >>>> <property name="contentExpression"> > >>>> <bean > >>>> class="org.apache.servicemix.expression.JaxenStringXPathExpression"> > >>>> <constructor-arg value="//asset"/> > >>>> </bean> > >>>> </property> > >>>> </bean> > >>>> </pre> > >>>> > >>>> In my RestProviderMarshaler class I added a property for > >>>> contentExpression > >>>> and replaced the createRequest method. Here are the relevant methods: > >>>> > >>>> public void createRequest(MessageExchange exchange, > >>>> NormalizedMessage > >>>> inMsg, SmxHttpExchange httpExchange) throws Exception { > >>>> logger.debug("*** Before CREATE MessageExchange: " + > exchange); > >>>> logger.debug("*** NM In Content: " + inMsg.getContent()); > >>>> logger.debug("*** LocationURI: " + getLocationUri(exchange, > >>>> inMsg)); > >>>> > >>>> httpExchange.setURL(getLocationUri(exchange, inMsg)); > >>>> httpExchange.addRequestHeader(HttpHeaders.HOST_BUFFER, new > >>>> ByteArrayBuffer(new URI(getLocationUri(exchange, inMsg)).getHost())); > >>>> httpExchange.setMethod(getMethod(exchange, inMsg)); > >>>> httpExchange.setRequestHeader(HttpHeaders.CONTENT_TYPE, > >>>> getContentType(exchange, inMsg)); > >>>> > >>>> if (getHeaders() != null) { > >>>> for (Map.Entry<String, String> e : > getHeaders().entrySet()) > >>>> { > >>>> httpExchange.setRequestHeader(e.getKey(), > e.getValue()); > >>>> } > >>>> } > >>>> > >>>> String contentToSend = getContentToSend(exchange, inMsg); > >>>> logger.debug("*** Content: " + contentToSend); > >>>> > >>>> if (contentToSend != null) { > >>>> httpExchange.setRequestContent(new > >>>> ByteArrayBuffer(contentToSend.getBytes())); > >>>> } > >>>> } > >>>> > >>>> protected String getContentToSend(MessageExchange exchange, > >>>> NormalizedMessage inMsg) throws Exception { > >>>> String content = null; > >>>> if (contentExpression != null) { > >>>> Object o = contentExpression.evaluate(exchange, inMsg); > >>>> logger.debug("*** Content Object Type: " + o.getClass()); > >>>> content = (o != null) ? o.toString() : null; > >>>> } > >>>> if (content == null) { > >>>> throw new IllegalStateException("Unable to find Content > for > >>>> exchange"); > >>>> } > >>>> return content; > >>>> } > >>>> > >>>> Here is what I see from the debugs: > >>>> > >>>> 16:18:59,407 - DEBUG - RestProviderMarshaler - *** Before > >>>> CREATE > >>>> MessageExchange: InOut[ > >>>> id: ID:127.0.0.2-11910ec49ca-3:4 > >>>> status: Active > >>>> role: provider > >>>> service: > >>>> {http://www.abc.com/wile}wileRestService<http://www.abc.com/wile%7DwileRestService> > <http://www.abc.com/wile%7DwileRestService> > >>>> endpoint: wileRestCreate > >>>> in: <?xml version="1.0" > >>>> > encoding="UTF-8"?><assetRequest><perspective>asset</perspective><asset > >>>> name="TestAsset"> <class_type>BigAsset</class_type> <description>This > >>>> is a > >>>> Test Asset</description> <serial_number>12345</serial_number> > >>>> <enabled>true</enabled> <category guid="67890" value="Default"/> > <type > >>>> guid="09876" value="Default"/> <state guid="54321" value="Default"/> > >>>> </asset> </assetRequest> > >>>> ] > >>>> 16:18:59,408 - DEBUG - RestProviderMarshaler - *** NM In > >>>> Content: > >>>> [EMAIL PROTECTED] > >>>> 16:18:59,408 - DEBUG - RestProviderMarshaler - *** > >>>> LocationURI: > >>>> http://localhost:8080/wile-www/assetmanagement/assetservice/asset > >>>> 16:18:59,409< > http://localhost:8080/wile-www/assetmanagement/assetservice/asset16:18:59,409 > >- > >>>> DEBUG - RestProviderMarshaler - *** Content Object > >>>> Type: class java.lang.String > >>>> 16:18:59,409 - DEBUG - RestProviderMarshaler - *** Content: > >>>> BigAsset This is a Test Asset 12345 true > >>>> 16:18:59,446 - DEBUG - DeliveryChannelImpl - Send > >>>> ID:127.0.0.2-11910ec49ca-3:4 in DeliveryChannel{servicemix-http} > >>>> [Fatal Error] :1:1: Content is not allowed in prolog. > >>>> 16:18:59,451 - TRACE - DeliveryChannelImpl - Sent: InOut[ > >>>> id: ID:127.0.0.2-11910ec49ca-3:4 > >>>> status: Active > >>>> role: provider > >>>> service: > >>>> {http://www.abc.com/wile}wileRestService<http://www.abc.com/wile%7DwileRestService> > <http://www.abc.com/wile%7DwileRestService> > >>>> endpoint: wileRestCreate > >>>> in: <?xml version="1.0" > >>>> > encoding="UTF-8"?><assetRequest><perspective>asset</perspective><asset > >>>> name="TestAsset"> <class_type>BigAsset</class_type> <description>This > >>>> is a > >>>> Test Asset</description> <serial_number>12345</serial_number> > >>>> <enabled>true</enabled> <category guid="67890" value="Default"/> > <type > >>>> guid="09876" value="Default"/> <state guid="54321" value="Default"/> > >>>> </asset> </assetRequest> > >>>> fault: Unable to display: org.xml.sax.SAXParseException: Content is > >>>> not > >>>> allowed in prolog. > >>>> ] > >>>> 16:18:59,454 - DEBUG - SedaFlow - Called Flow > >>>> send > >>>> > >>>> Thanks > >>>> Tom > >>>> > >>>> > >>>> gnodet wrote: > >>>> > > >>>> > I suppose the creation of the content does not support writing an > xml > >>>> > element and maybe use toString() or something like that to create > the > >>>> > content of the request. Could you paste the endpoint definition > and > >>>> > snippet > >>>> > of code, I'm not sure to fully understand your configuration. > >>>> > I think if you use a marshaler, you can really do anything you > need. > >>>> I'm > >>>> > sure we could come with something reusable using an expression for > >>>> the > >>>> > URL, > >>>> > the method and the content. > >>>> > > >>>> > On Wed, Apr 2, 2008 at 2:33 PM, Tom Purcell > >>>> > <[EMAIL PROTECTED]> > >>>> > wrote: > >>>> > > >>>> >> > >>>> >> Guillaume > >>>> >> > >>>> >> The message gets sent to the correct URI but the issue is the > >>>> content > >>>> of > >>>> >> the > >>>> >> message. I need to send the XML (<foo>bar</foo>) but what gets > >>>> returned > >>>> >> by > >>>> >> contentExpression.evaluate(exchange, inMsg), subsequently sent to > >>>> the > >>>> >> RESTful service, is just the values (bar). > >>>> >> > >>>> >> At this point I guess its really a Jaxen question. Can you get it > to > >>>> >> return > >>>> >> the XML instead of just the values? Otherwise some other parsing > >>>> strategy > >>>> >> is > >>>> >> needed. However, I really liked the idea of just defining an XPath > >>>> >> expression on the endpoint. It seems it would make the marshaler > >>>> pretty > >>>> >> flexible. > >>>> >> > >>>> >> Thanks > >>>> >> Tom > >>>> >> > >>>> >> > >>>> >> > >>>> >> gnodet wrote: > >>>> >> > > >>>> >> > Well, it sounds realy good. > >>>> >> > What exactly does not work when using POST with your marshaler ? > >>>> >> > > >>>> >> > On Wed, Apr 2, 2008 at 12:00 AM, Tom Purcell > >>>> >> > <[EMAIL PROTECTED]> > >>>> >> > wrote: > >>>> >> > > >>>> >> >> > >>>> >> >> Guillaume > >>>> >> >> > >>>> >> >> Okay, I'm new to REST so I may be missing something there too > but > >>>> this > >>>> >> is > >>>> >> >> where I'm at. SMX will receive a JMS message with an XML > payload. > >>>> The > >>>> >> XML > >>>> >> >> will have two high level nodes. One node's value will be the > >>>> service > >>>> >> to > >>>> >> >> call > >>>> >> >> (will become part of the REST URL). The other node will be a > big > >>>> chunk > >>>> >> of > >>>> >> >> XML to be POSTed to the service. The content-type is > >>>> >> >> x-www-form-urlencoded. > >>>> >> >> > >>>> >> >> I extended DefaultHttpProviderMarshaler and I call > >>>> >> >> > >>>> httpExchange.setRequestContent(bigXmlChunkContentOfTheSecondNode). > >>>> >> >> > >>>> >> >> This almost works. I use JaxenStringXPathExpression to get the > >>>> value > >>>> >> of > >>>> >> >> the > >>>> >> >> first node and set the REST URL. Then my class has a new > >>>> property, > >>>> >> >> contentExpression, also a JaxenStringXPathExpression. I use > this > >>>> to > >>>> >> >> define > >>>> >> >> the XPath to the second node, the one with the big chunk of > XML, > >>>> but > >>>> >> it > >>>> >> >> adds > >>>> >> >> the values of the second node. What I need is the chunk of XML, > >>>> >> elements, > >>>> >> >> attributes and all. > >>>> >> >> > >>>> >> >> I guess I could introduce a Saxon endpoint to do a > transformation > >>>> and > >>>> >> a > >>>> >> >> router to send the message to different HTTP endpoints based on > >>>> the > >>>> >> first > >>>> >> >> node but that seems a lot less elegant than just dynamically > >>>> >> determining > >>>> >> >> the > >>>> >> >> REST URL in the marshaler. It works fine for GETs but then > POST, > >>>> I'm > >>>> >> >> learning, is a different story. > >>>> >> >> > >>>> >> >> Any thoughts? > >>>> >> >> > >>>> >> >> Thanks > >>>> >> >> Tom > >>>> >> >> > >>>> >> >> > >>>> >> >> gnodet wrote: > >>>> >> >> > > >>>> >> >> > I really think the best way would be to create your own > >>>> marshaler > >>>> if > >>>> >> >> the > >>>> >> >> > default one does not work for you. If you come up with > >>>> something > >>>> >> >> generic > >>>> >> >> > enough feel free to contribute it back. However, the > >>>> >> >> > DefaultHttpProviderMarshaler should send a POST request if > the > >>>> input > >>>> >> >> > message > >>>> >> >> > is not null, but this is more like a soap POST rather than a > >>>> form > >>>> >> post > >>>> >> >> > with > >>>> >> >> > key/value pairs. Is that what you'd need ? How do you > extract > >>>> the > >>>> >> >> > key/value pairs from the exchange ? > >>>> >> >> > > >>>> >> >> > On Tue, Apr 1, 2008 at 3:26 PM, Tom Purcell > >>>> >> >> > <[EMAIL PROTECTED]> > >>>> >> >> > wrote: > >>>> >> >> > > >>>> >> >> >> > >>>> >> >> >> Hello > >>>> >> >> >> > >>>> >> >> >> I'm trying to use the servicemix-http http:provider to call > a > >>>> >> RESTful > >>>> >> >> >> service. GET works fine but I'm having trouble trying to > >>>> configure > >>>> >> it > >>>> >> >> to > >>>> >> >> >> do > >>>> >> >> >> a post. It appears to me that DefaultHttpProviderMarshaler > >>>> does > >>>> not > >>>> >> >> >> directly > >>>> >> >> >> support this and so I must write my own Marshaler to set the > >>>> >> content. > >>>> >> >> My > >>>> >> >> >> first question is just a request to verify that is correct > and > >>>> that > >>>> >> >> I'm > >>>> >> >> >> not > >>>> >> >> >> missing something. > >>>> >> >> >> > >>>> >> >> >> My next question is about > >>>> >> >> >> http://issues.apache.org/activemq/browse/SM-580 > >>>> >> >> >> SM-580 < > http://issues.apache.org/activemq/browse/SM-580SM-580> > >>>> . > >>>> >> This > >>>> >> >> >> appears to address this situation although I'm not certain > it > >>>> >> >> >> does so in a RESTful way (I'm new to REST). SM-580 appears > to > >>>> be > >>>> >> >> >> scheduled > >>>> >> >> >> for 3.3 so is this what I would use once 3.3 is released and > >>>> when > >>>> >> is > >>>> >> >> 3.3 > >>>> >> >> >> scheduled for release? > >>>> >> >> >> > >>>> >> >> >> Thanks > >>>> >> >> >> Tom > >>>> >> >> >> -- > >>>> >> >> >> View this message in context: > >>>> >> >> >> > >>>> >> >> > >>>> >> > >>>> > http://www.nabble.com/servicemix-http-Post-support-tp16418421s12049p16418421.html > >>>> >> >> >> Sent from the ServiceMix - User mailing list archive at > >>>> Nabble.com. > >>>> >> >> >> > >>>> >> >> >> > >>>> >> >> > > >>>> >> >> > > >>>> >> >> > -- > >>>> >> >> > Cheers, > >>>> >> >> > Guillaume Nodet > >>>> >> >> > ------------------------ > >>>> >> >> > Blog: http://gnodet.blogspot.com/ > >>>> >> >> > > >>>> >> >> > > >>>> >> >> > >>>> >> >> -- > >>>> >> >> View this message in context: > >>>> >> >> > >>>> >> > >>>> > http://www.nabble.com/servicemix-http-Post-support-tp16418421p16427193.html > >>>> >> >> Sent from the ServiceMix - User mailing list archive at > >>>> Nabble.com. > >>>> >> >> > >>>> >> >> > >>>> >> > > >>>> >> > > >>>> >> > -- > >>>> >> > Cheers, > >>>> >> > Guillaume Nodet > >>>> >> > ------------------------ > >>>> >> > Blog: http://gnodet.blogspot.com/ > >>>> >> > > >>>> >> > > >>>> >> > >>>> >> -- > >>>> >> View this message in context: > >>>> >> > >>>> > http://www.nabble.com/servicemix-http-Post-support-tp16418421p16446910.html > >>>> >> Sent from the ServiceMix - User mailing list archive at > Nabble.com. > >>>> >> > >>>> >> > >>>> > > >>>> > > >>>> > -- > >>>> > Cheers, > >>>> > Guillaume Nodet > >>>> > ------------------------ > >>>> > Blog: http://gnodet.blogspot.com/ > >>>> > > >>>> > > >>>> > >>>> -- > >>>> View this message in context: > >>>> > http://www.nabble.com/servicemix-http-Post-support-tp16418421p16452156.html > >>>> Sent from the ServiceMix - User mailing list archive at Nabble.com. > >>>> > >>>> > >>> > >>> > >>> -- > >>> Cheers, > >>> Guillaume Nodet > >>> ------------------------ > >>> Blog: http://gnodet.blogspot.com/ > >>> > >>> > >> > >> > > > > > > -- > View this message in context: > http://www.nabble.com/servicemix-http-Post-support-tp16418421p16471350.html > Sent from the ServiceMix - User mailing list archive at Nabble.com. > > -- Cheers, Guillaume Nodet ------------------------ Blog: http://gnodet.blogspot.com/