jax-ws web-service tier to the hibernate-based data provider - java

A data provider (java, hibernate) has an API for accessing instances of JPA-annotated classes. A web-service (jax-ws) is exposing the API to the network clients. A bit of a problem I'm thinking to solve is that a client of the data provider cannot be easily reconfigured to either use the provider directly or over the web-service. The reason is that for any persistent class there is a definition of this class in jax-ws client code and in data provider code, they are identical structurally but are different classes in Java. The obvious solution of putting generated classes to the same namespace as the original classes and setting up a class path in such a way that generated classes are always ignored doesn't seem ot be a clean one.
Has anyone solved this or knows a better way?

One way I've solved this in a similar problem is to work with interfaces and use reflection to build proxy objects that wrap the real underlying object. Something like:
interface IEntity
{
void setFoo(String foo);
String getFoo();
}
class WSEntity
{/* code generated by jax-ws */
}
class DataEntity
{ /* code generated by java, hibernate, .. */
}
class WSEntityInvocationHandler implements InvocationHandler
{
private final WSEntity entity;
public WSEntityInvocationHandler(WSEntity entity)
{
this.entity = entity;
}
public Object invoke(Object proxy,
Method method, Object[] args) throws Throwable
{
// this is a simplified version
Method m = entity.getClass().getMethod(method.getName(), params);
return m.invoke(entity, args);
}
}
static void example()
{
InvocationHandler handler = new WSEntityInvocationHandler(entity);
IEntity ie = (IEntity) Proxy
.newProxyInstance(IEntity.class.getClassLoader(),
new Class[]{IEntity.class},
handler);
}
Basically all your app would need to do, is decide which "invocation handler" to use, e.g.
InvocationHandler handler = new WSEntityInvocationHandler(entity);
or
InvocationHandler handler = new DataEntityInvocationHandler(entity);

Related

Designing custom workflow in JAVA and Spring

I am working on an spring 2.0.1.RELEASE application.
Brief of Application:
1. I have separate Transformer beans that transforms my DTO to Domain
and vice versa.
2. I have separate Validator beans that validate my domain object being passed.
3. I have Service classes that takes care of the applying rules and calling persistence layer.
Now, i want to build a Workflow in my application:
where i will just call the start of the workflow and below mentioned steps will be executed in order and exception handling will be done as per the step:
1.First-Transformtion - transformToDomain() method will be called for that object type.
2.Second-Validator - class valid() method will be called for that object.
3.Third-Service - class save() method will be called for that object.
4.Fourth- Transformation - transformToDTO() method will be called for that object type.
after this my workflow ends and i will return the DTO object as response of my REST API.
Exception handling part is the one, i also want to take care of, like if particular exception handler exist for that step then call it, else call global exception handler.
I designed some prototype of same, but looking for some expert advice and how this can be achieved with a better design in java.
Explanation with example considering above use case is highly appreciable.
I'm not so sure if what you are describing is a workflow system in its true sense, perhaps a Chain of Responsibility is more of what you are talking about?
Following what you described as a sequence of execution, here is a simplified example of how I would implement the chain:
Transformer.java
public interface Transformer<IN, OUT> {
OUT transformToDomain(IN dto);
IN transformToDTO(OUT domainObject);
}
Validator.java
public interface Validator<T> {
boolean isValid(T object);
}
Service.java
public interface Service {
void save(Object object);
}
And the implementation that binds everything:
ProcessChain.java
public class ProcessChain {
private Transformer transformer;
private Service service;
private Validator validator;
Object process(Object dto) throws MyValidationException {
Object domainObject = transformer.transformToDomain(dto);
boolean isValid = validator.isValid(domainObject);
if(!isValid){
throw new MyValidationException("Validation message here");
}
service.save(domainObject);
return transformer.transformToDTO(domainObject);
}
}
I haven't specified any Spring related things here because your question seems to be a design question rather than a technology questions.
Hope this helps
Brief of what i implemented in a way with not much hustle:
This is how I created flow of handlers:
Stream.<Supplier<RequestHandler>>of(
TransformToDomainRequestHandler::new,
ValidateRequestHandler::new,
PersistenceHandler::new,
TransformToDTORequestHandler::new)
.sequential()
.map(c -> c.get()) /* Create the handler instance */
.reduce((processed, unProcessed) -> { /* chains all handlers together */
RequestHandler previous = processed;
RequestHandler target = previous.getNextRequestHandler();
while (target != null && previous != null) {
previous = target;
target = target.getNextRequestHandler();
}
previous.setNextRequestHandler(unProcessed);
return processed;
}).get();
This is my Request Handler which all other handler extends

