jackrabbit oak repository integration with spring framework - java

I have a web application running on tomcat and using spring framework. I also have jackrabbit oak libraries embedded in project.
I can get jackrabbit repository with java code like this:
new Jcr(new Oak(ns)).createRepository();
but I want to define my repository in a repository.xml file and then put it somewhere and instantiate it with spring xml files, so I can customize various things like ExternalIdentityProvider in my repository.
Something like this I think:
<bean id="repository" class="org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl"
references="repository.xml"/>
but I don't know how I should define this repository in spring. any suggestion?

just use it like any other library:
put some variables in your application.properties
use Java config (XML config is not the most robust one)
access those variables using your favourite way
build your ns object using those variables
register the outcome of new Jcr(new Oak(ns)).createRepository() as a Bean that uses the newly created ns object - this should help you
and that should do the trick :)

Related

RESTful service in Karaf without blueprint xml

I am new to Karaf, hence was looking for resources to create a project for RESTful web services using felix annotations and without the use of BundleActivator class(i mean by an actual class that needs to be written by me, but its ok if some compiler or maven plugin does the same for me) and blueprint xml file. So far I got success in the first part(BundleActivator part) which now after compilation auto creates my MANIFEST.MF with import and export statements, creates the relevant XML file for each component class, and packages it into a a nice jar bundle which works very well when I deploy it on Karaf container. But what is not working is the RESTful services. The bundle is deployed correctly, but the REST urls are not exposed and hence I am unable to access them.
Please help me in getting this done. I don't want to write an XML file which needs to be modified everytime there is an addition or deletion of a rest service.
Thanks
If you want to completely avoid blueprint then you should use cxf-dosgi. You simply annotate your rest service using jaxrs and publish it as an OSGi service with some special properties.
See the cxf-dosgi rest sample.
The example uses the standard DS annotation and the maven bundle plugin to create the DS component xml on the fly.
If you prefer to have blueprint at runtime then you can use the blueprint-maven-plugin. See this example.
I figured out a way to do so without using the CXF feature. That is, create a component class and in activate method get the object of ConfigurationAdmin and put the required context path against the jersy server process(using jersey publisher jar). Using this mehtod, I was able to deploy any rest/serlvet in Karaf without using blueprint.xml file. I hope this helps.

Adding custom nodetypes to Apache Sling WebApp

I'm trying to figure out a way to add custom nodetypes using a CND file to my Sling WebApp. I downloaded the WAR file and got it running but since all the code is already compiled (as .class files), I can't add code to read the CND file and add the custom nodetypes.
On a separate note, I do have Jackrabbit running and with it, I can use the JackrabbitNodeTypeManager or other ways to code reading a CND file and adding nodetypes. This works on my local repository that is not running on a server.
I want to be able to add new nodetypes to the Sling Web Application in a similar way. So I'll boil my questions down to:
Is there a way to code the addition of new nodetypes in the Sling WebApp?
How can I connect my Jackrabbit repository (local) to the Sling Web Application (on server) so that I can possibly explore adding custom nodetypes this way (as I'm doing on my Jackrabbit repo locally at the moment)?
I understand that Sling is a framework that uses Jackrabbit as a repo and provides REST-like services to work with the repository, but I imagine there's a way to add these custom nodetypes just like Jackrabbit allows.
Thanks.
Is there a way to code the addition of new nodetypes in the Sling WebApp?
This is documented at Declared Node Type Registration. What you need to do is
write the node type definition in CND format
place it in a bundle
reference the file in the manifest using the Sling-Nodetypes header
deploy the bundle to your Sling app

How to configure Spring to load application.properties from outside of jar?

I'd like to have a directory structure as so:
/Directory
- Application.jar
- application.properties
So that I can change properties without having to repackage and redeploy (and instead just restarting the jar). How can I accomplish this with spring annotations or configuration classes?
I'm not asking about making external resources available with my web application, I'm also looking to change the location from where spring loads the application.properties file.
You're mentioning jar, so you're using Spring Boot?
If so, external application.properties in the same directory (structure just like you described) will override application.properties packaged inside the jar file.
Then, if you have something like key=value in your application.properties, you can inject it in your code with #Value("${key}") String key.
Try it, it will just work :)
You may want to explore PropertyPlaceholderExplorer class in Spring. This class provides the facility to access the properties file external to your jar/war bundle. There is a short nice tutorial on this as well here.
If you start using Spring Boot (at some stage you for sure will). you get powerful configuration externalization features.
With Spring Boot your applications.properties are automatically loaded into Spring Boot context and you can use ${...} placeholders.
You can use even more modern feature #ConfigurationProperties to map you configuration to POJO. This POJO can even be validated by Java EE validation annotations (e.g. #NotNull)

