What are best practices for neo4j server plugin development? - neo4j

I was able to get the example plugins installed on my server using these docs: http://docs.neo4j.org/chunked/milestone/server-plugins.html
Now I want to develop my own plugins but I'm not sure how to debug and unit test them. Where can I read more about this and best practices for server plugin development?

You can develop your plugin just as simple java project, testing the plugins is easy, just instantiate them in a unit-test and pass the Node, GraphDatabaseService and parameters to the plugin method and inspect the results.

my plugin:
package ru.a360.neo4j.plugins;
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.server.plugins.*;
import org.neo4j.server.rest.repr.Representation;
import org.neo4j.server.rest.repr.ValueRepresentation;
import org.neo4j.tooling.GlobalGraphOperations;
import java.util.logging.Logger;
#Description("An extension to the Neo4j Server for find routes between two nodes")
public class WarmUp extends ServerPlugin
{
private Logger logger = Logger.getLogger(WarmUp.class.getName());
public WarmUp()
{
}
#Name("warm_up")
#Description("Warm up all nodes and relationships")
#PluginTarget(GraphDatabaseService.class)
public Representation warmUp(#Source GraphDatabaseService graphDb)
{
long t0 = System.currentTimeMillis();
int relCount = 0;
int nodesCount = 0;
GlobalGraphOperations ggo = GlobalGraphOperations.at(graphDb);
for (Node n: ggo.getAllNodes())
{
for (String prop: n.getPropertyKeys())
{
n.getProperty(prop);
}
nodesCount++;
}
for (Relationship rel: ggo.getAllRelationships())
{
for (String prop: rel.getPropertyKeys())
{
rel.getProperty(prop);
}
relCount++;
}
logger.info("warmup;" + (System.currentTimeMillis() - t0) / 1000.0 );
return ValueRepresentation.string("WARMED UP " + nodesCount + " NODES AND " + relCount + " RELATIONSHIPS");
}
}
There is new string in main/java/META-INF/services/org.neo4j.server.plugins.ServerPlugin:
ru.a360.neo4j.plugins.WarmUp
I want to write test (test/java/ru/a360/neo4j/plugins/TestNeo.java) like this:
package ru.a360.neo4j.plugins;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class TestNeo {
#Before
public void prepareTestData()
{
}
#After
public void destroyTestDatabase()
{
}
#Test
public void myTest1()
{
}
}

Related

Xtext: Calling the Generator from a Context Menu

Following
https://christiandietrich.wordpress.com/2011/10/15/xtext-calling-the-generator-from-a-context-menu/
and using EclipseResourceFileSystemAccess2 instead of EclipseResourceFileSystemAccess when the line
final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
give an exception. The only information I have is
// Compiled from InvocationTargetException.java (version 1.8 : 52.0, super bit)
public class java.lang.reflect.InvocationTargetException extends java.lang.ReflectiveOperationException {
I don't know how to get the stack trace in Eclipse.
does the code in the blog still function in the most recent release of Xtext?
Update 1
Snippets from plugin.xml
Handler:
<extension
point="org.eclipse.ui.handlers">
<handler
class="tuks.mcrl2.dsl.ui.handlers.Mcrl22Lps"
commandId="tuks.mcrl2.dsl.ui.commands.mcrl2lps">
</handler>
</extension>
Commands:
<extension
point="org.eclipse.ui.commands">
<command
categoryId="tuks.mcrl2.dsl.ui.category.processalgebra"
defaultHandler="tuks.mcrl2.dsl.ui.handlers.Mcrl22Lps"
description="Conver a mclr2 file to lps"
id="tuks.mcrl2.dsl.ui.commands.mcrl2lps"
name="mcrl22lps">
</command>
<category
id="tuks.mcrl2.dsl.ui.category.processalgebra"
name="Process Algebra">
</category>
</extension>
it basically works, if you do the update from EclipseResourceFileSystemAccess and Stuff and (maybe) IGenerator.
I assume in your case you dont set the Accesses ProgressMonitor and other props.
package org.xtext.example.mydsl.ui.handler;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.commands.IHandler;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.ui.handlers.HandlerUtil;
import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess2;
import org.eclipse.xtext.generator.GeneratorContext;
import org.eclipse.xtext.generator.IGenerator2;
import org.eclipse.xtext.resource.IResourceDescriptions;
import org.eclipse.xtext.ui.resource.IResourceSetProvider;
import com.google.inject.Inject;
import com.google.inject.Provider;
public class GenerationHandler extends AbstractHandler implements IHandler {
#Inject
private IGenerator2 generator;
#Inject
private Provider<EclipseResourceFileSystemAccess2> fileAccessProvider;
#Inject
IResourceDescriptions resourceDescriptions;
#Inject
IResourceSetProvider resourceSetProvider;
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
ISelection selection = HandlerUtil.getCurrentSelection(event);
if (selection instanceof IStructuredSelection) {
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
Object firstElement = structuredSelection.getFirstElement();
if (firstElement instanceof IFile) {
IFile file = (IFile) firstElement;
IProject project = file.getProject();
IFolder srcGenFolder = project.getFolder("src-gen");
if (!srcGenFolder.exists()) {
try {
srcGenFolder.create(true, true,
new NullProgressMonitor());
} catch (CoreException e) {
return null;
}
}
final EclipseResourceFileSystemAccess2 fsa = fileAccessProvider.get();
fsa.setProject(project);
fsa.setOutputPath("src-gen");
fsa.setMonitor(new NullProgressMonitor());
URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true);
ResourceSet rs = resourceSetProvider.get(project);
Resource r = rs.getResource(uri, true);
generator.doGenerate(r, fsa, new GeneratorContext());
}
}
return null;
}
#Override
public boolean isEnabled() {
return true;
}
}
and make sure you register the handler properly.
the
class="org.xtext.example.mydsl.ui.MyDslExecutableExtensionFactory:org.xtext.example.mydsl.ui.handler.GenerationHandler"
is crucial, especially that it consists of 2 parts, the ExtensionFactory followed by a : followed by the actual class name

