BizTalk 2006 R2 EDI - web-services

I have an working orchestration in place to process X12 messages. Now I need to expose the orchestration as a webservice (ASMX) that accepts a text input (the X12 message) and returns the text response (the X12 response). If I try to use the wizard, the generated webservice will expose the inner XML representation of the X12 request and not the its original plain text representation.
In short, I want to be able to connect to a webservice (ASMX and not a WCF service), send a X12 request (plain text) and get the appropriate response (also plain text).
I've seen examples of this using WCF, but none with a simple webservice.
Can you give me a hand with this?
Thanks!

One possible solution would be to create a SOAP handler to convert the plain text to the xml representation (so BizTalk can read it) and back again. While I haven't tried this myself, it might work. You would need to create a handler for the request and one for the response to intercept the string and convert it to the xml schema and back again. You can also look at using a generic XML document instead of a string, that might be easiest. Check out this post:
http://blogs.msdn.com/richardbpi/archive/2006/11/10/exposing-biztalk-web-services-that-accept-generic-content.aspx
-Bryan

While I haven't tried, I have a feeling you will not be able to do that without some degree of custom coding in the pipeline.
When you publish the web service using the wizard, BizTalk takes the schemas involved and uses them as the types for the web service, this makes sense in almost all cases, but not in yours.
However , as far as I know, there is no good way to take and EDI message over SOAP; you could create your web service to accept a string message and have the client "know" that it needs to be X12, but there's no way to describe that in the WSDL.
If you would do that, however, you will get the X12 message into the pipeline, wrapped in a element (or somehting like that, depending on how you've modified your web service), before you get to the disassembler and to the orchestration you will have to have some code to strip that out, but that should be relatively easy to write.

I would also Translate my x12 260 file to SOAP Webservice . what are the best way... iam converting to XML & sending to SOAP... but here a problem is i get only 3 xml's which has only Transaction Details inside that file.... where are my Header & Trailers gone :(
Anyone faced such issue

Related

Genexus - Mark unrecognized procedure parameters as ignorable in webservices

I have procedures that are exposed as Webservices (REST):
I need it to be able to parse the request body ignoring unrecognized fields (that are not specified
in "rules"). Right now, when procedures tries to parse something that is not defined within the parameters, they throw the following error:
Example:
Some procedure has the following definition:
parm(in:&parm1, in:&parm2, out:&someResponse);
Then we change to:
parm(in:&parm1, in:&parm2, in:&parm3, out:&someResponse);
The web service is updated on some distributions, but on some they're still on the old version with 2 in parameters.
The service that consumes these web services on different APP distributions are sending the body with the second (latest definition).
{
"parm1" : "somevalue",
"parm2" : "somevalue",
"parm3" : "somevalue"
}
Unfortunately we don't have control of the third party that is consuming our web services, so in that case, it would be a lot easier if unused parameters could be ignored...
USING GX 16 U11 - Java Generator
Unfortunately there is no way in GeneXus 16 to "catch" the request and do something previous to the object logic. In GeneXus 17 we have the new API object, there you can transform the parameters.
But, not everything is lost. Taking into account you're generating in Java, there is an "external way" to do it with Filters. I used them to log the client requests for debugging purposes.
If you don't want to mess with the code, there is also API Gateways you could put in front of your API services to redirect the requests to the right service. Bear in mind that I'm not a specialist in this topic, maybe a post in ServerFault would help.

Spring WS endpoint routing when whole body is encrypted

So I'm working with Spring Boot to implement a service API for interop with a third party. I'm using payload-based routing because they are not sending SOAPAction or any addressing information. However, when a request comes in, it's trying to map one of the incoming encryption-related elements and failing to map. I think the problem is that my friends at the third party are element-encrypting the operation element:
<n1:body>
<n2:SomeOperation> // This is
...some content... // all
</n3:SomeOperation> // encrypted
</n1:body>
From my reading, Spring attempts to map to an endpoint before encryption, so payload mapping will never work. I could use #Action or #SoapAction, but they are using Soap 1.2 (so no action header) and not using addressing. I have also verified that the Wss4SecurityInterceptor is being added, but is never called when a request is made.
Is my assessment/understanding of the situation correct? Can anyone think of any workarounds, because having the remote party change anything is nearly impossible.
A related question (hopefully asking one is not too unorthodox): I was trying to make my test client only encrypt the content of my operation element, but my setSecurementEncryptionParts() call is not playing nice. Here's the outgoing payload(from the console):
<ns2:EchoTestInput xmlns:ns2="http://xml.netbeans.org/schema/EchoTestSchema">
<ns2:valueIn>Quack</ns2:valueIn>
</ns2:EchoTestInput>
And here's the call to setSecurementEncryptionParts()
securityInterceptor.setSecurementEncryptionParts("{Content}{http://xml.netbeans.org/schema/EchoTestSchema}EchoTestInput");
I thought this should all be easy, but I guess not. Thanks a million in advance!

Apache camel to aggregate multiple REST service responses

I m new to Camel and wondering how I can implement below mentioned use case using Camel,
We have a REST web service and lets say it has two service operations callA and callB.
Now we have ESB layer in the front that intercepts the client requests before hitting this actual web service URLs.
Now I m trying to do something like this -
Expose a URL in ESB that client will actually call. In the ESB we are using Camel's Jetty component which just proxies this service call. So lets say this URL be /my-service/scan/
Now on receiving this request #ESB, I want to call these two REST endpoints (callA and callB) -> Get their responses - resA and resB -> Aggregate it to a single response object resScan -> return to the client.
All I have right now is -
<route id="MyServiceScanRoute">
<from uri="jetty:http://{host}.{port}./my-service/scan/?matchOnUriPrefix=true&bridgeEndpoint=true"/>
<!-- Set service specific headers, monitoring etc. -->
<!-- Call performScan -->
<to uri="direct:performScan"/>
</route>
<route id="SubRoute_performScan">
<from uri="direct:performScan"/>
<!-- HOW DO I??
Make callA, callB service calls.
Get their responses resA, resB.
Aggregate these responses to resScan
-->
</route>
I think that you unnecessarily complicate the solution a little bit. :) In my humble opinion the best way to call two independed remote web services and concatenate the results is to:
call services in parallel using multicast
aggregate the results using the GroupedExchangeAggregationStrategy
The routing for the solution above may look like:
from("direct:serviceFacade")
.multicast(new GroupedExchangeAggregationStrategy()).parallelProcessing()
.enrich("http://google.com?q=Foo").enrich("http://google.com?q=Bar")
.end();
Exchange passed to the direct:serviceFacadeResponse will contain property Exchange.GROUPED_EXCHANGE set to list of results of calls to your services (Google Search in my example).
And that's how could you wire the direct:serviceFacade to Jetty endpoint:
from("jetty:http://0.0.0.0:8080/myapp/myComplexService").enrich("direct:serviceFacade").setBody(property(Exchange.GROUPED_EXCHANGE));
Now all HTTP requests to the service URL exposed by you on ESB using Jetty component will generate responses concatenated from the two calls to the subservices.
Further considerations regarding the dynamic part of messages and endpoints
In many cases using static URL in endpoints is insufficient to achieve what you need. You may also need to prepare payload before passing it to each web service.
Generally speaking - the type of routing used to achieve dynamic endpoints or payloads parameters in highly dependent on the component you use to consume web services (HTTP, CXFRS, Restlet, RSS, etc). Each component varies in the degree and a way in which you can configure it dynamically.
If your endpoints/payloads should be affected dynamically you could also consider the following options:
Preprocess copy of exchange passed to each endpoint using the onPrepareRef option of the Multicast endpoint. You can use it to refer to the custom processor that will modify the payload before passing it to the Multicast's endpoints. This may be good way to compose onPrepareRef with Exchange.HTTP_URI header of HTTP component.
Use Recipient List (which also offers parallelProcessing as the Multicast does) to dynamically create the REST endpoints URLs.
Use Splitter pattern (with parallelProcessing enabled) to split the request into smaller messages dedicated to each service. Once again this option could work pretty well with Exchange.HTTP_URI header of HTTP component. This will work only if both sub-services can be defined using the same endpoint type.
As you can see Camel is pretty flexible and offers you to achieve your goal in many ways. Consider the context of your problem and choose the solution that fits you the best.
If you show me more concrete examples of REST URLs you want to call on each request to the aggregation service I could advice you which solution I will choose and how to implement it. The particularly important is to know which part of the request is dynamic. I also need to know which service consumer you want to use (it will depend on the type of data you will receive from the services).
This looks like a good example where the Content Enricher pattern should be used. Described here
<from uri="direct:performScan"/>
<enrich uri="ServiceA_Uri_Here" strategyRef="aggregateRequestAndA"/>
<enrich uri="ServiceA_Uri_Here" strategyRef="aggregateAandB"/>
</route>
The aggregation strategies has to be written in Java (or perhaps some script language, Scala/groovy? - but that I have not tried).
The aggregation strategy just needs to be a bean that implements org.apache.camel.processor.aggregate.AggregationStrategy which in turn requires you to implement one method:
Exchange aggregate(Exchange oldExchange, Exchange newExchange);
So, now it's up to you to merge the request with the response from the enrich service call. You have to do it twice since you have both callA and callB. There are two predefined aggregation strategies that you might or might not find usefull, UseLatestAggregationStrategy and UseOriginalAggregationStrategy. The names are quite self explainatory.
Good luck

