Connect to different servers offering the same web service with WSDL - web-services

I'm entirely new to web services and all I've been able to do is a Hello World
My situation is the following, I have some servers which provide a WSDL file, all the servers provide the same file and methods, they just have different IPs/ports. In addition each server contains its own set of users.
I know how to communicate to work with one WSDL at a time, but I need 2 things:
Being able to add web services dynamically (connect/disconnect to other servers)
Being able to perform methods on the right server as the right user (you cant make a request if your user does not exist on the server you are asking to)
I have no idea of where to start, can someone point me in a direction to solve those 2 problems?

You're not specific in terms of libraries you use.
For example if you use CXF (Jax-WS in general) you can do the following:
// change endpoint URL
((BindingProvider)service).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "new url");
// new username. password will be provided by WS callback
((BindingProvider)service).getRequestContext().put(SecurityConstants.USERNAME, "username");
If you're using Spring for the infrastructure you can autowire all proxies with one statement:
#Autowired
private Map<String, ServiceInterface> interfaces;
If you want to add web services dynamically you have to decide whether this dynamically means at any time or at application startup - this however has nothing to do with web services - it's general programming model of autodiscovery (you can use database, one single remote source of available services, etc.)

Related

How to define URLs only once for server and client?

everyone! I am building a web application, i.e. a server-client application. For the interaction between the two, I have to define the URLs twice (hard-coded strings), both on the backend and the frontend, which makes future changes hard, because it would require changing the code in two places, rather than just one.
I am using Django and Angular and so I am looking for a way to specify the back end endpoints once, then ideally read them and use them for the Angular production build. Therefore changes to the endpoints will only require a new build, but no further changes.
Should these be defined in some .cfg file and be read by the back end on server startup and maybe somehow add them to the Angular's build process? Any suggestion would help because this redundancy comes in almost every webapp project and there has to be a more clever solution!
Thanks for the help in advance!
Here, it is the backend application that owns and defines url mappings to entities. It is possible that multiple clients can consume from the same API, like a web client, an Android client and an iOS client. In this setup, your backend is the point of truth for the url mappings, and client applications should be configured to use the url mappings defined in the backend application.
One possible way to do this is to serve defined urls in the backend on a path of the backend application, and have your client applications configure themselves using the data provided there. For example, if you use Django Rest Framework, by default, on the root path of the API ("/"), resources along with url mappings for the resources are served. You can use such a mechanism to configure your client applications on build time.
How many endpoints and how likely are you to alter them? Most likely you will always have to make more changes than just in 1 place as the reason behind changing an endpoint is normally you are trying to POST or GET new data structures. This would mean you will have to alter that request process anyway to handle the new data type or what was being posted.
Also, consider some of the publicly available api's out there - they don't give you an endpoint that serves a config file of available routes. When they make a change to their endpoints they usually create a versioned api so that consumers can upgrade in their own time.
In my opinion, unless you are planning a large scale web app, I wouldn't be too worried about trying to implement something like this.

Add a request header from the url, to support multi-tenancy

Background
I have an existing service contract which cannot be modified. The implementation of the service is code which I support and can change.
Currently, the service supports a single tenant, and multiple instances of this service are hosted, for example http://foo-tenant1.com/service.svc and http://foo-tenant2.com/service.svc
Now I want to change the service to support multiple tenants, with a single service. For example, the service hosted at address: http://foo.com/service.svc and support for multiple tenants by adding a tenant id to the address;
for example:
If WCF can somehow support wildcard routing:
http://foo.com/tenant1/service.svc and http://foo.com/tenant2/service.svc etc...
or if it can somehow support query strings:
http://foo.com/service.svc?tenant1 and http://foo.com/service.svc?tenant2 etc...
or some other way...
The reason for this is that the clients calling this will not have any concept of a tenant. From the client's perspective there is only a Url for each tenant.
Question
How can I host a WCF service with a "catch all" endpoint like this? Or can I do this with routing or url rewriting? I can then get the tenant Id into a request header, and modify the service code to support multi-tenants.
I can then change the service code to read from the request header and support the tenant Id.
If you don't have access to the code for the service or can't change the code, you'll need to think a little outside the box. One option would be to create separate applications inside IIS and hopefully your service allows you to change web.config values such that you can configure the service to look at a different database (if that's what is backing it).
But if the web.config route doesn't capture all of your variables, you might have to think about doing an IHttpModule. Injecting that early enough in the service stack would give you options to do what you will with the URL, though you still don't have control over the code that subsequently gets called unless you completely override what gets called and don't call the base method to continue execution.
You could also write a page for 404's that you have control over the backing code such that you can then do something dynamically at that point. You would just need to modify the web.config file to point 404's to the URL and execute it. Though be warned, that is all 404s.
Finally, if the code that implements the service contract can be removed, you could drop a DLL onto the server that implements the contract and update the web.config file to point to this DLL instead. Though this might not be possible if the DLL that you remove also removes a significant portion of other code.
If you don't have access to the code, you are going to have a tough time as all of these solutions are pretty advanced concepts.