Neo4j webadmin shows shows Labels, Relationships on Left side but does not list Nodes

I am using Neo4j 2.1.2 community edition. When I point neo4j to the database I created and login to webadmin, it shows the relationship type and and Labels I created in my code but when i try to fetch the nodes and relationship it does not list any thing.
See the screenshot attached.
I am creating my database using following piece of code.
import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.Label;
import org.neo4j.graphdb.Node;
import org.neo4j.graphdb.Relationship;
import org.neo4j.graphdb.RelationshipType;
import org.neo4j.graphdb.Transaction;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
public class HelloWorld {
private GraphDatabaseService m_databaseService;
private Node m_firstNode;
private Node m_secondNode;
private Relationship m_relationship;
public static void main(String[] args) {
new HelloWorld().startApplication();
}
private void startApplication() {
createDatabase();
createNodesAndrelationship();
shutDownDB();
}
private void createDatabase() {
m_databaseService = new GraphDatabaseFactory().newEmbeddedDatabase("E:\\ERM\\RoutingData\\neo4j");
}
private void createNodesAndrelationship() {
Transaction tx = m_databaseService.beginTx();
try {
m_firstNode = m_databaseService.createNode();
m_firstNode.addLabel(new Label() {
#Override
public String name() {
return "Demo";
}
});
m_firstNode.setProperty("message", "Hello");
System.out.println("Created First Node.");
m_secondNode = m_databaseService.createNode();
m_secondNode.setProperty("message", "world !");
m_secondNode.addLabel(new Label() {
#Override
public String name() {
return "Demo";
}
});
System.out.println("Created Second Node.");
m_relationship = m_firstNode.createRelationshipTo(m_secondNode, RelType.KNOWS);
m_relationship.setProperty("message", "bravo neo4j !");
System.out.println("Created relationship.");
tx.success();
} finally {
tx.failure();
}
System.out.println(m_firstNode.getProperty("message").toString() + " " + m_relationship.getProperty("message") + " " + m_secondNode.getProperty("message"));
}
private void shutDownDB() {
m_databaseService.shutdown();
System.out.println("Database shutdown completed.");
}
private static enum RelType implements RelationshipType {
KNOWS
}
}
Please suggest what am I doing wrong.
You are rolling back the transaction rather than committing it.
Replace tx.failure() with tx.close().
Also, this line needs to be moved before the tx.close() call, to avoid an org.neo4j.graphdb.NotInTransactionException:
System.out.println(m_firstNode.getProperty("message").toString() + " " + m_relationship.getProperty("message") + " " + m_secondNode.getProperty("message"));

