Distinguished field on a web service (BizTalk) - web-services

How do you access a field in the message returned by a web service call ?
I found Richard Seroters blog post but it says to drill through the Reference.map to the Reference.xsd ...
- problem is, I've not got a Reference.xsd
- I do have the Reference.map, and the child Reference.odx
- I also have the wsdl, but not the disco

It would seem that ...
If the method includes something other than primitive data types, there will also be a Reference.xsd file under Reference.map. After adding this reference, we’ll be able to create messages to communicate with the web service defining the type as a Web Message and choosing the appropriate schema.
and the web services I'm talking to just return a string, albeit actually XML
From this blog post

I am confused as to why you do not have an XSD that was generated by the BizTalk proxy? You can of course tag the generated proxy code class with attributes that will allow you to set the field as a promoted property or a distinguisted field. If you do not have either I am not sure you can do it. Take a look here.
-Bryan

Related

C++ RESTful Service Router Pattern

I've been searching around for the past few days trying to find a good article that addresses what I'm trying to do, but haven't really found much yet. Most point me in the direction of pre-existing C++ MVC frameworks.
I have a C++ application with a tiny embedded web server that responds to HTTP requests. What I want to do is create a routing pattern in which I can define service end points and the application will be able to use the proper C++ controller class.
For example, I could define my service end points like the following in a text file:
POST /login UserController::login()
GET /user UserController::get()
GET /dashboard DashboardController::get()
And have the C++ application call the appropriate class and static method based on the service I'm invoking. So in the case of the above example, if I submit an HTTP POST request to /login, then the Router should invoke UserController::login(). Service end points don't necessarily have to be defined in a text file, there could be another in-memory data structure they can be defined in.
I've been considering something like the Proxy pattern: http://en.wikipedia.org/wiki/Proxy_pattern
Or I was looking at this pattern: http://gameprogrammingpatterns.com/service-locator.html
Before going too far down a specific implementation I wanted to get some feedback from others on how they might go about implementing such a requirement?
Thanks!

How to use servlet filters with Pax-Web and the whiteboard pattern

Registering filters with whiteboard.
Hi,
I'm trying to use a Servlet filter with a servlet. I'm using Pax-Web 3.0, Declarative services and whiteboard.
I have to declarative service components (one for the servlet and one for the filter), and it seems to work fine.
Looking at the documentation I see the following sentence:
For URL Patterns, the pattern registered must be already mapped,
either as Resource or a Servlet alias - e.g there should already be a
Resource or aServlet registered to the path /foo. For Servlet names,
the names used should have been the name that has been explicitly
given to the Servlet (as servlet-name), when registering.
How can I guarantee that in a whiteboard setting? I have no idea when the servlet actually gets registered. I guess I can list the servlet as a dependency of the filter, but that makes it tricky to use the filter for multiple servlets.
Is there a better way?
regards, Frank
It seems highly unlikely that this is an issue. I expect that the sentence from the documentation indicates that your filter just never get called when there is no destination for the path. I.e. the filter is only called when there is a valid destination (a resource or servlet). A basic aspect of the whiteboard is that you should not care about these issues. It is the responsibility for the whiteboard to handle the http service, the filters, and the servlets in any possible registration order. If not ... it needs a serious issue raised.
I have not looked at the code but I am a heavy user of the whiteboard + filter + servlet + DS and never have seen an issue.

How to call a webservice programmatically in asp.net

How to call webservice programmatically in asp.net without using add web reference?
My webservice url keeps on changing. Hence i need to capture the url at runtime and display the results.
Please advice.
You can change the URL of a web-reference at runtime (provided that the new address is hosting a service with the same schema that you originally used to create the reference):
MyWebService ms = new MyWebService();
ms.Url = "http://example.com/webservice.asmx";
ms.MyWebMethod();
Web References are definitely the way to go - whilst the classes that are created by the web reference are usually pretty heavy, all that strong typing makes it well worth your while.
you need to do the following steps.
PreReq :
First of all, you know the URL of web service.
Solution:
use wsdl.exe to create a proxy class and than compile it.
wsdl /out:myProxyClass.cs http://hostServer/WebserviceRoot/WebServiceName.asmx?WSDL
(there are other switches available
for wsdl. For Example to generate VB
class, you need to add switch
/language:VB)
Once your proxy class is generated you can easily consume in code.
MyProxyClass objService = new MyProxyClass();
DateTime time = objService.GetServerTime(); //Suppose service has method getServerTime
You can specify the end-point URL as part of the constructor of your client-side proxy class.
If you don't need to specify it during runtime then it can also be set in your web.config file.
Where are you trying to call the service and where the service file is located?
If the service is located on the same site. Why not just instantiate the class name from the service. Or just create a separate class and use interface

Should I be using the xfire plugin with Gralis or is there a better way?

