Create Spring context in OSGI through the API - spring

To clarify my question further:
I have a spring xml file with camel routes. I want to bootstrap this route in a BundleActivator. What are the steps in the OSGI world to initialize and start a SpringContext and register with OSGI registry. I want to do this custom through the api – need to control this rather than use the spring DM. I under stand that I need to use the OSGI classes. Any examples to follow:
This does not start the routes:
ConfigurableApplicationContext ctx = new GenericApplicationContext();
ConfigurableEnvironment environment = ctx.getEnvironment();
//set up the props for the context
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader((BeanDefinitionRegistry) ctx);
ClassPathResource classPathResource = new ClassPathResource("context.xml",properClassLoader );
xmlReader.loadBeanDefinitions(classPathResource);
ctx.refresh();
ctx.start();
Thanks.

What you are looking for is called Managed Service Factories.
Take a look at the description at eclipse gemini project.

Related

How to remove CXF from rest service URL dynamically using admin config services

I am new to OSGI. I have developed a student rest service using cxf and blueprint .Deployed it in karaf. By default karaf has cxf in its URL. I have found that i can configure the property(org.apache.cxf.servlet.context=/student) in etc folder or I can run config:edit/setprop/update/ commands in karaf. So that i can replace cxf in the url with some custom value. But now I want to remove the CXF from my url without doing any above mentioned changes in karaf. Is there any other way I can do the same? I found that using admin config service and configuration I can update the above property but it is not working.
I referred following link:
How can I get properties stored in ConfigAdmin? -It didn't work for me.
As am using blueprint do I need to add anything extra? and what is exactly factorypid and location which I have to pass to createFactoryConfiguration.
Thanks in advance.
I had found solution for my issue. Add following code to activator's start method.
Dictionary<String, String> props = new Hashtable<String, String>();
props.put( "org.apache.cxf.servlet.context", "/student" );
// Use OSGI admin configuration to update CXF url
ServiceReference reference = context.getServiceReference( ConfigurationAdmin.class.getName() );
ConfigurationAdmin admin = (ConfigurationAdmin) context.getService( reference );
try
{
Configuration config = admin.getConfiguration( "org.apache.cxf.osgi", null );
config.update( props );
}
catch ( Exception exception )
{
throw exception;
}
No need to do any changes in blueprint.xml. It works in both karaf and equinox. Initially i was trying in equinox without passing location argument to getConfiguration() hence it was not working.

Equivalent of Google Guice Injector in Spring

