In the context of an Eclipse RCP application I decided to use OSGi services to provide "Interfaces" out of a plugin (i.e a bundle).
In one of my plugin I have the following Parser interface:
public interface Parser {
public void start(File file);
public boolean hasNext();
public Object next();
}
Consumer plugins will use this interface to parse files. Because several parsing can be done in the same time and because an implementation of this interface will need several "state" private field each consumer of this service must use a dedicated service instance.
In this case, the default solution provided by manu OSGi tutorials consisting in registering ONE service instance in the start method of the parser bundle doesn't work. What is the best solution to handle such a solution ?
I can create a ParserFactory service with one unique method:
public Parser create(File file);
??
Any comment is welcome,
As you're suggesting, I would change your service interface to be a provider of Parsers.
And your Parser is just an Iterator, so maybe something like
public interface ParserFactory<T> {
/** Iterating on the returned object
* provides Ts parsed from the InputStream.
*
* #param input must be closed by the returned object
* when done iterating.
*/
Iterable<T> createParser(InputStream input);
}
Using an InputStream or Reader also makes it more flexible that requiring a File.
Have a look at the OSGi ServiceFactory; this allows you to instantiate services for different requesting bundles. You can read more about it in section 5.6 of the core specification.
Related
We are using Spring Cloud Stream as the underlying implementation for event messaging in our microservice-based architecture. We wanted to go a step further and provide an abstraction layer between our services and the Spring Cloud Stream library to allow for dynamic channel subscriptions without too much boilerplate configuration code in the services themselves.
The original idea was as follows:
The messaging-library provides a BaseHandler abstract class which all individual services must implement. All handlers of a specific service would like to the same input channel, though only the one corresponding to the type of the event to handle would be called. This looks as follows:
public abstract class BaseEventHandler<T extends Event> {
#StreamListener
public abstract void handle(T event);
}
Each service offers its own events package, which contains N EventHandlers. There are plain POJOs which must be instantiated programmatically. This would look as follows:
public class ServiceEventHandler extends BaseEventHandler<ImportantServiceEvent> {
#Override
public void handle(ImportantServiceEvent event) {
// todo stuff
}
}
Note that these are simple classes and not Spring beans at this point, with ImportantServiceEvent implementing Event.
Our messaging-library is scanned on start-up as early as possible, and performs handler initialization. To do this, the following steps are done:
We scan all available packages in the classpath which provide some sort of event handling and retrieve all subclasses of BaseEventHandler.
We retrieve the #StreamListener annotation in the hierarchy of the subclass, and change its value to the corresponding input channel for this service.
Since our handlers might need to speak to some other application components (repositories etc.), we use DefaultListableBeanFactory to instantiate our handlers as singleton, as follows:
val bean = beanFactory.createBean(eventHandlerClass, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
beanFactory.registerSingleton(eventHandlerClass.getSimpleName(), bean);
After this, we ran into several issues.
The Spring Cloud Stream #StreamListener annotation cannot be inherited as it is a method annotation. Despite this, some mechanism seems to be able to find it on the parent (as the StreamListenerAnnotationBeanPostProcessor is registered) and attempts to perform post-processing upon the ServiceEventHandler being initialized. Our assumption is that the Spring Cloud Stream uses something like AnnotationElementUtils.findAllMergedAnnotations().
As a result of this, we thought that we might be able to alter the annotation value of the base class prior to each instantiation of a child class. Due to this, we thought that although our BaseEventHandler would simply get a new value which would then stay constant at the end of this initialization phase, the child classes would be instantiated with the correct channel name at the time of instantiation, since we do not expect to rebind. However, this is not the case and the value of the #StreamListener annotation that is used is always the one on the base.
The question is then: is what we want possible with Spring Cloud Stream? Or is it rather a plain Java problem that we have here (does not seem to be the case)? Did the Spring Cloud Stream team foresee a use case like this, and are we simply doing it completely wrong?
This question was also posted on on the Spring Cloud Stream tracker in case it might help garner a bit more attention.
Since the same people monitor SO and GitHub issues, it's rather pointless to post in both places. Stack Overflow is preferred for questions.
You should be able to subclass the BPP; it specifically has this extension point:
/**
* Extension point, allowing subclasses to customize the {#link StreamListener}
* annotation detected by the postprocessor.
*
* #param originalAnnotation the original annotation
* #param annotatedMethod the method on which the annotation has been found
* #return the postprocessed {#link StreamListener} annotation
*/
protected StreamListener postProcessAnnotation(StreamListener originalAnnotation, Method annotatedMethod) {
return originalAnnotation;
}
Then override the bean definition with yours
#Bean(name = STREAM_LISTENER_ANNOTATION_BEAN_POST_PROCESSOR_NAME)
public static StreamListenerAnnotationBeanPostProcessor streamListenerAnnotationBeanPostProcessor() {
return new StreamListenerAnnotationBeanPostProcessor();
}
Assume that we've some interface my.gwt.shared.Facade in shared package of our GWT project (exists both server and client) and two implementation of it: class my.gwt.client.ClientFacadeImpl (exists only client) and class my.gwt.server.ServerFacadeImpl (exists only server).
Is there any way to write a piece of code or annotation that substitute ClientFacadeImpl in client side and ServerFacadeImpl in server side?
Thanks all for the answers and discussion. I've found simple and elegant solution for my needs.
So, I've interface my.gwt.shared.Facade and two classes: class my.gwt.client.ClientFacadeImpl and class my.gwt.server.ServerFacadeImpl.
interface Facade {
Map<Boolean, Facade> FACADES = new HashMap<Boolean, Facade>();
}
Now, we should fill you FACADES interface. This is done like that:
public class MyEntry implements EntryPoint {
static {
Facade.FACADES.put(true, ClientFacadeImpl.INSTANCE); // client side
}
And
#Startup
#Singleton
public class Initializer {
#PostConstruct
private void init() {
Facade.FACADES.put(false, ServerFacadeImpl.INSTANCE); // server side
// other things
}
}
Now, when I need to get appropriate Facade, I just write
Facade facade = Facade.FACADES.get(GWT.isClient());
Also in this case in map is only corresponding to server or client side implementation.
P. S. Goal of this question was to allow handling of some GwtEvents fired on client direclty on server and vice-versa. This solution removed large set of DTO (data transfer objects) and simplified code a lot.
There's no answer to your question other than "it depends". Or rather, of course there are ways of doing what you ask, but would you accept the tradeoffs?
Given that you tagged the question with dependency-injection, let's start with that. If you use a DI tool with GWT, it's likely GIN (Dagger 2 would work, but it's still under development). In that case, just use distinct modules for GIN client-side and Guice server-side that bind() the appropriate implementation.
For a few releases, GWT.create() can be made to work outside a GWT (client) environment (i.e. on the server side). You have to register a ClassInstantiator on the ServerGwtBridge as an alternative to the rebind rules from gwt;xml files. So you could have a <replace-with class="my.gwt.client.ClientFacadeImpl"> rule in your gwt.xml, and a ClassInstantiator returning a ServerFacadeImpl on the server side.
Finally, you can also use a static factory and replace it with a client-side specific version by way of <super-source>.
A last one, but I'm unsure whether it'd work: you could use an if/else using GWT.isClient(), and annotate your ServerFacadeImpl with #GwtIncompatible to tell the GWT compiler that you know it's not client-compatible.
I'm currently digging into Apache MINA. It's a great framework with lots of capabilities. The hardest part until now was the decoder part. Checking the api documents I understand that there are the following classes that one can extend and implement his own:
DemuxingProtocolDecoder - A composite ProtocolDecoder that demultiplexes incoming IoBuffer decoding requests into an appropriate MessageDecoder.
ObjectSerializationDecoder - A ProtocolDecoder which deserializes Serializable Java objects using IoBuffer.getObject(ClassLoader).
PrefixedStringDecoder - A ProtocolDecoder which decodes a String using a fixed-length length prefix.
All of the above extend the CumulativeProtocolDecoder class - A ProtocolDecoder that cumulates the content of received buffers to a cumulative buffer to help users implement decoders.
Could you please mention with some real world examples what subclass of CumulativeProtocolDecoder you would or did use and why?
Is there an example that doesn't need the decoder to extend the CumulativeProtocolDecoder class and just implement the ProtocolDecoder directly without worrying about fragmentation?
I am using an instance of DemuxingProtocolDecoder class with my application. Under the package org.apache.mina.filter.codec.demux there are some interfaces and classes that you can use to decode your messages. There is an interface called MessageDecoder. Create your own class that implements this interface and MINA will the work. Something like this,
public class MyDecoder implements MessageDecoder {
public MessageDecoderResult decode(IoSession session, IoBuffer buffer, ProtocolDecoderOutput decoderOutput) throws Exception {
/* Your
decode
mechanism */
decoderOutput.write(message); // don't forget to write your decoded message object at some point.
return MessageDecoder.OK; //or something else that matches your needs.
}
}
I am working on a web application which is based on spring MVC. We have various screens for adding different domain components(eg. Account details, Employee details etc). I need to implement an upload feature for each of these domain components i.e. to upload Account, upload employee details etc which will be provided in a csv file (open the file, parse its contents, validate and then persist).
My question is, which design pattern should i consider to implement such a requirement so that upload (open the file, parse its contents, validate and then persist) feature becomes generic. I was thinking about using the template design pattern. Template Pattern
Any suggestions,pointers,links would be highly appreciated.
I am not going to answer your question. That said, let me answer your question! ;-)
I think that design patterns should not be a concern in this stage of development. In spite of their greatness (and I use them all the time), they should not be your primary concern.
My suggestion is for you to implement the first upload feature, then the second and then watching them for what they have that is equal and create a "mother" class. Whenever you come to a third class, repeat the process of generalization. The generic class will come naturally in this process.
Sometimes, I believe that people tend to over engineer and over plan. I am in good company: http://www.joelonsoftware.com/items/2009/09/23.html. Obviouslly, I am not advocating for no design software - that never works well. Nevertheless, looking for similarities after some stuff has been implemented and refactoring them may achieve better results (have you already read http://www.amazon.com/Refactoring-Improving-Design-Existing-Code/dp/0201485672/ref=sr_1_1?ie=UTF8&qid=1337348138&sr=8-1? It is old but stiil great!).
A strategy pattern my be useful here for the uploader. The Uploader class would be a sort of container/manager class that would simply contain a parsing attribute and a persistance attribute. Both of these attributes would be defined as an abstract base class and would have multiple implementations. Even though you say it will always be csv and oracle, this approach would be future-proof and would also separate the parsing/verifying from the persistence code.
Here's an example:
class Uploader
{
private:
Parser parser_;
Persistence persistence_;
void upload() {
parser_.read();
parser_.parse();
parser_.validate();
persistence_.persist(parser_.getData());
}
public:
void setParser(Parser parser) {parser_ = parser;}
void setPersister(Persistence persistence) {persistence_ = persistence;}
};
Class Parser
{
abstract void read();
abstract void parse();
abstract void validate();
abstract String getData();
};
class Persistence
{
abstract persist(String data);
};
class CsvParser : public Parser
{
// implement everything here
};
// more Parser implementations as needed
class DbPersistence : public Persistence
{
// implement everything here
};
class NwPersistence : public Persistence
{
// implement everything here
};
// more Persistence implementations as needed
You could use an Abstract Factory pattern.
Have an upload interface and then implement it for each of the domain objects and construct it in the factory based on the class passed in.
E.g.
Uploader uploader = UploadFactory.getInstance(Employee.class);
I want to create a paging service that will return pages based on a SQL like query. Here is the simple interface:
public interface IPage {
public boolean hasNext();
public Object[] next();
}
When I call this service I want to be able to initialize it with a query String and a page size int.
How do I go about getting a reference to the service that has been initialized with the arguments specified above? I would prefer to use declarative services but it seems to me I would have to use ServiceTracker if I wanted to pass in arguments.
Thanks for your help.
Instead exposing IPage as a service, you might expose an IPageFactory as a service instead. The factory would then take a query and a page size, and return an initialised IPage instance.