Neo4J 2.0.2 + Gremlin plugin: the console doesn't run

I'm experimenting with Neo4J + Gremlin plugin, unfortunately I got this error (bellow) when I try to use the Gremlin console web (the console didn't runs on Gremlin language):
SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NoClassDefFoundError: org/neo4j/server/logging/Logger
at org.neo4j.server.webadmin.console.GremlinSession.<clinit>(GremlinSession.java:42)
at org.neo4j.server.webadmin.console.GremlinSessionCreator.newSession(GremlinSessionCreator.java:35)
......
Any suggestions?
Many thanks!
Neo4J 2.0.2 server has changed the Logger class, so I modified GremlinSession.java code in order to use java.util.logging.Logger class instead of org.neo4j.server.logging.Logger. Finally the Gremlin console web works fine:
Here you will find the new GremlinSession.java code.
/**
* Copyright (c) 2002-2014 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.neo4j.server.webadmin.console;
import com.tinkerpop.blueprints.TransactionalGraph;
import com.tinkerpop.blueprints.impls.neo4j2.Neo4j2Graph;
import groovy.lang.Binding;
import groovy.lang.GroovyRuntimeException;
import org.codehaus.groovy.tools.shell.IO;
import org.neo4j.graphdb.Transaction;
import org.neo4j.helpers.Pair;
import org.neo4j.server.database.Database;
import java.util.logging.Logger;
import java.util.logging.Level;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GremlinSession implements ScriptSession {
private static final String INIT_FUNCTION = "init()";
private static final Logger log = Logger.getLogger(GremlinSession.class.getName());
private final Database database;
private final IO io;
private final ByteArrayOutputStream baos = new ByteArrayOutputStream();
private final List<String> initialBindings;
protected GremlinWebConsole scriptEngine;
public GremlinSession(Database database) {
this.database = database;
PrintStream out = new PrintStream(new BufferedOutputStream(baos));
io = new IO(System.in, out, out);
Map<String, Object> bindings = new HashMap<String, Object>();
bindings.put("g", getGremlinWrappedGraph());
bindings.put("out", out);
initialBindings = new ArrayList<String>(bindings.keySet());
try {
scriptEngine = new GremlinWebConsole(new Binding(bindings), io);
} catch (final Exception failure) {
scriptEngine = new GremlinWebConsole() {
#Override
public void execute(String script) {
io.out.println("Could not start Groovy during Gremlin initialization, reason:");
failure.printStackTrace(io.out);
}
};
}
}
/**
* Take some gremlin script, evaluate it in the context of this gremlin
* session, and return the result.
*
* #param script
* #return the return string of the evaluation result, or the exception
* message.
*/
#Override
public Pair<String, String> evaluate(String script) {
String result = null;
try (Transaction tx = database.getGraph().beginTx()) {
if (script.equals(INIT_FUNCTION)) {
result = init();
} else {
try {
scriptEngine.execute(script);
result = baos.toString();
} finally {
resetIO();
}
}
tx.success();
} catch (GroovyRuntimeException ex) {
log.log(Level.SEVERE, ex.toString());
result = ex.getMessage();
}
return Pair.of(result, null);
}
private String init() {
StringBuilder out = new StringBuilder();
out.append("\n");
out.append(" \\,,,/\n");
out.append(" (o o)\n");
out.append("-----oOOo-(_)-oOOo-----\n");
out.append("\n");
out.append("Available variables:\n");
for (String variable : initialBindings) {
out.append(" " + variable + "\t= ");
out.append(evaluate(variable));
}
out.append("\n");
return out.toString();
}
private void resetIO() {
baos.reset();
}
private TransactionalGraph getGremlinWrappedGraph() {
Neo4j2Graph neo4jGraph = null;
try {
neo4jGraph = new Neo4j2Graph(database.getGraph());
} catch (Exception e) {
throw new RuntimeException(e);
}
return neo4jGraph;
}
}

