I am a bit confused on the approach of creating web services.
Problem statement:
Should i create a service with two end points like below
<jaxws:endpoint id="stateService" implementor="com.service.StateServiceImpl" address="/stateservice" />
<jaxws:endpoint id="countryService" implementor="com.service.CountryServiceImpl" address="/countryservice" />
Or create a single end point with two methods
public class Service{
#WebMethod(operationName="country", action="countryservice" )
public String countryService() {}
#WebMethod(operationName="state", action="stateservice" )
public String stateService() {}
}
The purpose of both of my services or operations is different.
I am currently using Apache CXF with approach 1 i.e. separate end point.
what is the advantage of one over another.
I think it's mostly a question of how you want to advertise the relationship of the methods. My rule of thumb here: if they are not related in any way, then separate endpoints. If they operate on the same data (even if the operations are different), then it makes more sense to bundle as separate methods in the same endpoint, to telegraph that the data source is the same.
But, I'm sure there's a lot of variation to the answers you'll get ... this will ultimately boil down to what makes the most sense for you and your customers.
Related
Having all your business logic in one place comes with various benefits. It makes your logic clean and easy to debug. However, I feel that it does not scale well under some circumstances.
For example,
class Book{
String a, b......z;
}
My book class has 26 fields ( a thru z). For searching alone, there are 2^26 possible ways to query.
If I were to write a service class (repository) for this :
interface BookRepo{
List<Book> findById(int id);
List<Book> findByA(String a);
List<Book> findTop10ByADescending(String a);
List<Book> findByBAndCAndDAnd....Z(String a, b, c,d, e....z);
....
}
As you can see, it is absurd since there are so many combinations of search variable possible, not to mention sorting, and paging variables that may come into the picture.
If my application is so flexible such that for a given "Resource", user can filter any field, sort by anything. Shouldn't I skip service layer completely?
I have tried writing a "generic" service layer, it is not easy in statically typed language. In addition, if your service layer now lets everything through, there is no point having it there.
your problem is not really related to existing vs missing a service layer. your problem is caused by bad data structure and/or repository design.
if you want to filter by all possible combinations of 26 letters then think about creating queries dynamically and/or make many-to-many relationship between letter and book rather than having 26 fields inside a book. then you will have constant and small number of repository methods and you can easily add new letters.
if your application doesn't need service layer then you don't have to add it. but if you don't have it and your application grows it's harder to spot the moment when it's needed. instead people tend to put service-logic into controllers and/or repositories. especially when you work in a team
I am using Apache CXF (apache-cxf-2.5.0) to create Web Services using a bottom-up approach (Java first approach). I want to return some data/records (for example, username, email) from a database table. I can write a Java class which returns a simple response. But I am not able to find way to return a response such as data/records extracted from a database table. How to do that?
You don't mention how you are accessing the database, but the basic idea is that you ensure that the classes that you return have JAXB annotations (notably #XmlRootElement or #XmlType) on them, which allows CXF to convert the instances of those classes into XML document fragments. The classes which you annotate this way probably should not have lots of functionality in them; they should exist just to hold data. (I find anything else too confusing given the complex lifecycle they'll have.) Once the annotations are in place, just return the relevant objects and all the conversions will happen automatically.
I'm talking a simple class like this:
#XmlRootElement // <---- THIS LINE HERE!
public class UserInfo {
public String username;
public String email;
}
You can use this in conjunction with other annotations (e.g., for your ORM) as necessary. Of course, if you're talking straight JDBC to the DB to get the information out, you won't need to worry about that.
The one tricky bit is that the objects being returned will have a lifespan that goes beyond that of the database transaction you're using; you may need to detach (i.e., do some copying, though the ORM layer might provide assistance) the objects extracted from the DB for that to work. This won't be much of a concern in this case as the DB you're describing is very simple (one table, no inter-row relations) but could be an issue if you make things more complex.
Here is a description of the scenario and I would appreciate also any comments on the approach used
The core of my application is a set of web services backed by a P2P database. One service accepts a simple XML-based record (I have designed a generic schema for it). The service processes this data (mainly creating keys based on certain criteria) and pass the original data along with the created keys to a listening SocketServer in one of the listening P2P nodes. This key,data pair is routed to the proper node, which stores the data (associated with the key as an ID) in an XML database.
A second service accepts a query document that is structured based on the same schema, but with optional values that would be used for searching and matching from the previously stored ones. So the second service would pass this query (with the proper keys) to the P2P part, get back the results and pass them back to the service client.
E.g. if the original record submitted to the first service was < attr1 >value1 < /attr1 > < attr2 > value2 < / attr2 > (attribute list along with some other metadata mandated by the schema) then the second service should retrieve that record if the query received was < attr2 >value2 < / attr2 >
(I could later think about using more complex XPath or XQuery queries as the underlying XML database allows instead of exact matches for values here but that is not important at this stage. there is also a third service I am working on but it depends on getting the first two in proper shape first)
So my questions are:
1) What data type should I use as the parameters of the web services? How to utilize my schema for this usage? I was considering various XML binding frameworks (especially JAXB and SDO) for this but didn't know how to proceed.
2) How can I enhance the two services (call them store and search) to use dynamically created templates based on the original generic schema? The service would still accept documents of the main schema type but has the inner attribute list based on a template say template1 only requires whose values are ints while template2 require (float) and (string). The current JSP-based prototype manually creates this template but as an XML document that is assembled by hand (<>tags dispersed in text) and there is no type checking what so ever so I thought I could do better!
3) Is it possible to generate a quick web app prototype for simple access to this system (again by using the schema (&templates) to edit the appropriate XML message structures? What I am looking for is for the (human) user to choose a template and then just "fill in the blanks" and submit, no need for any fancy look and feel.
4) Can I or how can I also use this XML message type for communicating across sockets?
5) Does it matter if I deploy the services as stateless EJBs or not? Do I need them to be EJBs or servlets would be more than enough?
I currently have a rudimentary implementation (from previous developers) that were meant for a subset of my current requirements (I am improving on the services and adding new derived ones) but there was no schema nor validation and the data is passed all along as basic strings, thus providing weak typing and difficult to update manual parsing. The reason I want to update this to a stronger bound typing is to introduce changes in the data schema that would be passed along the whole system easily. Basically I want the system to be as less coupled to the data format/schema used as possible; the current prototype is too coupled to the data that I am finding it extremely difficult to change the data without breaking the system.
My initial investigation led me to consider JAXB but it supports only static typing (cannot create a schema/types dynamically at runtime that I want to persist for later usage). So I came across SDO which has both dynamic and static typing. The problem is just that there is not enough community and/or examples of using this approach so it seems risky (the examples of Apache Tuscany and Eclipselink implementations are very scarce and I could not find complete examples that are not 5+ years old (like this http://www.ibm.com/developerworks/java/library/j-sdo/) and also tackles the XML use case of SDO (most seem to focus on the relational usage of SDO).
This is my first time asking for programming help (here and elsewhere) so please bear with me. I searched a lot on the net but I could not find anything useful but pieces here and there that did not add up.
Any comment or hint is really appreciated.
trfndr
EDIT
I forgot one thing: how would the search service get back the results? Since it is opening a client socket connection, there is no way to get back any results synchronously. The current implementation tackles this by having the service client opening a listening socket on a random port and putting this contact info in the query document. After the search web service sends the query to the p2p part it finishes. The p2p sends the results as a WS call to another service which sends them back to the service client socket. I don't like this approach much, is there any more elegant solution?
I lead the EclipseLink JAXB & SDO implementations and represent Oracle on those specifications so hopefully I can help you out. This question is very similar to talk I'm giving at JavaOne in September.
1) What data type should I use as the
parameters of the web services? How to
utilize my schema for this usage? I
was considering various XML binding
frameworks (especially JAXB and SDO)
for this but didn't know how to
proceed.
This depend's on what web service framework you are using. JAXB is much easier to use with JAX-WS, and while JAXB is still easier to use with JAX-RS SDO, is a possible alternative.
2) How can I enhance the two services
(call them store and search) to use
dynamically created templates based on
the original generic schema? The
service would still accept documents
of the main schema type but has the
inner attribute list based on a
template say template1 only requires
whose values are ints while template2
require (float) and (string). The
current JSP-based prototype manually
creates this template but as an XML
document that is assembled by hand
(<>tags dispersed in text) and there
is no type checking what so ever so I
thought I could do better!
I'm not 100% what you mean here, but the following may be helpful:
Using #XmlAnyElement to Build a Generic Message
3) Is it possible to generate a quick
web app prototype for simple access to
this system (again by using the schema
(&templates) to edit the appropriate
XML message structures? What I am
looking for is for the (human) user to
choose a template and then just "fill
in the blanks" and submit, no need for
any fancy look and feel.
JAX-RS is a nice framework for creating quick prototypes. Below is an example I created:
Part 1 - The Database
Part 2 - Mapping the Database to Objects
Part 3 - Mapping the Objects to XML
Part 4 - The RESTful Service
Part 5 - The Client
4) Can I or how can I also use this
XML message type for communicating
across sockets?
I prefer frameworks like JAX-RS that communicate over the HTTP protocol.
5) Does it matter if I deploy the
services as stateless EJBs or not? Do
I need them to be EJBs or servlets
would be more than enough?
My preference is to use an EJB session bean for the service. If you are interacting with a database then you can leverage the Java Transaction API (JTA) to manage your database transactions.
Part 4 - The RESTful Service
SDO
EclipseLink is the SDO 2.1.1 (JSR-235) reference implementation. We have some examples posted below. If you are looking how to do something specific, I will try to post a relevant example.
http://wiki.eclipse.org/EclipseLink/Examples/SDO
JAXB
JAXB is static. It is also more popular than SDO. Recognizing this in EclipseLink we have implemented a dynamic JAXB feature. It gives you the dynamic aspect of SDO with a JAXB slant.
http://wiki.eclipse.org/EclipseLink/Examples/MOXy/Dynamic
EDIT #1
Since you are dealing with JAX-WS and your model is almost entirely dynamic, I think you should skip the JAXB binding altogether. In the following link see the section "Switching Off Data Binding"
http://java.sun.com/developer/technicalArticles/xml/jaxrpcpatterns3/
This will give us the body of the message as a javax.xml.transform.Source object. We will need to process the XML based on the dynamic templates. SDO would be a good choice here. You can constantly add new types to the HelperContext using XML schemas.
helperContext.getXSDHelper().define(schema1, null);
helperContext.getXSDHelper().define(schema2, null);
You wil be able to unmarshal the Source from the web service as follows:
XMLDocument doc = helperContext.getXMLHelper().load(source, null, null);
DataObject rootDataObject = doc.getRootObject();
String someValue = rootDataObject.getString("attr3/childAttr/anotherChildAttr");
You will also be able to use the XMLHelper to marshal your objects to XML when calling another service.
I'm after some guidance on how to approach coding a problem, I don't want to jump straight into coding without think about it as I need it to be as generic and customisable as possible,
The scenario is i have a web service that acts as a gateway to downstream services, with the aim of authenticating and authorising SOAP message destined for down stream services, basically allivating the downstream service from doing it themselves. Each SOAP message has a variety of different WS-Security mechanisms attached usually a WS-UsernameToken, WS-Timestamp, and a XML Signature of the message body.
My problem is i want to figure out a good extensible way of validating all these security mechanims, I'm not after how to do it just how to appraoch it.
I thought about having a controller class that is intialised and controls the validation flow i.e.
ISecurityController controller = SecurityControllerFacotry.getInstance();
boolean proceed = controller.Validate(soapMessage);
using it very much like a template design pattern which ditates the flow of logic i.e.
public Boolean Validate(Message soapMessage)
{
return ValidateAuthentication(soapMessage) && ValidateTimeStamp(soapMessage) && ValidateSignture(soapMessage);
}
Would this be the best apporach to the problem?
Also would it be best to put these validation methods each into a class of there own that which implemented a common interface? So that a class could be instantiated and retrieved from some sort of validation factory i.e.
IValidationMechanism val = ValidationFactory.getValidationType(ValidationFactory.UsernameToken);
boolean result = val.Validate(soapMessage);
This would give me an an easily extensible aspect.
Would this be an vaible solution or can anyone think of other ways of doing it?
I'm interset in design patterns and good oo principles so would like to go down a route utilising them if possible.
Thanks in advance
Jon
EDIT: The service is basically a gateway security service that relieves the burden of authentication and authorisation from services that sit behind it. The security service can be thought of as an implicitly invoke intermediary on the SOAP message path that validates the security mechanisms in the SOAP message and depending on the validation result forwards the message to the appropriate down stream service by interrogating the WS-addressing headers. Although the service is not really the question it is more on how to implement the validation procedure.
I think your intuition on this is good; go with the single interface approach. That is, hide your validation implementations behind a single validation interface; this allows you to extend your validation implementations later without modifying the calling code.
And yes, the idea of putting the validation into its own class is a good one; you might want to think about having a common base class, if you have any common validation items (for example, username might be a common validation element, even though each different validation scheme may encode it differently; one as an element, another as an attribute, etc.). I think validation classes is a more appropriate mapping for the level of complexity that you're talking about anyhow, as opposed to validation methods; I suspect that the type of validation you're doing requires groups of methods (i.e., classes).
I can think of another way to validate your SOAP message against different validations. You use a visitor Pattern.
For that You will have a simple wrapper around the SOAP message you get.
MySoapMessage{
SOAPMessage soapMessage;
List<String> validatonErrors;
void accept(Validator validator){
validator.isValid(this);
}
}
Your security Controller will contain the list of Validatiors which you will inject basically.
SecurityController{
List<IValidator> validators;
//Validate the message
void validate(MySOAPMessage soapMessage){
forEach(Validator validator: validators){
soapMessage.isValid(validator)
}
}
}
Your Validators will look something like this.
UserNameValidator implements IValidator{
public void validate(MySOAPMessage message){
// Validate and put error if any
}
}
You dont need and unnecessary factory here for the validators.. if you want to want to add/remove validators from the controller you just inject/un inject then from the list.
Spring has a generic validation package that handles this type of process nicely IMHO.
Theirs looks something like
public interface Validator {
public boolean supports(Class<?> clazz);
public void validate(Object o, Errors errors);
}
Granted, they're using an Errors param to return validation issues in, which might or might not suit your goal.
I'm new to the Repository Pattern and after doing a lot of reading on the web I have a rough understanding of what is going on, but there seems to be a conflict of ideas.
One is what the IRepository should return.
I would like to deal in ONLY Pocos so I would have an IRepository implementation for every aggregate root, like so:
public class OrangeRepository: IOrangeRepository
{
public Orange GetOrange(IOrangeCriteria criteria);
}
where IOrangeCriteria takes a number of arguments specific to finding an Orange.
The other thing I have is a number of data back-ends - this is why I got into this pattern in the first place. I imagine I will have an implementation for each, e.g
OrangeRepositoryOracle, OrangeRepositorySQL, OrangeRepositoryMock etc
I would like to keep it open so that I could use EF or NHibernate - again if my IOrangeRepository deals in POCOs then I would encapsulate this within the Repository itself, by implementing a OrangeRepositoryNHibernate etc.
Am I on the right lines?
Thanks
EDIT: Thanks for the feedback, I don't have anyone else to bounce these ideas off at the moment so it is appreciated!
Yes, your version is the safest / most compatible one. You can still use it with about any resources, not only data access ones, but with web services, files, whatever.
Note that with the IQueryable version you still get to work based on your POCOs classes, but you are tied to the IQueryable. Also consider that you could be having code that uses the IQueryable and then turns out it you hit a case where one of the repository's ORM doesn't handle it well.
I use the same pattern as you do. I like it a lot. You can get your data from any resources.
But the advantage of using IQuerable is that you do not have to code your own criteria API like the OrangeCriteria.
When NHibernate gets full Linq support then I may switch to the IQueryable.
Then you get
public class OrangeRepository: IOrangeRepository {
public IQueryable<Orange> GetOranges();
}