Implementation of the Factory Design Pattern

I am developing a small application for my client and I tried to apply there Factory Method design pattern. I am not sure if I have done it correctly.
Basically I have an abstract class Scheme that is extended by concrete Schemes (AccountScheme, ContactScheme, OrderScheme etc.). Each class consists mainly of instance variables and a method responsible for transforming Scheme into actual system object (AccountScheme will be used eventually to create Account, ContactScheme to create Contact and so on).
I also have SchemeFactory class which has a static method createScheme taking two parameters - type of system object the Scheme should be able to transform into AND JSON String which will be parsed into the Scheme object itself.
And finally there is a ApiService class which handles Rest Requests and uses the SchemeFactory to create Schemes (using request body). The schemes are processed after that and at certain point if needed particular System Objects is created (using scheme) and inserted to database.
I believe the UML diagram (it is my first one) would look something like that:
UML Diagram
The concept is correct.
Your UML not show the abstract class. In your case, you can have something like this (as described in you UML):
class SchemaFactory
{
public static Schema getSchema(String type, String json)
{
if ( type.equals("account") )
return new AccountSchema(json);
else if ( type.equals("contact") )
return new ContactSchema(json);
else if ( type.equals("order") )
return new OrderSchema(json);
throw new IllegalArgumentException();
}
}
The interface:
interface Schema {
}
The implementation of AccountSchema:
class AccountSchema implements Schema {
AccountSchema(String json) {
//use json
}
}
The abstract class is optional for the pattern. It's useful if you would like to force that the Schemas fill the constructor of abstract class with json as parameter, but the schema class can still fake, like:
public class FakeSchema extends AbstractSchema {
public FakeSchema () {
super(null);
}
}

Code injection via custom annotation

