How do you create CouchDB Views using Spring Bean Deployment with LightCouch - spring-mvc

I am using Spring-MVC LightCouch and CouchDB and I have custom Views that need to be inserted into the DB on deployment. I have found the LightCouch has a method for pulling documents "from desk" as noted on their website:
DesignDocument designDoc = dbClient.design().getFromDesk("example");
Response response = dbClient.design().synchronizeWithDb(designDoc);
This Works good from within JAVA code, however I need to be able to do it in the Spring ApplicationContext.xml I have more than one so I would like to mimick the call of:
dbClient.dessign().synchronizeAllWithDB()
How would I do this in the bean definition of the ApplicationContext I already have this:
<bean id="dbClient" class="org.lightcouch.CouchDbClient" lazy-init="false" destroy- method="shutdown">
<constructor-arg value="couchdb.properties" />
</bean>

It seems you can't do it with Spring xml config, as the init method falls under a different instance; that is returned by the call to design() factory method. Maybe you can try Java code equivalence, i.e. #PostConstruct.

I ended up having to make a bean that synchronized the database on init and created that when the app starts

Related

Dispatcher servlet blocking the uploaded attachments

I am using spring mvc in our application. The application has a form which has certain fields including one field for uploading attachments. The form submits to a controller. The problem is -
whenever I upload an attachment, it doesen't reaches the controller. I have debugged the code and till the flow reaches the last filter to be called, the file is there. But then the dispatcher servlet gets called and after that no attachment reaches the controller.
You need to add multipartResolver into spring-servlet.xml
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
reference link https://www.javatpoint.com/spring-mvc-file-upload
I figured out the problem. It was the multipartResolver. If we have created the bean(in case of spring) for this, and then using dsRequest.getUploadedFiles(), we won't get the uploaded files because Multipart resolver has already resolved the multiparts in Dispatcher Servlet. So, please avoid using multipartResolver in this case.

Cannot register a filter to the CXF bundle in my bundle