Run JesterRecommenderEvaluationRunner, but get no results of evaluation

I downloaded the Jester example code in Mahout, and tries to run it on jester dataset to see the evaluation results. the running is done successfully, but the console only has the results:
log4j:WARN No appenders could be found for logger (org.apache.mahout.cf.taste.impl.model.file.FileDataModel).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
I expect to see the evaluation score range from 0 to 10. any one can help me found out how to get the score?
I am using mahout-core-0.6.jar and the following is the code:
JesterDataModel.java:
package Jester;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.regex.Pattern;
import com.google.common.collect.Lists;
import org.apache.mahout.cf.taste.example.grouplens.GroupLensDataModel;
import org.apache.mahout.cf.taste.impl.common.FastByIDMap;
import org.apache.mahout.cf.taste.impl.model.GenericDataModel;
import org.apache.mahout.cf.taste.impl.model.GenericPreference;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.Preference;
import org.apache.mahout.common.iterator.FileLineIterator;
//import org.apache.mahout.cf.taste.impl.common.FileLineIterable;
public final class JesterDataModel extends FileDataModel {
private static final Pattern COMMA_PATTERN = Pattern.compile(",");
private long userBeingRead;
public JesterDataModel() throws IOException {
this(GroupLensDataModel.readResourceToTempFile("\\jester-data-1.csv"));
}
public JesterDataModel(File ratingsFile) throws IOException {
super(ratingsFile);
}
#Override
public void reload() {
userBeingRead = 0;
super.reload();
}
#Override
protected DataModel buildModel() throws IOException {
FastByIDMap<Collection<Preference>> data = new FastByIDMap<Collection<Preference>> ();
FileLineIterator iterator = new FileLineIterator(getDataFile(), false);
FastByIDMap<FastByIDMap<Long>> timestamps = new FastByIDMap<FastByIDMap<Long>>();
processFile(iterator, data, timestamps, false);
return new GenericDataModel(GenericDataModel.toDataMap(data, true));
}
#Override
protected void processLine(String line,
FastByIDMap<?> rawData,
FastByIDMap<FastByIDMap<Long>> timestamps,
boolean fromPriorData) {
FastByIDMap<Collection<Preference>> data = (FastByIDMap<Collection<Preference>>) rawData;
String[] jokePrefs = COMMA_PATTERN.split(line);
int count = Integer.parseInt(jokePrefs[0]);
Collection<Preference> prefs = Lists.newArrayListWithCapacity(count);
for (int itemID = 1; itemID < jokePrefs.length; itemID++) { // yes skip first one, just a count
String jokePref = jokePrefs[itemID];
if (!"99".equals(jokePref)) {
float jokePrefValue = Float.parseFloat(jokePref);
prefs.add(new GenericPreference(userBeingRead, itemID, jokePrefValue));
}
}
data.put(userBeingRead, prefs);
userBeingRead++;
}
}
JesterRecommenderEvaluatorRunner.java
package Jester;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.eval.RecommenderEvaluator;
import org.apache.mahout.cf.taste.impl.eval.AverageAbsoluteDifferenceRecommenderEvaluator;
import org.apache.mahout.cf.taste.model.DataModel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
public final class JesterRecommenderEvaluatorRunner {
private static final Logger log = LoggerFactory.getLogger(JesterRecommenderEvaluatorRunner.class);
private JesterRecommenderEvaluatorRunner() {
// do nothing
}
public static void main(String... args) throws IOException, TasteException {
RecommenderEvaluator evaluator = new AverageAbsoluteDifferenceRecommenderEvaluator();
DataModel model = new JesterDataModel();
double evaluation = evaluator.evaluate(new JesterRecommenderBuilder(),
null,
model,
0.9,
1.0);
log.info(String.valueOf(evaluation));
}
}
Mahout 0.7 is old, and 0.6 is very old. Use at least 0.7, or better, later from SVN.
I think the problem is exactly what you identified: you don't have any slf4j bindings in your classpath. If you use the ".job" files in Mahout you will have all dependencies packages. Then you will actually see output.