I have a web service in Grails, published using the xfire plugin. It's all fine and can be connected to no problem at all. But I'd like to modify the format of the request and response. Is that possible?
The example structure is:
Domain class Person, has many Siblings. Each Sibling has a Child.
My web serice method currently looks something like this:
Person updatePerson(Person person) {
return Person.getById(person.id)
}
But that produces a WSDL with the format:
Person
Person fields
Sibling
Sibling fields
Child
Sibling
Sibling fields
etc etc.
I don't want to accept the data in this format, or return it in that format. Is there a way of specifying which fields are exposed to the web service and what the WSDL should look like, or is xfire the wrong plugin to use for this?
I would answer this as its creator.
To exclude some domain properties, add:
static xmlTransients = ['your_property_goes_here']
to your domain classes.
However, the plugin does not allow you to control creation of the WSDL directly.
I would recommend looking at the Spring WS plugin. It's designed around "contract-first" web service development, so you have complete control over the resulting WSDL. The Xfire, Axis and Metro plugins are all great, but from my experience are all geared towards code-first and don't allow direct control over the resulting interface/output.

"Duplicate file name" for same WSDL namespace when using web-service from different sub-domains

Preface
We are providing customers with our service API.
Each customer has own subdomain (e.g. sergii.ourwebsite.com) and own WSDL URL, it looks like http://sergii.ourwebsite.com/api/bsapi.cfc?wsdl
Also, all the websites (including API, of course) using the same codebase.
Problem
Say, two applications on same CF-server. This can easily happen, because some of customer websites are hosted on our servers.
Both trying to use own API WSDL, say:
http://sergii.ourwebsite.com/api/bsapi.cfc?wsdl
http://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl
And here come the problems.
When second website tries to register the web-service, CF throws an error:
Name:
https://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl.
WSDL:
https://galashyn.ourwebsite.com/api/bsapi.cfc?wsdl.
org.apache.axis.wsdl.toJava.DuplicateFileException:
Duplicate file name:
/opt/coldfusion8/stubs/WS1985941973/api/Bsapi.java.
Hint: you may have mapped two
namespaces with elements of the same
name to the same package name. It is
recommended that you use a web browser
to retrieve and examine the requested
WSDL document to ensure it is correct.
If the requested WSDL document cannot
be retrieved or is dynamically
generated, it is likely that the
target web service has programming
errors.
Problem is that both of them are using same WSDL namespace, built from CFC path:
<wsdl:definitions targetNamespace="http://api">
Current solution
The only working solution for us is using the CFC aliases, like:
http://galashyn.ourwebsite.com/api/v1n1/bsapi.cfc?wsdl
http://galashyn.ourwebsite.com/api/v1n1/bsapi.cfc?wsdl
Each this CFC extends the parent like this:
<cfcomponent output="false" extends="api.bsapi">
<!--- this component used to extend base api version 1.x --->
</cfcomponent>
They produce different namespaces, which can be used without problems -- own namespace for each application:
<wsdl:definitions targetNamespace="http://v1n1.api">
<wsdl:definitions targetNamespace="http://v1n2.api">
This is pretty dumb workaround, but it works for now.
Other solution would be to use the single API sub-domain and identifying the customers by some key (we are already using them for security purposes), but it has serious negative problems for us because of some legacy code.
Please note that I don't know Java, so many specific advices are not so clear for me.
Google shows that this problem exists for years, but I can't find the smart solution.
So maybe here?
I can not "place the WSDL at a common URL for all customers" for now and I've explained why: because I have to use the sub-domains. If you know the way to put the WSDL at one URL and make service requests to another -- please tell me.
A WSDL is just an XML document that describes the web service. You can write (customize) it using CFML. For instance:
http://subdomain.domain.com/api/wsdl.cfm?api=bsapi&customer=subdomain
Then just copy the WSDL generated by CF, and use it as a template for your custom WSDL page. Replace the parts of the WSDL that are subdomain-specific and return the XML document. Be mindful of whitespace (perhaps see CFSilent, CFSetting), and consider using CFHeader to set the mime type to "text/xml".
Do all the customers use the same WSDL? Then place the WSDL at a common URL for all customers.
I also think you need to find out exactly what the error message means. I don't see where it has anything to do with the URL being used. If it had mentioned the URL of another customer, I'd have understood.
Part of this may be due to my lack of understanding of how CF works. In particular, what is this "registering web services" that triggers the problem when two customers do it?
Did you realize that the URL in the <soap:address/> element in the WSDL is only a hint? In many clients, it can be overridden. In a .NET client, just set the Url property of the proxy class. This should allow you to have a single WSDL at a single location, and yet have your customers each reference the proper subdomain, assuming there's some way to convey that information to them. For instance, if there is a way for you to know which customer is making the call, then perhaps you could receive calls on one URL and then redirect to the proper URL, or else use a SOAP Routing infrastructure to route to the correct one.
I hope you are not changing the namespaces from one customer to another. Namespaces have nothing to do with URLs, even if they happen to look like URLs.
There is a namespace attribute for the cfcomponent tag. You should be able to use this, along with cgi.host_name (? I'm at home, without docs) to specify a namespace that matches the subdomain being queried.
Something like:
<cfcomponent namespace="http://#cgi.host_name#/api/v1n1/bsapi.cfc">
Have caught this error message when tried to CFINVOKE webservice from localhost by test script located on same localhost (but in different folder). Sounds 'buggish' for me.