In short, what I'm looking to achieve is the ability to run wsdl2java and generate extra code. Has anyone done this and can offer hints/tips/advice, has anyone done anything similar with a different approach the one outline further down the question (a lot further down)?
In the long form:
Background:
We have a third party piece of software that is used extensively in many projects but it has no ability to integrate directly with web services. With this in mind we take the wsdl, generate the client and then have a lot of boilerplate code that sits on top to allow integration. I've spent some time stream lining this but I want to go the whole hog.
Current standing:
I've written a simple first generation code generator which handles the creation of 95% of the code however this is reads in a hand written xml config, outputs the code using FileWriter(eugh), but I still need to hand write the code to tie it pass info to/from the actual webservice client code. This was just a quick and dirty solution as I needed it fast, and also to act as a POC.
Approach to solving this:
I'm picking this up in my own time purely because I think its a interesting problem but as such I don't want to waste lots of it on a dead end approach.
I believe the way to achieve my goal is to write an extension to the code generation module as described here http://wso2.org/library/35, I belive by writing this extension I will get access to the axis model of the wsdl and can apply my own xslt to it.
If you agree and have done similar, is there any advice you care to share, or useful resources you can point me to.
If you disagree with my approach I'd appreciate a brief outline( don't want to waste your time) of why and suggestion for a new approch.
I have never extended the Axis2 WSDL2Java emitter so I don't know how much flexibility you would gain from doing so. The article you reference suggests that you can hook into the generation process quite easily. It really depends on what you have to generate.
Recently I had to do create boilerplate code from Database schemas and WSDLs and I have used a mixed approach:
Groovy
Groovy is great for rapid prototyping and templates. You can, for instance, collect information from a Database or a Wsdl and emit code based on a template. Here you can see some examples: http://groovy.codehaus.org/Groovy+Templates
PMD API
PMD is a tool to scan Java code and report potential problems. It also exposes an API for parsing code using XPATH and has a very rich model to work with. You can do stuff like:
final Java15Parser parser = new Java15Parser();
final FileInputStream stream = new FileInputStream("VehicleServiceType.java");
final Object c = parser.parse(new InputStreamReader(stream));
final XPath xpath = new BaseXPath("//TypeDeclaration/Annotation/NormalAnnotation[Name/#Image = 'WebService']",
new DocumentNavigator());
for (final Iterator iter = xpath.selectNodes(c).iterator(); iter.hasNext();) {
final Object obj = iter.next();
// Do code generation based on annotations...
}
Personally, I have found that a mixed approach works better then a monolithic one. Code generation is often an art more then a science.
One more thing: in my current project, I'm looking at Python for (simple) code generation. It has a very nice templating library (jinja), but I wouldn't recommend it for parsing Java code.
Hope this help!
You've already started writing a code generator to achieve your end so you could try continuing on this path. The codemodel library is a pretty amazing library for generating code. I have just recently used it to generate code and it was very good.
I'd suggest you give this codemodel library a try to generate the code you require. This is the codemodel library written for jaxb wsdl to java compiler.
We've used wsdl2java a lot (but in axis 1.4) My only tips are:
1 use complex/structured types as the arguments to operations e.g. resetWidget(widgetStruct) where widgetStruct class contains the fields widgetId, widgetName, widgetType etc instead of resetWidget(arg1, arg2, arg3..). So next year when you extend the WSDL and add some more params all the legacy code will still compile without have to extend all your methods. This approach was actually forced on us because another (old) WSDL tool didn't generate the responses correctly if we passed all the fields as params.
2 Put all you business logic into other classes. So when you regenerate the skeleton you can just put back in a few lines of code instead of having to update huge chunks of code.
Maybe some of these problems are solved in Axis2.
Further research revealed that the way to go was to create a new CodeEmitter based on AxisServiceBasedMultiLanguageEmitter.
Unfortunately this project was canned as there stopped being a requirement to create the web service clients. The third party piece of software released a new version allowing it to directly consume web services.
Related
I have a requirement where I need to put some logic to calculate the rank of some entity (for example a site user eligible for bonus prize). This logic changes very often depending upon the sales, available products, season etc. Also, different installations of the application will have different logic to calculate this rank. I am not sure where should I put this logic. If I put it in java I would have to go for frequent deployments. Getting it through webservice too doesn't looks that promising.
I heard Drools can be used in such scenarios but I have never used it in past. Any help in this regards is highly appreciated.
You should make the classes that implement this logic as decoupled as possible. Use well defined interfaces, and allow each installation to provide it's own implementation if necessary. A Dependency Injection framework, like Spring could be a great help.
Also, consider making your projects in a way that you can deploy independently API and implementation. Maven could help a lot on this.
You can place set of rules in JSON, XML file.
There will be a set of rules.
Your java program will read tags from that file to perform calculations.
For example:
<CalculateBonus>
<minVal>10</minVal>
<maxVal>30</maxVal>
</CalculateBonus>
Then java will read that file containing that rule and get all required data from it:
Int nonPremiumDiscount = 10;//got from file
Int premiumDiscount = 30;//got from file
if(person.isPremiumMember)
{
calculateDiscount(premiumDiscount,price);
}
else
{
calculateDiscount(nonPremiumDiscount,price);
}
If you design your program carefully you will be able to add new rules modify them without or with small change to the code.
That is just idea and would not work for you. But it is exactly what I am doing right now. I have different rules applying to different kind of objects in my code. So for example if I want to validate some additional objects/classes etc (Hope u get what I mean) I just add new rule to my file without even changing a code.
That is really simplified example. In my case I have more than 10 different files having aprox 100 rules each. All of them are in some way connected. So I have rules for general validation but there I include references to other rules in another file:
GeneralValidation -> ValidateEntities -> Something Else
I'm in a situation that I have a lot of of XMLs, that are sent to me from a server and I'm using JAXB or any API based on that architecture for building instances of objects.
The problem is, I have to per-determine the class that I want to unmarshall for at compile time. My solution that is in my mind, is to read the incoming XML object and based on some tags, I will direct the unmrashaller to make an instance of the specified class. That approach will let me have a lot of IFs statements and big state machine.
Is there a better design pattern or approach ?
Try using Apache digester 3, I think it can save you lots of "if"s and is not difficult to use at all.
Have a look at this article: http://www.javaworld.com/javaworld/jw-10-2002/jw-1025-opensourceprofile.html
I am looking for concrete ideas of how to manage a lot of different parameter settings for my java program. I know this question is a bit diffuse but I need some ideas about the big picture so that my code becomes more maintainable.
What my project does is to perform many processing steps on data, mostly text. These processing steps are algorithms of varying complexity that often have many settings. I would also like to change which processing steps are used by e.g. configuration files.
The reason for my program is to do repeatable experiments, and because of this I need to be able to get a complete view of all the parameters used in the different parts of the code, preferably in a nice format.
At this (prototype) stage I have the settings in source code like:
public static final param1=0.35;
and each class that is responsible for some processing step has its own hard coded settings. It is actually quite scary because there is no simple way to change things or to even see what is done and with what parameters/settings.
My idea is to have a central key/value store for all settings that also supports a dump of all settings. Example:
k:"classA_parameter1",v:"0.35"
k:"classC_parameter5",v:"false"
However, I would not really like to just store the parameters as strings but have them associated to an actual java class or object.
Is it smarter to have a singleton "SettingsManager" that manages everything. Or to have a SettingsManager object in each class that main has access to? I don't really like storing string descriptions of the settings but I cant see any other way (Lets say one setting is a SAXparser implementation that is used and another parameter is a double, e.g. percentage) since I really don't want to store them as Objects and cast them.
Experience and links to pages about relevant design patterns is greatly appreciated.
To clarify, my experiments could be viewed as a series of algorithms that are working on data from files/databases. These algorithms are grouped into different classes depending on their task in the whole process, e.g.
Experiment //main
InternetLookup //class that controls e.g. web scraping
ThreadedWebScraper
LanguageDetection //from "text analysis" package
Statistics //Calculate and store statistics
DatabaseAccess
DecisionMaking //using the data that we have processed earlier, make decisions (machine learning)
BuildModel
Evaluate
Each of the lowest level classes have parameters and are different but I still want a to get a view of everything that is going on.
You have the following options, starting with the simplest one:
A Properties file
Apache Commons Configuration
Spring Framework
The latter allows creation of any Java object from an XML config file but note that it's a framework, not a library: this means that it affects the design of the whole application (it promotes the Inversion of Control pattern).
This wheel has been invented multiple times already.
From the most basic java.util.Properties to the more advanced frameworks like Spring, which offers advanced features like value injection and type conversion.
Building it yourself is probably the worst approach.
Maybe not a complete answer to your question, but some points to consider:
Storing values as strings (and parsing the strings into other types via your SettingsManager) is the usual approach. If your configuration value is too complex to do this then it's probably not really a configuration value, but part of your implementation.
Consider injecting the individual configuration values required by each class via constructor arguments, rather than just passing in the whole SettingsManager object (see Law of Demeter)
Avoid creating a Singleton SettingsManager if possible, singletons harm testability and damage the design of your application in various ways.
If the number of parameters is big I would split them to several config files. Apache Commons Configuration, as mentioned by #Pino is really a nice library to handle them.
On the Java-side I would probably create one config-class per file and wrap Commons Configuration config to load settings, eg:
class StatisticsConfig {
private Configuration config = ... ;
public double getParameter1() {
return config.getDouble("classA_parameter1");
}
}
This may need quite a lot of boilerplate code if the number of parameters is big but I think it is quite clean solution (and easy to refactor).
I want to generate an object model out of an RelaxNG Schema.
Therefore I want to use the RNGOM Object Model/Parser (mainly because I could not find any alternative - although I don't even care about the language the parser is written in/generates). Now that I checked out the RNGOM source from SVN, I don't have ANY idea how to use RNGOM, since there is not any piece of information out there about the usage.
A useful hint how to start with RNGOM - a link, example, or any description which saves me from having to read understand the whole source code of RNGOM - will be awarded as an answer.
Even better would be a simple example how to use the parser to generate an Object model out of an RNG file.
More infos:
I want to generate Java classes out of the following RelaxNG Schema:
http://libvirt.org/git/?p=libvirt.git;a=tree;f=docs/schemas;hb=HEAD
I found out that the Glassfish guys are using rngom to generate the same object model I need, but I could not yet find out how they are using rngom.
A way to proceed could be to :
use jing to convert from Relax NG to XML Schema (see here)
use more common tools to generate classes (e.g. JaxB).
Hi I ran into mostly the same requirement except I am concentrating on the Compact Syntax. Here is one way of doing what you want but YMMV.
To give some context, my goal in 2 phases: (a) Trying to slurp RelaxNG Compact Syntax and traverse an object/tree to create Spring 4 POJOs usable in Spring 4 Rest Controller. (b) From there I want to develop a request validator that uses the RNG Compact and automatically validates the request before Spring de-serializes the request. Basically scaffolding JSON REST API development using RelaxNG Compact Syntax as both design/documentation and JSON schema definition/validation.
For the first objective I thought about annotating the CompactSyntax with JJTree but I am obviously not fluent in JavaCC so I decided to go a more programatic approach...
I analyzed and tested the code in several ways to determine if there was a tree implementation in binary, digested and/or nc packages but I don't think there is one (an om/tree) as such.
So my latest, actually successful approach, has been to build upon binary and extend SchemaBuilderImpl, implement the visitor interface, and passing my custom SchemaBuilderImpl to CompactSyntax using the long constructor: CompactSyntax(CompactParseable parseable, Reader r, String sourceUri, SchemaBuilder sb, ErrorHandler eh, String inheritedNs)
When you call CompactParseable.parse you will get structured events in the visitor interface and I think this is good enough to traverse the rng schema and from here you could easily create an OM or tree.
But I am not sure this is the best approach. Maybe I missed something and there is in fact an OM/Tree built by the rngom implementation (in my case CompactSyntax) that you can traverse to determine parent/child relationships more easily. Or maybe there are other approaches to this.
Anyway, this is one approach that seems to be working for what I want. Is mostly visitor pattern based and since the interfaces were there I decided to use them. Maybe it will work for you. Bottom line, I could not find an OM/AST that can be traversed implemented anywhere in the implementation packages (nc, binary, digested).
I'm out to create a fairly simple web service for intranet use. The service will ultimately be the interface to a DB that will allow me to keep track of what the various internal tools within the company are doing. I'm thinking I want a web service so that various tools (and thus different languages) within the organization can easily update the DB without needing to know the schema.
I've read many of the related REST vs SOAP questions already that come up from searching https://stackoverflow.com/search?q=soap+rest but I'm not sure I've found my answer.
My dilemma seems to be that I want the simplicity of REST while also having the code generation abilities of a WSDL, which seems to imply SOAP. It is of utmost importance to me that various internal tools (JAVA, Perl, Python, PHP, C++) be able to talk to this service and it would seem silly to have to rewrite/maintain the interface layer for each of these languages manually when the WSDL route would do that for me. From what I can tell, if the WS needs to change, you would update the WSDL, regenerate the client stubs, and make any changes necessary to the code that uses the stubs (which would need to be done anyway).
For example - say I have a tool written in JAVA that utilizes a RESTful web service. I imagine that the tool will have specific code for dealing with certain URLs, launching the request, doing something with the response, translating that into some data structure if I'd like, etc. Now lets say I also have a Perl tool doing the same thing. Now I'll need Perl code to do the same, make requests on specific URLs get the responses, do something with them, etc. In each case, and thus in C++ and Python and C#, where code cannot be shared, eventually I'll end up with a wrapper classes/methods that hide a lot of that ugliness from me. I'd much rather call a function on a class that returns my data encapsulated in an object instead of having to worry about the URL, the arguments, the response, etc. Sure, maybe its not a lot of code in any particular place but it starts to add up over time. Multiply that out over each of the tools and now when I make a change to the service I must go update the URLs in each CRUD operation and all that goes along with that. I guess I imagine that with a WSDL that is the aspect that is done for you. Your code simply interacts with the stubs. What the stubs do, who cares? Urls, arguments, responses - if anything changes just regenerate the stubs from the WSDL. If that process causes your code to break, so be it, but at least I didn't also have to update all the code that deals with the specifics of making the request and dealing with the response. Is this really not a problem? Perhaps what I need to do is just create a service and a few clients and see what I'm really up against.
While I'm a fairly seasoned programmer with experience in JAVA, Perl, Python, C++, etc, this is the first time I've considered authoring a WS and don't have prior experience with other WSs, so I'm looking for some guidance. Do I just go with WSDL/SOAP and forget about what everybody is saying about how popular, simple, and useful REST is?
I don't get the code generation issue here.
REST rarely requires any code generation of any kind. It's just HTTP requests with simple JSON (or XML) payloads.
You use the existing HTTP libraries (e.g. Apache Commons, or Python urrlib2). You use existing JSON (or XML) libraries. (the Jersey project has a nice JAXB-JSON conversion, for example).
What's "generated"? Our RESTful library in Java and Python are nearly identical and simply make REST requests through the HTTP library.
class OurService {
def getAResource( String argValue ) {
path = { "fixed", argValue };
URI uri= build_path( path );
return connection.get( uri )
[I've left out the exception handling.]
Are you trying to layer in the complex SOAP interface/implementation separation?
A client "written in JAVA that utilizes a RESTful web service"... A "Perl tool doing the same thing" ... "in C++ and Python and C#".
Correct.
"where code cannot be shared"
Correct. The code cannot be shared. You have to write each client in the appropriate language. Writing some kind of "generator" to create this code from WSDL is (1) a huge amount of work and (2) needless. Each language has unique syntax and unique libraries for making REST requests. But it's so simple and generic that there's hardly anything there.
The canonical example in Python is
class Some_REST_Stub( object ):
def get_some_resource( self, arg ): # This name is from the WSDL
uri = "http://host:port/path/to/resource/%s/" % arg # This path is from the WSDL
data= urllib2.open( uri )
return json.load( data )
This block of code is shorter than the WSDL required to describe it. And it seems easier to change because the name is the method name and the URI is simply a string.
In most languages the client is approximately that simple. I just wrote a bunch of REST client code in Java. It's wordier, but it's generic stuff. Build a request, parse the JSON that comes back. That's it.
A RESTful WSDL declaration buries two pieces of trivial information in a lot of XML.
It provides an "interface name" for the URI.
It documents the meaning of GET, PUT, POST and DELETE by providing Stub class method names.
It doesn't help you write much code, since there isn't much code. Note that all REST requests have the same generic HttpRequest and HttpResponse structure. The request contains generic an Entities. The response, also, contains a generic Entity that must be parsed. There's very little to REST -- the point is to be as simple as possible.
It largely eliminates the need for WSDL since everything is a generic JSONObject or XML URLEncoded and sent as a string.
"I'd much rather call a function on a class that returns my data encapsulated in an object instead of having to worry about the URL, the arguments, the response, etc."
Correct, you'll have to write a "stub" class. It has almost no code, and it will be shorter than the WSDL required to describe it.
"Multiply that out over each of the tools and now when I make a change to the service I must go update the URLs in each CRUD operation and all that goes along with that."
You can either update the stub class in each language for each client. Or you can update the WSDL and then regenerate each client. It seems like the same amount of work, since the URI is trivially encapsulated in the client code.
"I guess I imagine that with a WSDL that is the aspect that is done for you."
I'm unclear on what's "done". Translating the wordy and complex WSDL into a simple stub class? I suppose this could be helpful. Except the WSDL is bigger than the stub class. I'm suggesting that you'll probably find it easier to simply write the stub class. It's shorter than the WSDL.
"Your code simply interacts with the stubs."
Correct.
"What the stubs do, who cares? Urls, arguments, responses - if anything changes just regenerate the stubs from the WSDL."
Sadly, almost none of this requires any real programming. Generating it from WSDL is more work than simply writing it. URI's a strings. Arguments are generic JSONObjects. Responses are generic HttpResponses including a JSONArray. That's it.
"I didn't also have to update all the code that deals with the specifics of making the request and dealing with the response."
Except, there aren't any interesting specifics of making the request. HTTP is simple, generic stuff. GET, POST, PUT and DELETE are all nearly identical.
Fossill,
I recommend that you do not bother to learn SOAP for this. Ws-* has a very high learning curve and the (unnecessary) complexity will likely eat you alive.
Looking at your skill set (Java, Perl, Python, C++) you should be very satisfied with a REST (or at least HTTP-based) approach. And: you'll get results very fast.
As S.Lott said, do not worry about the code generation. You'll not need it.
For questions, I suggest you join rest-discuss on Yahoo groups:
http://tech.groups.yahoo.com/group/rest-discuss/
You usually get immediate help with all things REST there.
Personally, I have yet to see any use case that could benefit from using WS-*.
Jan
The code-generation aspect that you value is a maintenance item, but I question its real worth.
Be it thru a WSDL document or your own grammar documentation for a REST-style implementations, clients have to comply to the published interface. The WS/SOAP (code-generation) development model might have more tools, but I think that's because it's clunky and needs them.
There's no impact in the 'integrateability' of your web service. That's an issue of publishing the formal interface (in whatever form that takes), in either case. And the speed with which you move from an interface change to an implementation change is arguably faster with REST-style services. Firing up (and fighting with) WS-* code generation tools takes time.
FYI - REST does have a WSDL-like auto-generation schema definition called WADL. But almost no one uses it.
Apache CXF has Java support for REST clients that gives you the same sorts of 'code generation' advantages, in many cases, as full SOAP.