neo4j community V1.9 - how to specify path of config files in Spring?

I need multiple neo4j embedded databases running on the same machine, on different ports.
I'm building on Spring -- how best to configure via Spring to do that? Ideally I want separate property files for each app, rather than baking the ports in the code -- e.g. /etc/app1.conf, /etc/app2.conf, and to be able to specify the relevant ports and other properties in those files.
I understand that such configuration was once possible in earlier versions of neo4j through a EmbeddedServerConfigurator class, which is no longer present in 1.8+
I'm running 1.9.5 with an eye to 2.0 in the nearish future, so a non-deprecated way of doing this would be much appreciated.
D
Darrell, if you run embedded there are no ports and no config files.
You just provide store-directories and optionally database config to your GraphDatabaseService instances which are (in Spring Data Neo4j) created as spring beans.
Unfortunately there is no compatible way between 1.9 and 2.0 as the public constructors of EmbeddedGraphDatabase were removed in 2.0 and I added a GraphDatabaseServiceFactoryBean in SDN 3.0 / Neo4j 2.0.
To run a server with an embedded Neo4j you'd probably have to go the way of extending CommunityBootstrapper. But here is no out of the box way integrating this in Spring right now.
So to make it work, I'd probably create a subclass of CommunityBootstrapper which starts the server, but can be passed in the GraphDatabaseService from the outside.
See my in-memory-server project for some hints: https://github.com/jexp/neo4j-in-memory-server

Overwrite configuration for Spring project from outside

I'm developing a Spring application which shall be used by any kind of other application, no matter if that is a Spring project, a web application or even a simple single-class console application. The application who uses my project will just have to add the JAR file with my application.
So my project has a static factory class that gets and returns a bean from its Spring context which acts as an access object to access all public available functions of my project.
That part is already working.
But I need the developer of the application that uses my JAR to be able to overwrite certain configurations in my project without editing the config files in the JAR itself. At the moment those settings should be overwritable:
- the data source and hibernate bean configuration
- the jasypt (encryption) bean configuration
- the log4j settings
How do I make those settings overwriteable with configs from outside the jar?
Greetings
touchdown
Maybe a good solution would be a configuration that the user could override, for this take a look into:
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-java
Specially to #Configuration and #Bean
Maybe you could have a configuration class implemented and the user can override it. After extending the class and overwrite some methods that provides some beans the user shall inform it to your factory that will do nothing else than
new AnnotationConfigApplicationContext(userConfigurationClass);
If you want to replace the complete configuration, than the easyest way would be to have a parametrized factory that takes an alternative configuration file as its argument.
If you need it a bit more fine grain (lets say up to 10 parts), than you can split your application xml in several smaller once, and use again a configurable factory that allows to exchange the smaller xml files.
So I got a solution that is working for me.
I put an general import for override context-XMLs at the bottom of my main application context:
<import resource="classpath*:project/package/config/override/or-*.xml" />
So all the user has to do is to create the package "project/package/config/override" in his classpath (e.g. resource folder) and place matching XML files in it with new bean definitions.

Categories