Here's my use case:
I need to do some generic operation before and after each method of a given class, which is based on the parameter(s) of the method. For example:
void process(Processable object) {
LOGGER.log(object.getDesc());
object.process();
}
class BaseClass {
String method1(Object o){ //o may or may not be Processable(add process logic only in former case)
if(o intstanceof Prcessable){
LOGGER.log(object.getDesc());
object.process();
}
//method logic
}
}
My BaseClass has a lot of methods and I know for a fact that the same functionality will be added to several similar classes as well in future.
Is something like the following possible?
#MarkForProcessing
String method1(#Process Object o){
//method logic
}
PS: Can AspectJ/guice be used? Also want to know how to implement this from scratch for understanding.
Edit: Forgot to mention, what I have tried.(Not complete or working)
public #interface MarkForProcessing {
String getMetadata();
}
final public class Handler {
public boolean process(Object instance) throws Exception {
Class<?> clazz = instance.getClass();
for(Method m : clazz.getDeclaredMethods()) {
if(m.isAnnotationPresent(LocalSource.class)) {
LocalSource annotation = m.getAnnotation(MarkForProcessing.class);
Class<?> returnType = m.getReturnType();
Class<?>[] inputParamTypes = m.getParameterTypes();
Class<?> inputType = null;
// We are interested in just 1st param
if(inputParamTypes.length != 0) {
inputType = inputParamTypes[0];
}
// But all i have access to here is just the types, I need access to the method param.
}
return false;
}
return false;
}
Yes, it can be done. Yes, you can use AspectJ. No, Guice would only be tangentially related to this problem.
The traditional aspect approach creates a proxy which is basically a subclass of the class you've given it (e.g. a subclass of BaseClass) but that subclass is created at runtime. The subclass delegates to the wrapped class for all methods. However, when creating this new subclass you can specify some extra behavior to add before or after (or both) the call to the wrapped class. In other words, if you have:
public class Foo() {
public void doFoo() {...}
}
Then the dynamic proxy would be a subclass of Foo created at runtime that looks something like:
public class Foo$Proxy {
public void doFoo() {
//Custom pre-invocation code
super.doFoo();
//Custom post-invocation code
}
}
Actually creating a dynamic proxy is a magical process known as bytecode manipulation. If you want to to do that yourself you can use tools such as cglib or asm. Or you can use JDK dynamic proxies. The main downside to JDK proxies are that they can only wrap interfaces.
AOP tools like AspectJ provide an abstraction on top of the raw bytecode manipulation for doing the above (you can do a lot with bytecode manipulation, adding behavior before and after methods is all aspects allow). Typically they define 'Aspect's which are classes that have special methods called 'advice' along with a 'pointcut' which defines when to apply that advice. In other words you may have:
#Aspect
public class FooAspect {
#Around("#annotation(MarkForProcessing)")
public void doProcessing(final ProceedingJoinPoint joinPoint) throws Throwable
{
//Do some before processing
joinPoint.proceed(); //Invokes the underlying method
//Do some after processing
}
}
The aspect is FooAspect, the advice is doProcessing, and the pointcut is "#annotation(MarkForProcessing)" which matches all methods that are annotated with #MarkForProcessing. It's worth pointing out that the ProceedingJoinPoint will have a reference to the actual parameter values (unlike the java.lang.reflect.Method)
The last step is actually applying your aspect to an instance of your class. Typically this is either done with a container (e.g. Guice or Spring). Most containers have some way of knowing about a collection of aspects and when to apply them to classes constructed by that container. You can also do this programmatically. For example, with AspectJ you would do:
AspectJProxyFactory factory = new AspectJProxyFactory(baseClassInstance);
factory.addAspect(FooAspect.class);
BaseClass proxy = factory.getProxy();
Last, but not least, there are AOP implementations which use compile-time "weaving" which is a second compilation step run on the class files that applies the aspects. In other words, you don't have to do the above or use a container, the aspect will be injected into the class file itself.

RPC call - static methods is not working

I am trying to define a static method in the service interface to make an rpc call. But it doesn't allow me to do so. here I am pasting my code
Client class
public void sendDomesticData(String product,String dma,String yrmnths,String dist,String metrics) {
String url = GWT.getModuleBaseURL() + "domesticservice";
domesticServiceAsync = (DomesticServiceAsync) GWT.create(DomesticService.class);
ServiceDefTarget endpoint = (ServiceDefTarget) domesticServiceAsync;
endpoint.setServiceEntryPoint(url);
domesticServiceAsync.sendDomesticData(product,dma,yrmnths,dist,metrics,new Domestichandler<Void>() );
}
public class Domestichandler<Void> implements AsyncCallback<Void> {
#Override
public void onFailure(Throwable caught) {
String error = caught.getMessage();
System.out.println(error);
}
public void onSuccess(Void result) {
System.out.println("perfect");
}
}
Service
public interface DomesticService extends RemoteService {
public void sendDomesticData(String product,String dma,String yrmnths,String dist,String metrics);
}
public interface DomesticServiceAsync {
void sendDomesticData(String product,String dma,String yrmnths,String dist,String metrics,AsyncCallback<Void> callback);
}
Server side -
public void sendDomesticData(String product, String dma, String yrmnths, String dist, String metrics) {
System.out.println(product);
}
Basically I am trying to send the values from the front interface to the server side and I don't want any return value. But the values passed to the server side should be stored globally in the server class so i can access those values in different method. I tried changing all the senddomestic values to static but it won't allow me to do so? why?
Because RemoteServiceServlet needs to invoke your service methods somehow and the implementation expects instance methods. But this shouldn't prevent you from assigning the method data to static fields. Just be aware of multi threading.
GWT always uses instance methods for RPC calls, static methods are not possible in this case.
What is important to understand about GWT is that any RemoteServiceServlet instances are created and maintained by the servlet container (e.g. Tomcat). The servlet container might create a number of servlet instances on startup (Tomcat creates 6 RemoteServiceServlet instances by default) and then uses load balancing to determine which servlet handles an RPC request at a particular point in time. Depending on settings of course, you have little control over which RemoteServiceServlet instance exactly will handle a specific RPC request.
Therefore, if you want to store information on the server side globally using RPC calls, the idea proposed by YuPPie to use static fields of your RemoteServiceServlet implementation is a BAD idea. You will have no idea which of the RemoteServiceServlet instances maintained by the server contains your static data, and any subsequent calls to retrieve the data will give erratic results.
You have a few options, though. Storing the information in a database (or something similar) is the most straightforward option, but from your post I'm guessing you want something simpler. A singleton class which holds your data is probably the way to go. A thread-safe example:
public class DataContainer
{
private static DataContainer _singleton;
private String _dataField1;
public static synchronized DataContainer getInstance()
{
if (_singleton == null)
_singleton = new DataContainer();
return _singleton;
}
public synchronized String getDataField1()
{
return _dataField1;
}
public synchronized void setDataField1(String dataField1)
{
_dataField1 = dataField1;
}
}
Then in the server side implementation of your RPC call you could do something like:
public void sendDomesticData(String product, String dma, String yrmnths, String dist, String metrics)
{
DataContainer.getInstance().setDataField1(product);
}
This way, if there are multiple servlet instances they will all share the singleton instance of DataContainer, thus giving you a place to store your data globally. I hope this will help you.

By using a dynamic proxy, is there a way I can return an object whose type doesn't match the method signature of the proxied interface?

I think the short answer may be no, but I'm hoping I can get alternative suggestions. Assume I have a data object and a data service. The data service is an interface and has the following method.
public Data getData();
I'm creating a proxy for the service using the following invocation handler plus Netty to do what I'd call asynchronous rpc. The proxy is on the client side.
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Convert the call into an async request that returns a ListenableFuture
APCRequest request = new APCRequest(serviceType, method, args);
ListenableFuture future = apcClient.asyncMessage(request);
// This blocks until the future finishes
return future.get();
}
This works fine. However, if my client is a UI, I end up wrapping the service call in something like a SwingWorker. I'd prefer to come up with a way of returning the ListenableFuture that I already have sitting there. Is there any way I can accomplish that without creating a separate, asynchronous service API. For example:
public ListenableFuture<Data> getData();
If I could have my InvocationHandler return the wrong type, I could use something like this.
public abstract class AsyncServiceCall<S, D> { // S = service type, D = expected doCall return type
protected final S service;
protected AsyncServiceCall(Class<S> serviceType, APCClient client) {
ProxyFactory proxyFactory = new ProxyFactory(client);
// The true tells the proxyFactory we're expecting a ListenableFuture<D>
// rather than the real return type.
service = proxyFactory.createProxy(serviceType, true);
}
// Sub-classes would make a normal method call using this. For
// example, service.getData()
public abstract Object doCall();
#SuppressWarnings("unchecked")
public ListenableFuture<D> execute() {
return (ListenableFuture<D>) doCall();
}
Is there another way of accomplishing what I want? Performance isn't an issue for me, so blocking until the proxy can get the return value from the future is still an option if there's no simple way of doing what I want. It just seems like a waste since I want an asynchronous call in the UI anyway.
Keeping my service API simple is more of a priority than anything. I want to be able to prototype using a simple service provider that instantiates service implementations directly and plug in my remoting protocol / server that's using dynamic proxies / Netty late in the development cycle.
If you want to keep your API simple then I would suggest providing only the async API in the interface - it's much easier to wrap up a synchronous implementation in an asynchronous API than vice-versa.
public interface DataService {
public ListenableFuture<Data> getData();
}
public abstract class LocalDataService implements DataService {
public ListenableFuture<Data> getData() {
SettableFuture<Data> result = SettableFuture.create();
try {
Data theData = computeData();
result.set(theData);
} catch(Throwable t) {
result.setException(e);
}
return result;
}
protected abstract Data computeData() throws Throwable;
}

Categories

Resources