At the moment I have some code that uses Google Guice to start a server:
Injector injector = createInjector(
new Module(root, domain, realm),
new TestsArtefactsServiceModule()
final Server server = injector.getInstance(Server.class);
server.acquire();
server.activate();
getRuntime().addShutdownHook(new Thread(() -> stopServer(server)));
I need to change it to use Spring.
Is there an equivalent of the Guice Injector class in Spring? Or, is there some other way to achieve this?
In Spring it's the ApplicationContext you are looking for.
There is a comparison of these two frameworks:
http://www.theserverside.com/feature/Comparing-Spring-vs-Google-Guice-By-Example

Deploy Spring-based web app in Undertow

I am trying to migrate our Spring-based web app from Tomcat 8 to Undertow.
We use Spring's WebApplicationInitializer for the programmatic configuration of Spring-MVC and HibernateTransactionManager.
There is a ServletContainerInitializerInfo class (Javadoc) that seems to serve my purpose, e.g I can instantiate it and then follow the steps given in Undertow docs (link) to start the server:
ServletContainerInitializerInfo sciInfo =
new ServletContainerInitializerInfo(containerInitializerClass,
instanceFactory, handlesTypes);
DeploymentInfo servletBuilder = Servlets.deployment()
.addServletContainerInitalizer(sciInfo);
DeploymentManager manager = Servlets.defaultContainer()
.addDeployment(servletBuilder);
manager.deploy();
PathHandler path = Handlers.path(Handlers.redirect("/myapp"))
.addPrefixPath("/myapp", manager.start());
Undertow server = Undertow.builder()
.addHttpListener(8080, "localhost")
.setHandler(path)
.build();
server.start();
The problem is that I don't know what to substitute for instanceFactory and handlesTypes arguments in call to ServletcontainerInitializerInfo constructor. In addition, the name of the addServletContainerInitalizer method is mis-spelled (should be Initializer instead of Initalizer).
Can someone please help?
Thanks!
Undertow uses InstanceFactory<T> as an extension point for dependency injection or other customization of an instance of a given class after instantiation.
The handlesTypes argument would be the set of all classes corresponding to the #HandlesTypes annotation on your servlet container initializer.
If your initializer has no #HandlesTypes and does not require dependency injection, you can simply try this:
MyInitializer initializer = new MyInitializer();
InstanceFactory<MyInitializer> instanceFactory
= new ImmediateInstanceFactory<>(initializer);
ServletContainerInitializerInfo sciInfo =
new ServletContainerInitializerInfo(MyInitializer.class,
instanceFactory, new HashSet<Class<?>>());

Deploy Spring and Jersey App with JavaConfig on Grizzly

I am trying to make this run for days now and I can't figure out how to do it. Perhaps someone else has an idea or has done this already?
I want to deploy my application on a grizzly embedded server. I configured my Spring application using JavaConfig, and that worked out pretty good so far, but now I seem to be stuck. Here is the code I use to deploy my Jersey stuff to grizzly:
HttpServer server = new HttpServer();
NetworkListener listener = new NetworkListener("grizzly2", "localhost", 4433);
server.addListener(listener);
WebappContext ctx = new WebappContext("ctx","/");
final ServletRegistration reg = ctx.addServlet("spring", new SpringServlet());
reg.addMapping("/*");
reg.setInitParameter("com.sun.jersey.config.property.packages", "com.myapp.http.webservices");
ctx.addContextInitParameter("contextConfigLocation", "com/myapp/config/beans.xml");
ctx.addListener("org.springframework.web.context.ContextLoaderListener");
ctx.addListener("org.springframework.web.context.request.RequestContextListener");
ctx.addFilter("springSecurityFilterChain", new DelegatingFilterProxy());
ctx.deploy(server);
server.start();
Now as far as I can tell the following line is the problem.
ctx.addContextInitParameter("contextConfigLocation", "com/myapp/config/beans.xml");
I have a beans.xml in which I configure the spring security stuff, but all the other beans I use are declared via JavaConfig. So, if I only pass the beans.xml, the application will only have access to the beans declared in there. What I really want to so is to pass my ApplicationContext so that all my beans can be retrieved properly.
I there a way to pass my ApplicationContext with the deployment as well? Or has someone a better idea on how to make this work?
Try this
ctx.addContextInitParameter("contextConfigLocation", "classpath:com/myapp/config/beans.xml")
And you should not use com.sun.jersey.config.property.packages anymore as you already use Spring to manage the beans.

Automatic configuration reinitialization in Spring

In Log4j, there is a feature wherein the system can be initialized to do a configure and watch with an interval. This allows for the log4j system to reload its properties whenever the property file is changed. Does the spring framework have such a Configuration Observer facility wherein the Configuration is reloaded when it changed. The Configuration that needs reloading is not the Springs's applicationContext.xml but various other configuration files that are initialized using the Spring initialization beans.
I found a utility that does something similar to Log4J here. It's basically an extension to PropertyPlaceholderConfigurer that reloads properties when they change.
AFAIK Spring does not provide such a utility. However there is a 3rd party tool, JRebel that enables you to update an entire web application (including the Spring configuration) without requiring a server restart.
A free trial is available, and the purchase price is fairly inexpensive.
I would be extra cautious with reloading spring application context.
What do you expect to happen with singleton beans? If an object has a reference to singleton bean, should it be updated?
I develop using JRebel and I would be very wary of expecting it to refresh your configuration. Works fine with Java, not with Spring though.
If you would like to add context, I have done that in the following way :
public class ApplicationContextUtil
{
static String[] configFiles = {"applicationContextParent.xml"};
private static ApplicationContext context = null;
static
{
context = new ClassPathXmlApplicationContext ( configFiles );
}
public static void addContext( String[] newConfigFiles )
{
// add the new context to the previous context
ApplicationContext newContext = new ClassPathXmlApplicationContext ( newConfigFiles, context );
context = newContext;
}
public static ApplicationContext getApplicationContext ()
{
// return the context
return context;
}
}
This is your context provider class. For details, you can look at my blog

Resources