Timestamp of server from a web service call

Is there a way that I can retrieve the timestamp of a web service call? I'm trying to get the time of the server hosting the web service.
Easiest thing to do is to just log them in the server implementation of your service contract, you can use PostSharp to make some attributes to take of this aspect.
For instance, you can write a Trace attribute which simply logs a debug message when a method is invoke. Here's one I wrote a while back which tracks how long a method takes and log a warning message if it takes longer than a set threshold:
http://theburningmonk.com/2010/03/aop-method-execution-time-watcher-with-postsharp/
I came across some 'trace' attribute example before, if you want I can look for it for ya.

BizTalk Send Flat File to Web Service

I currently have a BizTalk 2006 (r1) application which receives XML from a SQL stored proc using the SQL adapter. It maps this to another schema before sending out to a 3rd party. The send port uses a custom pipeline component which converts the XML to a flat file - in the format required by the customer. I don't use any orchestration, this is a pure message based solution.
This all works great when sending via FTP. However, the 3rd party have now requested that I push the message to a web service they hosy. I haven't received the WSDL yet but can assume that the method I'll be calling simply receives a string as a single parameter.
Could anyone advise on the best way to approach this please? I have created a simple web service stub. I then followed Recipe 6-11 from the excellent BizTalk 2006 Recipes book, generating a proxy class using wsdl.exe which I then reference from the "web service" tab of the SOAP send port. However, when processing an order I get the following message in the event log:
Could not load type 'WSProxy' from assembly 'Direct.IS.Payment.Components, Version=3.1.145.0, Culture=neutral, PublicKeyToken=dc03da781bea1472'.".
The type must derive from System.Web.Services.Protocols.SoapHttpClientProtocol.
The type must have the attribute System.Web.Services.WebServiceBindingAttribute. ".
Next step will be for me to play around with the proxy so that it address the derive and attribute issues mentioned in the even log message. However, I can't help but think that there must be an easier way?
Thanks
The custom pipeline component you have created is not producing a message that is suitable for SOAP transmission. Not knowing what the end customer is going to do, I'd hold off on trying ot make SOAP work. In the mean time, just spin up an ASPX page with the following code:
private void Page_Load(object sender, EventArgs e)
{
StreamReader reader = new StreamReader(page.Request.InputStream);
String xmlData = reader.ReadToEnd();
}
Add code to write XMLData to a DB or to a text file or something to see what it is. This is very crude and does not send a response code. It should get you started.