Exposing Neo4J REST within TomCat - neo4j

I have an SDN 2.3.1 application running 1.9 Neo4J embedded which is deployed on Tomcat 7. All good when running both embedded and rest. However, I'm now looking to try and expose the REST interface having followed This Post so that I cuse Linkurious to explore the embedded data.
The exception I get on deployment is:
com.sun.jersey.api.container.ContainerException: No WebApplication provider is present
My XML config is
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase" destroy-method="shutdown">
<constructor-arg index="0" value="${neo4j.datastore}"/>
<constructor-arg index="1">
<map>
<entry key="allow_store_upgrade" value="true"/>
<entry key="enable_remote_shell" value="true"/>
</map>
</constructor-arg>
</bean>
<bean id="serverWrapper" class="org.neo4j.server.WrappingNeoServer" init-method="start" destroy-method="stop">
<constructor-arg ref="graphDatabaseService"/>
</bean>
I have the static-web and neo4j-server in my pom.xml
My guess is it's a conflict with Jetty and Tomcat around who's allowed to deploy to a context. Is my config even possible and if so, what step might I be missing?

Missing transitive dependency on Jersey which I didn't spot in documentation.
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.17.1</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.17.1</version>
</dependency>
The web admin interface is throwing an exception but I can at least run embedded and expose a RESTful interface to Neo4J- Yay!
Thanks to this post for the pointer

Related

Not all MBean available in Confluence