Can a web service client with identical signature call a different web service?

My project has gotten into web services lately, but our QA team has a request to be able to set up a clone client and clone web service so that they can issue a request from the clone client to the real web service and from the real client to the clone service to test the real pieces individually.
The clone client to real web service part is easy, I just wrap the generated client in a main() app that picks up data to send that the test team specifies. But the service part is confusing to me. How can I make a dummy service that just echoes out its requests to a log without affecting the real service? I want the real client to use the same generated client code, just point the soft-coded URL to the URL of the dummy.
If I define a new web service with identical names and signatures to the real service, can the real client hit the dummy with just a URL change? Or is it more complicated? Am I barking up the wrong tree?
Re: Making a dummy service
This would actually be called making a "mock" service or a web service "stub". You don't even technically have to code it - you can use tools. For example, SoapUI has the ability to import a WSDL and create a mock service. The have some other discussion of mock services as well - they can be used both to test the client application (or to simply develop it before the back-end resources are ready or available). To use a WSDL-based service stub you would simply change the endpoint of your client-under-test to the stub instance. SoapUI will show you (and let you configure) the stub's endpoint URL.
The trendy term for service mocking and stubbing is "service virtualization" (not to be confused with server virtualization as in virtual machines). Searches using this terminology will find you even more powerful (and expensive) tooling.
Re: Just a URL Change
Yep, for the most part. So long as the XML namespaces are the same and the WSDL is the same (minus endpoint URL) you should be fine. Since the WSDL acts as an interface contract, the stub MUST accept those same inputs and produce those same outputs. How it does so, of course, is up to you.
PS - free extra advice - Don't code a dummy client. Use tools (I'll use SoapUI again as an example free tool) to make your web service testing more robust and repeatable. You can create test suites with sample SOAP requests, add assertions on how the service should behave, and best of all - your investment in time of creating a test project can be shared across team members, cutting down time to test setup and making sure testing is thorough and repeatable. If you code a client, every tester/user of the test client will have their own way of testing, response inspection will probably be manual, and you'll notice when your best QA tester goes on vacation because regressions slip into the web service product. Repeatable testing can nix this, and tool based automated functional testing is the bees knees. You're already on the right path by testing the pieces individually.

How to do SSO between two web services in intranet?

The two web service(rest) are running on separated JVM instances with its own authentication.
The services is used by external user's log in, the server2 is for customer service team. After external use log in, he can call server2 for query. Oppositely, after customer service guy log in server2, he also can call server1 to change external user profile.
In another word, these two services trust each other. It seems like a SSO between them. Since both of them run on internal environment, I am wondering if there is a simple solution to implement it.
Thanks
I've had a good experience with JOSSO:
The setup is relatively simple (gateway and partner applications)
Non intrusive (no big changes needed for your application to work with it)
Based on JAAS
Supports various stores (LDAP, XML, DB...)
Works with Java, PHP and ASP (we use Java and PHP at our company and it works flawlessly)
You've got a lot of different options:
You could roll your own authentication system. It'd be exactly what you need, but you get to debug it yourself.
You could deploy Kerberos. A little old-school, but it clearly differentiates login servers from trusting servers.
If you're already in an MS-heavy environment, Active Directory might be just the tool.
OpenID is the new kid on the block; as used by StackOverflow :) but implementations of servers and clients might be harder to find.
LDAP is an easy way to get site-wide directory services; actually doing authentication against it might be a bit more work. (Which is why Active Directory is as popular as it is -- combining LDAP with Kerberos into one mechanism for site-wide authentication and authorization. Neat.)

CXF WebService Client generation: Use existing Domain Model classes

I have got a web application which is speparated in a GUI (JSF 2.0, Orchestra, Spring) and service (Spring, JPA, Hibernate,...) project. Due to network issues between the web server and the database server, I neet to split the application completely, between the layers and deploy them on two different tomcats, for the service part close to the database server. I have generated allready a webservice and a webservice-client with the Eclipse WTP CXF Plugin.
My Problem is: For the client it generates a copy of the domain model classes, so I can't use them directly in my gui project and would need to introduce an conversion layer, between the web service client and the gui layer. Wich is cumbersome and error prone.
Is there a possibility to generate the web service client (out of the existing web service module and the wsdl) using the shared domain model (model classes are in an separate project, wich both - service and gui - projects depend on)?
desperatly looking for a solution, as the deployment deadline is close...
To generate a copy of the domain model classes (DTOs) is a good practice when you have two physical layers : Your Hibernate POJOs need to be deproxyfied before being sent to an other physical layer. Maybe you could use Dozer to do it, to avoid to spend too much time doing it.
Maybe you should use RMI instead of Web Services if you need performances.
If you're absolutely determined to use your domain objects in the presentation layer, you should look about Gilead (formerly known as Hibernate4GWT).
Pure DTOs, DTOs with Dozer, and Gilead use are described in details here :
http://code.google.com/intl/fr/webtoolkit/articles/using_gwt_with_hibernate.html