Is there any easy way to perform Junit test for WSDL WS-I compliance

I am trying to validate generated WSDL to be correct. I have tried WS-i test tool downloaded from http://www.ws-i.org/ but it's test tool require all input to go through a config xml and the output is again an output xml file. Is there other easier way of validating a WSDL?
The Woden library/jar provides adequate functionality to be able to do this. If your wsdl isn't valid, the last statement, reader.readWSDL(...), will throw an exception.
import static junit.framework.Assert.fail;
import java.net.URISyntaxException;
import org.apache.woden.WSDLException;
import org.apache.woden.WSDLFactory;
import org.apache.woden.WSDLReader;
import org.apache.woden.wsdl20.Description;
import org.junit.Test;
public class WSDLValidationTest {
String wsdlFileName = "/MyService.wsdl";
#Test
public void validateWSDL2() throws WSDLException {
String wsdlUri = null;
try {
wsdlUri = this.getClass().getResource(wsdlFileName).toURI().toString();
}
catch( URISyntaxException urise) {
urise.printStackTrace();
fail( "Unable to retrieve wsdl: " + urise.getMessage());
}
WSDLFactory factory = WSDLFactory.newInstance("org.apache.woden.internal.OMWSDLFactory");
WSDLReader reader = factory.newWSDLReader();
reader.setFeature(WSDLReader.FEATURE_VALIDATION, true);
reader.readWSDL(wsdlUri);
}
}
And should you need a unit test for WSDL 1.1, see the following:
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import javax.wsdl.Definition;
import javax.wsdl.WSDLException;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;
import javax.xml.stream.XMLStreamException;
import org.junit.Before;
import org.junit.Test;
import org.xml.sax.SAXException;
import com.sun.xml.ws.api.model.wsdl.WSDLModel;
import com.sun.xml.ws.api.server.SDDocumentSource;
import com.sun.xml.ws.api.wsdl.parser.WSDLParserExtension;
import com.sun.xml.ws.api.wsdl.parser.XMLEntityResolver;
public class WSDLValidationTest {
String wsdlFileName = "/MyService.wsdl";
String wsdlUri = null;
URL wsdlUrl = null;
#Before
public void before()
{
try {
wsdlUrl = this.getClass().getResource(wsdlFileName);
wsdlUri = wsdlUrl.toURI().toString();
}
catch( URISyntaxException urise) {
urise.printStackTrace();
fail( "Unable to retrieve wsdl: " + urise.getMessage());
}
}
#Test
public void parseAndValidateWSDL1_1WithWSDL4J() throws WSDLException
{
WSDLReader wsdlReader = null;
try {
WSDLFactory factory = WSDLFactory.newInstance();
wsdlReader = factory.newWSDLReader();
}
catch( WSDLException wsdle) {
wsdle.printStackTrace();
fail( "Unable to instantiate wsdl reader: " + wsdle.getMessage());
}
// Read WSDL service interface document
Definition def = wsdlReader.readWSDL(null, wsdlUri);
assertNotNull(def);
}
#Test
public void parseAndValidateWSDL1_1WithJaxWS() throws IOException, XMLStreamException, SAXException
{
final SDDocumentSource doc = SDDocumentSource.create(wsdlUrl);
final XMLEntityResolver.Parser parser = new XMLEntityResolver.Parser(doc);
WSDLModel model = WSDLModel.WSDLParser.parse( parser, null, false, new WSDLParserExtension[] {} );
assertNotNull(model);
}
}

Resources