I have confluence 5.10.6 on tomcat 8.
In tomcat I have setup jmx:
CATALINA_OPTS="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=6969 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false ${CATALINA_OPTS}"
and using jconsole trying to have access to Confluence MBeans.
Unfortunately only several of MBeans available:
CacheStatistics
IndexingStatistics
MailTaskQueue
SchedulingStatistics
SystemInformation
But I need also RequestMetrics (https://confluence.atlassian.com/doc/live-monitoring-using-the-jmx-interface-150274182.html).
What I missed in my configuration?
Your configuration is perfectly fine.
The missing RequestMetrics MBean is actually a known bug in Confluence since 5.9.2: https://jira.atlassian.com/browse/CONF-40442
You can vote for this issue there to raise awareness by Atlassian.
I have the same MBeans, in my evaluation version of the confluence.
I have a "confluense.jar" file with "jmxContext.xml" inside.
jmxContext.xml (it contains a reference to MBeanExporterWithUnregisterImpl implementaion) :
<bean id="exporter" class="com.atlassian.confluence.jmx.MBeanExporterWithUnregisterImpl">
<constructor-arg index="0" ref="eventPublisher"/>
<constructor-arg index="1" ref="tenantAccessor"/>
<property name="server" ref="mbeanServer"/>
<property name="beans">
<map>
<entry key="Confluence:name=MailTaskQueue">
<bean class="com.atlassian.confluence.jmx.TaskQueueWrapper"><constructor-arg
ref="mailTaskQueue"/></bean>
</entry>
<entry key="Confluence:name=IndexingStatistics">
<bean class="com.atlassian.confluence.jmx.JmxIndexManagerWrapper"><constructor-arg
ref="indexManager"/></bean>
</entry>
<entry key="Confluence:name=SchedulingStatistics">
<bean class="com.atlassian.confluence.jmx.JmxScheduledTaskWrapper"><constructor-arg
ref="scheduler"/></bean>
</entry>
<entry key="Confluence:name=SystemInformation">
<bean class="com.atlassian.confluence.jmx.JmxSystemInfoWrapper"><constructor-arg
ref="systemInformationService"/></bean>
</entry>
<entry key="Confluence:name=CacheStatistics">
<bean class="com.atlassian.confluence.jmx.JxmCacheStatisticsWrapper">
<constructor-arg ref="cacheStatisticsManager"/>
</bean>
</entry>
</map>
</property>
<property name="exposeManagedResourceClassLoader" value="true"/>
</bean>
So, at least there is nothing wrong, because our installation does not support RequestMetrics mbean, and as far as we can see the RequestMetrics.class inside of confluence.jar, i believe it is a licensing issue.

how to configure a neo4j EmbeddedGraphDatabase (now deprecated) with spring-data-neo4j?

I'm using spring-data-neo4j 3.1.1.Release with neo4j 2.1.2. I managed to make a spring configuration which is working well but it use the org.neo4j.kernel.EmbeddedGraphDatabase class which is now deprecated. Here is my current configuration :
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
destroy-method="shutdown">
<constructor-arg index="0" value="${graphdir}"/>
<!-- optionally pass in neo4j-config parameters to the graph database -->
<constructor-arg index="1">
<map>
<entry key="allow_store_upgrade" value="true"/>
</map>
</constructor-arg>
<constructor-arg index="2" ref="defaultGraphDatabaseDependencies" />
</bean>
<bean id="defaultGraphDatabaseDependencies" class="org.neo4j.kernel.DefaultGraphDatabaseDependencies"/>
<neo4j:config graphDatabaseService="graphDatabaseService" base-package="com.company.domain"/>
How can I write the same kind of spring configuration but using non deprecated classes please ?
You can use the GraphDatabaseFactory class using spring for this. I've blogged about at http://blog.armbruster-it.de/2013/08/configuring-a-neo4j-graphdatabaseservice-via-spring/

How can I use the webadmin interface with an embedded Neo4j 2.0 instance?

I have a project which has been running with an embedded Neo4j 1.8.2 plus web admin interface.
Now I updated the project to run with the latest Neo4j 2.0.1. Although there were some obstacles during that course (as I'm utilizing Spring Data Neo4j) in the end everything went smooth.
But currently I'm stuck in getting the web admin running with it.
Any advise would be highly appreciated.
Here's my config which I was using for the 1.8 version
(class for configuration referenced in the snippets)
package com.example;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.MapConfiguration;
import org.neo4j.server.configuration.Configurator;
import org.neo4j.server.configuration.ThirdPartyJaxRsPackage;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class Neo4jServerConfig implements Configurator {
private Configuration config;
public Neo4jServerConfig(Map<String, String> config) {
this.config = new MapConfiguration(config);
}
#Override
public Configuration configuration() {
return config;
}
#Override
public Map<String, String> getDatabaseTuningProperties() {
return null;
}
#Override
public Set<ThirdPartyJaxRsPackage> getThirdpartyJaxRsClasses() {
return new HashSet<>();
}
#Override
public Set<ThirdPartyJaxRsPackage> getThirdpartyJaxRsPackages() {
return new HashSet<>();
}
}
And the bean definitions
...
...
...
...
As mentioned ... this works as expected for the 1.8 embedded Neo4j.
But initialization under Neo4j 2.0 changed quite a bit. So I was forced to use the following bean definitions to get things running again
<!-- neo4j server configuration -->
<util:map id="neo4jConfig">
<entry key="allow_store_upgrade" value="true"/>
<entry key="enable_remote_shell" value="true"/>
<entry key="online_backup_enabled" value="true"/>
<entry key="node_auto_indexing" value="true"/>
<entry key="node_keys_indexable" value="id,name,type,__type__"/>
<entry key="relationship_auto_indexing" value="true"/>
</util:map>
<bean id="graphDbFactory" class="org.neo4j.graphdb.factory.GraphDatabaseFactory"/>
<bean id="graphDbBuilder" factory-bean="graphDbFactory" factory-method="newEmbeddedDatabaseBuilder">
<constructor-arg index="0" value="${neo4j.db.path}"/>
</bean>
<bean id="graphDbBuilderFinal" factory-bean="graphDbBuilder" factory-method="setConfig">
<constructor-arg ref="neo4jConfig"/>
</bean>
<bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal" factory-method="newGraphDatabase" destroy-method="shutdown" />
After that I get error markers in this bean definition
<bean id="serverWrapper" class="org.neo4j.server.WrappingNeoServerBootstrapper" init-method="start" destroy-method="stop">
<constructor-arg index="0" ref="graphDatabaseService" />
<constructor-arg index="1" ref="config"/>
</bean>
First, the "org.neo4j.server.WrappingNeoServerBootstrapper" is now deprecated - are there any alternatives, I can use?
And secondly it complains about wrong constructor-arg "graphDatabaseService" ... it says "bean must be of org.neo4j.kernel.GraphDatabaseAPI" (which is also deprecated)
The server starts (at least what I can see from my jetty logs) without errors, but trying to browse to localhost:28473 ends up with no response.
Any clue?
Thanks in advance.
WrappingNeoServerBootstrapper & GraphDatabaseAPI are deprecated, but there is no alternitve for now ... So you have to use them.
For you, this a sample code of my application, where webadmin is started with an embedded neo4j 2.0.1 server :
val graphdb = new GraphDatabaseFactory()
.newEmbeddedDatabaseBuilder(DBPath)
.loadPropertiesFromFile(neo4jPropertiesPath)
.newGraphDatabase()
.asInstanceOf[GraphDatabaseAPI}
val srv = new WrappingNeoServerBootstrapper(graphdb, config);
srv.start()
So you must cast your "graphDatabaseService" to "GraphDatabaseAPI".
Sorry I don't khnow how to this with spring ... but you can do a wrapper of WrappingNeoServerBootstrapper with the good type.
Cheers
Took me longer than I care to admit to get this working. Please take a look at this pom for the dependencies, basically 2 includes for neo4j-server and 2 for Jersey. You also have to config the WrappingNeoServerBootstrapper (deprecated).
My POM excludes the CH.QOS logging stuff from Neo4J in favour of my own log configuration.
I've used Spring as well and have externalised most of the config. You can see that file here.
Once that little lot is done, simply access localhost on port 7474.
<util:map id="config">
<entry key="remote_shell_enabled" value="true"/>
</util:map>
<bean id="graphDbFactory" class="org.neo4j.graphdb.factory.GraphDatabaseFactory"/>
<bean id="graphDbBuilder" factory-bean="graphDbFactory" factory-method="newEmbeddedDatabaseBuilder">
<constructor-arg value="${neo4j.datastore}"/>
</bean>
<bean id="graphDbBuilderFinal" factory-bean="graphDbBuilder" factory-method="setConfig">
<constructor-arg ref="config"/>
</bean>
<bean id="graphDatabaseService" factory-bean="graphDbBuilderFinal" factory-method="newGraphDatabase"
destroy-method="shutdown"/>
<bean id="serverWrapper" class="org.neo4j.server.WrappingNeoServerBootstrapper" init-method="start"
destroy-method="stop">
<constructor-arg ref="graphDatabaseService"/>
</bean>
So verified this on OSX; Just to be clear once you add the POM updates and the spring configuration, that is all you need to do. Then just browsing to localhost:7474 gives you your object graph.

Spring Data Neo4j: Using the server with an embedded

I'm trying to configure my application context in order to be able to use the Neo4j server with an embedded graph in my app without much success. I'm using Spring Data at the same time (both Mongo and Neo4j repositories approach). This is my application-context, which isn't running:
<context:component-scan base-package="org.domain.team.project.*"/>
<mongo:repositories base-package="org.domain.team.project.data.repositories.mongodb"/>
<!-- Neo4j -->
<!-- <neo4j:config storeDirectory="/data/production/graph.db"/> -->
<neo4j:repositories base-package="org.domain.team.project.data.repositories.neo4j"/>
<neo4j:config graphDatabaseService="graphDatabaseService" />
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
destroy-method="shutdown">
<constructor-arg index="0" value="/data/production/graph.db" />
<constructor-arg index="1">
<map><entry key="enable_remote_shell" value="true"/></map>
</constructor-arg>
</bean>
<bean id="serverWrapper" class="org.neo4j.server.WrappingNeoServerBootstrapper"
init-method="start" destroy-method="stop">
<constructor-arg ref="graphDatabaseService"/>
</bean>
If I don't use this approach and specify simply the store directory (commented line) everything runs fine. I suspect it's a version between SDN and neo4j-server issue. This is my POM:
<properties>
<spring.data.mongo.version>1.1.0.RELEASE</spring.data.mongo.version>
<spring.data.neo4j.version>2.1.0.RELEASE</spring.data.neo4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>${spring.data.mongo.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-neo4j</artifactId>
<version>${spring.data.neo4j.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>org.neo4j.app</groupId>
<artifactId>neo4j-server</artifactId>
<classifier>static-web</classifier>
<version>1.8.2</version>
</dependency>
</dependencies>
Its parent has as a dependency Spring(core,context,test) 3.2.0 Release.
The concrete error being displayed is:
Caused by: java.lang.NoSuchFieldError: query_cache_size
at org.neo4j.cypher.ExecutionEngine.org$neo4j$cypher$ExecutionEngine$$getQueryCacheSize(ExecutionEngine.scala:95)
at org.neo4j.cypher.ExecutionEngine$$anon$1.<init>(ExecutionEngine.scala:91)
at org.neo4j.cypher.ExecutionEngine.<init>(ExecutionEngine.scala:91)
at org.neo4j.cypher.javacompat.ExecutionEngine.<init>(ExecutionEngine.java:54)
at org.neo4j.cypher.javacompat.ExecutionEngine.<init>(ExecutionEngine.java:44)
at org.springframework.data.neo4j.support.query.CypherQueryEngine.<init>(CypherQueryEngine.java:42)
at org.springframework.data.neo4j.support.DelegatingGraphDatabase.createCypherQueryEngine(DelegatingGraphDatabase.java:217)
at org.springframework.data.neo4j.support.DelegatingGraphDatabase.queryEngineFor(DelegatingGraphDatabase.java:190)
at org.springframework.data.neo4j.support.MappingInfrastructureFactoryBean.afterPropertiesSet(MappingInfrastructureFactoryBean.java:146)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1545)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1483)
... 47 more
which as far as I am concerned, should be no problem as the default value is 100. The SDN doc does not talk too much about it. Any suggestions?
Thank you all in advance.
Looks like version compatibility issue. For me below combination is working fine
spring-data-neo4j : 2.1.0.RC4
spring-data-mongodb : 1.1.0.RELEASE
neo4j-server : 1.8
static-web : 1.8
Further, I am using-
Spring framework version : 3.1.2.RELEASE
Neo4j version : 1.8
mongodb version : 2.2.2
mongo-java-driver : 2.9.1
slf4j : 1.7.2

JMX server locator replacement in JBoss AS 7 for class MBeanServerLocator

I am currently using JBoss 4.3 for a web application. I would like to move to the JBoss AS 7. I have been able to fix must of the differences of the application in both versions but one. The application has some JMX beans that are created thru the spring framework. Unfortunately the AS 7 release removed the class: org.jboss.mx.util.MBeanServerLocator which was used in spring to locate the JBoss JMX server and create some beans. I am not to familiar with JMX but so far the only thing I have found so far is:
"http://lists.jboss.org/pipermail/jboss-as7-dev/2011-February/000569.html". I was wondering if somebody knows how to replace the class above from JBOSS with the new JMX 1.6 classes. Here is my spring configuration snipet for the piece I need to fix:
<bean class="org.springframework.jmx.export.MBeanExporter">
<property name="server">
<bean class="org.jboss.mx.util.MBeanServerLocator" factory-method="locateJBoss"/>
</property>
<property name="beans">
<map>
<entry key="MywebMbeans:name=profileListenerContainer" value-ref="profileListenerContainer"/>
<entry key="MywebMbeans:name=jmsSenderService" value-ref="jmsSenderService"/>
<entry key="MywebMbeans:name=mailSender" value-ref="mailSender"/>
</map>
</property>
<property name="assembler" ref="mbeanAssembler"/>
</bean>
Thanks,
The MBeanServer used by JBoss 7 (by default) is the platform MBeanServer. The class name is com.sun.jmx.mbeanserver.JmxMBeanServer and the default domain is DefaultDomain. Accordingly, you can simply use:
java.lang.management.ManagementFactory.getPlatformMBeanServer()
Alternatively:
for(MBeanServer server: javax.management.MBeanServerFactory.findMBeanServer(null)) {
if("DefaultDomain".equals(server.getDefaultDomain())) return server;
}
throw new Exception("Failed to locate MBeanServer");
Actually I just look in the JMX page for spring
http://static.springsource.org/spring/docs/1.2.x/reference/jmx.html
The following will work in both JBoss instaces 4 and 7.
<bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean">
<property name="locateExistingServerIfPossible" value="true" />
</bean>
<bean class="org.springframework.jmx.export.MBeanExporter">
<property name="server" ref="mbeanServer"/>
</property>
<property name="beans">
<map>
<entry key="MywebMbeans:name=profileListenerContainer" value-ref="profileListenerContainer"/>
<entry key="MywebMbeans:name=jmsSenderService" value-ref="jmsSenderService"/>
<entry key="MywebMbeans:name=mailSender" value-ref="mailSender"/>
</map>
</property>
<property name="assembler" ref="mbeanAssembler"/>
</bean>

Resources