I am having trouble using the Pax Web Whiteboard service to register a javax.servlet.Filter to a running JaxRS endpoint registered through CXF. I have tried a few different approaches, namely registering the Filter as a service, and using the org.ops4j.pax.web.service.WebContainer to register the filter directly.
For my test, i booted karaf, and installed pax-web, webconsole, cxf and the pax-web whiteboard service.
I the registered a bundle with a blueprint:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
<jaxrs:server id="webfiltersample" address="/webfilter">
<jaxrs:serviceBeans>
<ref component-id="serviceBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<service id="servletFilterService" interface="javax.servlet.Filter">
<service-properties>
<entry key="filter-name" value="BasicWebFilter"/>
<entry key="urlPatterns" value="/*"/>
<entry key="initParams" value=""/>
</service-properties>
<bean class="test.webfilter.BasicWebFilter"/>
</service>
<bean id="serviceBean" class="test.webfilter.WebFilterSample" init-method="init" destroy-method="destroy">
<property name="bundleContext" ref="blueprintBundleContext"/>
</bean>
</blueprint>
However, this filter is never called. I have tried both using servlet names and urlpatterns, going so far as to attempt the urlpattern /*
I then tried a slightly different approach, removing the service declaration from the blueprint, and adding the filter directly though the init method of the blueprint instead:
public void init(){
logger.info("Starting Sample");
filter = new WebFilter();
ServiceReference<WebContainer> ref = bundleContext.getServiceReference(BasicWebFilter.class);
WebContainer container = bundleContext.getService(ref);
logger.info("Registering "+ filter + " with "+ container);
container.registerFilter(filter, new String[]{"/cxf/*"}, new String[]{""}, null, null);
bundleContext.ungetService(ref);
}
The method is indeed called, as reflected by the log statements, but the filter is still not executed.
So am i completely wrong in how this works? My "Application" is really just an endpoint registered to the CXF servlet. This part is working, and i can call the REST services defined therein. But no matter what i do, the filter is not executing. I am working with a few libraries here that i don't really know that well (Servlets/Filters, Pax-Web and the Writeboard extender) do i have no idea why exactly this isn't working? My guess is that there are different httpcontexts for each bundle, and that i can't simply register a filter for another bundle (CXF) in my own test bundle.
If this is true, can someone tell me how to properly go about this problem? I could get the CXF bundles bundlecontext and register the filter to that, but that seems like a terrible horrible hack.
If that is NOT the case, can someone tell me why this is not working?
You are right, every bundle should have it's own httpContext. With Pax-Web it's possible to have shared httpContextes. For this you need to enable it for the bundle initially registering the httpContext. Though in this case it's the cxf bundle that does take care of it. As the shared context is a pax-web only feature (till v6 where OSGi R6 is implemented), this won't be added to cxf as cxf tends to rely on the smallest possible solution, which is the HttpService.
Basically even though it's possible to share httpContextes with different bundles, it's not possible for you with this scenario.
I propose to use JAAS instead of shiro as a way to login and store the authentication information. You can then use this in shiro as well as in other security implementations to do the authorization.
For CXF there is a JAASLoginFeature. It can receive basic auth as well as UserNameToken. See https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=42568988
This also has the advantage that it works the same way as the standard karaf authentication. So by default you can define users and groups in etc/users.properties but you can also for example attach karaf to ldap.
If you use blueprint then you can use blueprint-authz do role based authorization using annotations. See https://github.com/apache/aries/tree/trunk/blueprint/blueprint-authz and https://github.com/apache/aries/blob/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/authz/testbundle/impl/SecuredServiceImpl.java

Mixsing #Transactional & #Controller Semantics on a REST Api

I'd like to expose the backend as 'Resources' (like Restlet) and eliminate the Service Layer so a Rest Resource can direclty interact with a Dao. This way the Resource is the contract and not the Interface.
Is there a problem using #Transactional semantics on a Spring MVC 3 Controller if the transactions are managed locally by Spring? Any gotchas with Rollback and catching exceptions?
#RequestMapping(value = "/user/{userId}", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.OK)
#Transactional
public void updateUser(#PathVariable Long userId, #RequestBody ProfileUser user) {
// dao update
}
spring config:
<tx:annotation-driven />
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
I think you could run into issues here. By default Spring will use a JDK dynamic proxy to apply the transactional behaviour to your method. This relies on your controller implementing a suitable interface i.e. one which exposes an updateUser method. There is an excellent blog post on the Spring blog.
It is likely that you'll see an error due to Spring failing to find the method on the proxy.
You can use your above approach if you tell Spring to use CGLIB based proxies. This is described in the documentation here.

What does <mvc:annotation-driven /> do?

I use filenames in my REST API (example: GET http://xxx/api/myImage.jpg)
problem is #PathVariable dropped ".jpg".
this problems already asked few times in here and answered. but not worked to me.
so I searched then found at the
https://jira.springsource.org/browse/SPR-6524
"... is simply not supposed to be combined with manual DefaultAnnotationHandlerMapping instances; this is designed as an either-or choice at present, quite similar to and ."
"mvc namespace are make simplifed configurations".
Real question is mvc what does do? and changed?
I found my self these things..
intercepter configuration changed. (mvc namspace required in bean configuation)
useDefaultSuffixPattern is not working.
adds JSON message converter. if jackson library is available
#PathVariable arguments are auto added to model
Any others?
Thanks in advance!
The mvc:annotationDriven tag essentially sets you your Spring context to allow for dispatching requests to Controllers.
The tag will configure two beans DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter.
You can find more information from the spring documents:
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html
Before I provide certain points let me clear up the answer provided by Roy is not accurate. You don't have to provide mvc:annotation-driven tag to instantiate default beans. This tag can be used Spring 3.0+ to enable new feature introduced from Spring 3.0
(Do not use it if you want backward compatibility, especially if you are using old controller based classes like MultiActionController, SimpleFormController)
Now lets come to what this tag actually does -
Prior to Spring 3.1 default beans used where
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter
AnnotationMethodHandlerExceptionResolver
These are deprecated in Spring 3.1 and if you use above mentioned tag it will be replaced by -
RequestMappingHandlerMapping
RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver
DefaultAnnotationHandlerMapping decided which controller to use and the AnnotationMethodHandlerAdapter selected the actual method that handled the request. RequestMappingHandlerMapping does both the tasks. Therefore the request is directly mapped right to the method.
There are other infrastructure beans that are instantiated by these tag (chained in addition to defaults) like - MappedInterceptor, ConfigurableWebBindingInitializer, SessionFlashManager, ContentNegociationManager etc. I am not going to explain these :) as they each are long answers themselves, so google it for more info.
PS : And yes Spring 3.1+ automatically expose #PathVariables to the model. Also you have mvc:interceptors tag. But I think it is not related to <mvc:annotation-driven />. I would highly recommend read - http://spring.io/blog/2009/12/21/mvc-simplifications-in-spring-3-0/
To enable MVC Java config add the annotation #EnableWebMvc to one of your #Configuration classes:
#Configuration
#EnableWebMvc
public class WebConfig {
}
To achieve the same in XML use the
mvc:annotation-driven
element in your DispatcherServlet context (or in your root context if you have no DispatcherServlet context defined):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
</beans>
The above registers a RequestMappingHandlerMapping, a RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver (among others) in support of processing requests with annotated controller methods using annotations such as #RequestMapping, #ExceptionHandler, and others.
For details refer the below link :
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config
mvc:annotation-driven tag do extra work from context:component-scan tag
The tag registers the Handler Mapping and Handler Adapter required to dispatch requests to your #Controllers:
tag helps registering the following components.
DefaultAnnotationHandlerMapping - This is a HandlerMapping implementation which maps the HTTP requests to the handler methods defined using the #RequestMapping annotation.
AnnotationMethodHandlerAdapter - It is responsible for scanning the controllers to identify methods (and parameters) annotated with #MVC annotations. It scans and caches handler methods annotated with #RequestMapping. Also handles the #RequestParam, #ModelAttribute, #SessionAttributes and #InitBinder annotations.
ConfigurableWebBindingInitializer - The initializer for the Web Data Binder. Helps in declaratively configuring the Web Binder with validators, conversion services, property editors, etc.
LocalValidatorFactoryBean - Implements the validator interface and enables JSR303 validation. This is injected into ConfigurableWebBindingInitializer.
FormattingConversionServiceFactoryBean - A conversion factory that returns conversion services for basic objects like date and numbers. This factory is again injected into ConfigurableWebBindingInitializer.
Message Converters
ByteArrayHttpMessageConverter - A HTTP request message converter that reads a HTTP message body and returns a byte stream. It can also read a byte stream and construct a response body. Used for receiving and sending documents like PDF, XLS, etc.
StringHttpMessageConverter - A HTTP request message converter that reads a plain text request body and binds it to a String object. And vice-versa with response.
FormHttpMessageConverter - A HTTP request message converter that reads a form encoded request body and binds it to a form Binding object.
SourceHttpMessageConverter - A HTTP request converter that converts a XML message body to/from Binding Object.
If we do not use mvc:annotation-driven tag then we have to do register these components manually in xml file in order to use them , which results in too much extra work.

How to obtain OSGi service references from a Servlet that is registered in OSGi HttpService?

It seems natural that a HttpServlet running in OSGi environment (i.e. registered in OSGi HttpService) would want to call some OSGi services to accomplish it's tasks. The question is how to obtain references to these OSGi service inside the servlet.
One way would be to inject dependencies into the HttpServlet instance that is being registered to the OSGi HttpService like this:
MyServlet servlet = new MyServlet();
servlet.setFooService(fooService);
httpService.registerServlet("/myservlet", servlet, initparams, context);
I'm not sure if this is a valid approach since in non-OSGi environment the servlet life-cycle is managed by the Web Container and hence the service reference would not be injected for the servlet instances created later on.
There is another way to solve this when using PAX Web as an implementation of the OSGi HttpService. PAX Web exports the OSGi BundleContext into the ServletContext as a special attribute "osgi-bundlecontext". The BundleContext can then be used to obtain necessary service references:
public void init(ServletConfig servletConfig) throws ServletException {
ServletContext context = servletConfig.getServletContext()
BundleContext bundleContext =
(BundleContext) context.getAttribute("osgi-bundlecontext");
ServiceReference serviceRef =
bundleContext.getServiceReference("com.foo.FooService")
}
However this approach is rather ugly and ties you to a concrete implementation of the OSGi HttpService. Do you know any other (and possibly better) solution to this problem?
If you use a setter for the dependency on the service, as you have shown, it can work outside of OSGi as well. You just need to use some other dependency injection mechanism. If there is none, you could provide a subclass that initializes the servlet using JNDI lookups or from the servlet context.
public class MyServlet_AdapterForMissingDI extends MyServlet{
public void init(ServletConfig config){
setFooService(getItFromSomewhere());
}
}
The point being that if you have DI capabilities that can inject setFooService, you can just use the same servlet in OSGi and elsewhere, if you do not (and still want to support this case), you provide an adapter.
On a related note, check out Felix SCR to configure your object's dependencies, and Pax Web Extender Whiteboard, which takes care of hooking your servlet up with the HttpService.
Specifically, without SCR and Whiteboard, you need to think about the case when the fooService becomes unavailable later, or the HttpService gets started after your servlet.
In these cases your servlet would have a reference to a dead service that prevents the bundle from being garbage-collected, or your servlet would not be registered with the HttpService.
Update: Here is the SCR descriptor I use for one of my servlets. SCR handles servlet instantiation, life-cycle, registration (via Whiteboard), and dependencies. There is no OSGi-specific code in the servlet. There is not even the need for a BundleActivator anymore (SCR registers all services):
<component name="oracle.statusServlet" >
<implementation class="mypackage.DataSourceStatusServlet"/>
<property name="service.description" value="Oracle DataSource status servlet" />
<property name="alias" value="/OracleDataSourceStatus" />
<property name="servlet-name" value="Oracle DataSource status servlet" />
<service>
<provide interface="javax.servlet.Servlet" />
</service>
<reference name="DATASOURCES"
interface="javax.sql.DataSource"
cardinality="0..n" policy="dynamic"
bind="bindDataSource" unbind="unbindDataSource"/>
</component>
The dependencies for the servlet are specified in the reference tag. SCR will do the service lookup and binding.
May be an old post and you already might have got the answer..
Are you launching felix or whatever OSGi container yourself. If that is the case you can set the bundle context as an attribute to the servlet context.
Whats wrong in using an http service by PAX. ultimately the thread management and other aspects are taken care of by the servlet container in which you run this http service.
You could inject the services into some object, which is then queried by the servlets.

Resources