Neo4j - How to handle incompatible RestGraphDatabase calls - java

In my project I'm using Neo4j's Core-API through GraphDatabaseService. In Tests we have an EmbeddedGraphDatabase where everything works as expected. I then wrote some tests to see how my implementation behaves on a RestGraphDatabase, just to find out, that most of it fails!
(The GraphDatabaseService is obtained by GraphDatabaseFactory of the Rest-API, so without an instanceof check I do not know which one it is)
Some examples:
If I use GlobalGraphOperations everything will fail, because GlopalGraphOperations are not supported by the RestGraphDatabase. (Strange enough that GlobalGraphOperations.at doesn't throw but all methods from GlobalGraphOperations).
Then I thought "ok I'll use Cypher to get the same behavior."
I tryed to implement a Method like this:
public getNodesWithLabel(String label, GraphDatabaseService graphService){
try(Transaction tx graphService.beginTx()){
ExecutionEngine ee = new ExecutionEngine(graphService);
//throws NullPOinterExeption in execute method
ExecutionResult result = ee.execute("MATCH (n:" + label + ") RETURN n");
result.columnAs("n");
//... mapping of Nodes
}
}
Searching through the API I see, that there is a RestCypherQueryEngine which is initialized via a RestAPIFascade. Problem here is, that the methods are not interchangeable, do not implement the same interface, and the return types are completeley different (i.e. ExecutionResult vs QueryResult)
So my question is: Is there a way, to get the same behavior from Neo4j where the used technology (Rest vs. Embedded) doesn't matter? Some kind of a technology independed Wrapper will suit my needs.
by the way, I'm using Neo4j in Version 2

Just don't do it. What it would do (if it worked) would be to execute every call to the database over the wire, ever read and write of nodes, rels and properties. You don't want to do that.
Use this instead.
queryEngine = new RestCypherQueryEngine(restGraphDb.getRestAPI());
queryEngine.query(query, params)
This sends the queries to the server and runs them there.

Related

How we can get forest data directory in MarkLogic

I am trying to get the forest Data directory in MarkLogic. I used the following method to get data directory...using the Server Evaluation Call Interface running queries as admin. If not, please let me know how I can get forest data directory
ServerEvaluationCall forestDataDirCall = client.newServerEval()
.xquery("admin:forest-get-data-directory(admin:get-configuration(), admin:forest-get-id(admin:get-configuration(), \"" + forestName +"\"))");
for (EvalResult forestDataDirResult : forestDataDirCall.eval()) {
String forestDataDir = null;
forestDataDir = forestDataDirResult.getString();
System.out.println("forestDataDir is " + forestDataDir);
}
I see no reason for needing to hit the server evaluation endpoint to ask this question to the server. MarkLogic comes with a robust REST based management API including getters for almost all items of interest.
Knowing that, you can use what is documented here:
http://yourserver:8002/manage/v2/forests
Results can be in JSON, XML or HTML
It is the getter for forest configurations. Which forests you care about can be found by iterating over all forests or by reaching through the database config and then to the forests. It all depends on what you already know from the outside.
References:
Management API
Scripting Administrative Tasks

OpenRDF/Sesame don't delivers an Model

I was using FUSEKI and now changed to OpenRDF/Sesame.
Everything works fine, i have just one problem.
In one method i need to get back the complete database of my repositori in a Model. The Method looks like this:
private static Model getRepositoryModel() throws ResourceRepositoryException{
String queryString = "DESCRIBE * WHERE {?r ?s ?p}";
Model currentModel = QueryExecuter.executeSparqlDescribeQuery(queryString);
return currentModel; }
public static Model executeSparqlDescribeQuery(String queryString) throws ResourceRepositoryException {
Model resultModel = null;
try{
QueryExecution qe = QueryExecutionFactory.sparqlService(SESAME_SERVICE_QUERY, queryString);
resultModel = qe.execDescribe();
} catch(QueryExceptionHTTP | QueryParseException e){
throw new ResourceRepositoryException(e.getMessage());
}
correctNsPrefixes(resultModel);
return resultModel;}
But i don't actually get a Model back. But in SPARQL you have to get one back if you call this method. It also worked with FUSEKI.
From your comments I gather that you are using Jena to query a remote Sesame Server (it wasn't clear earlier that that was what you were doing, I initially thought you had switched your own client code over to use Sesame as well but had posted the wrong/old code). Although this is a slightly unconventional setup (most people using Sesame Server also use the Sesame APIs to actually query/access it), it certainly should be possible.
Apparently, however, you are using something like this as the Sesame SPARQL endpoint URL:
http://localhost:8080/openrdf-workbench/repositories/test
(assuming your repository is named 'test').
This is not the correct URL to use. It should be:
http://localhost:8080/openrdf-sesame/repositories/test
Notice the difference: not "openrdf-workbench", but "openrdf-sesame".
The workbench is a client UI for a Sesame Server, it is not intended to be used as the SPARQL endpoint itself. The fact that it apparently works if you use it for SELECT-queries is just an unfortunate side effect. It is not intended to be used as such.

Drools render output in a webpage

I'm new to Drools Expert, currently from the Sample project of the drools what I can only do is print something to the console. Now I integrate drools to a web project and It was successful, I was be able to print something to the console depending on the interaction of the user to the page.
My rules currently is like this:
rule "A test Rule"
when
m: FLTBean ( listeningScore == 1, test : listeningScore )
then
System.out.println( test );
end
So what if I want to print it out to a web page? How would I do that? Do I need to use return to return some value back to the java page and render it to the page?
In order to display something on a web page, then you need to be using the API to invoke Drools and get some output, which can then be rendered by your web application.
Therefore, you need to consider how to get output from it within your Java code. There are a few ways of doing this.
For example, when performing a simple action such as validating a request, then just operate on the request which you insert. For instance:
rule "IBAN doesn't begin with a country ISO code."
no-loop
when
$req: IbanValidationRequest($iban:iban, $country:iban.substring(0, 2))
not Country(isoCode == $country) from countryList
then
$req.reject("The IBAN does not begin with a 2-character country code. '" + $country + "' is not a country.");
update($req);
end
In that example, I'm calling a "reject" method on the fact which I inserted. That modifies the inserted fact, so that after rules execution, I have an object in my Java code, with a flag to indicate whether it was rejected or not. This method works well for stateless knowledge sessions. i.e.
Java code - Insert request fact via API
Drools rule - Modify the request fact (flag rejection, annotate, set properties, etc)
Java code - Look at the fact to see what was done to it
The following code example of how to perform this interaction is taken from the following full colass:
https://github.com/gratiartis/sctrcd-payment-validation-web/blob/master/src/main/java/com/sctrcd/payments/validation/payment/RuleBasedPaymentValidator.java
// Create a new knowledge session from an existing knowledge base
StatelessKnowledgeSession ksession = kbase.newStatelessKnowledgeSession();
// Create a validation request
PaymentValidationRequest request = new PaymentValidationRequest(payment);
// A stateless session is executed with a collection of Objects, so we
// create that collection containing just our request.
List<Object> facts = new ArrayList<Object>();
facts.add(request);
// And execute the session with that request
ksession.execute(facts);
// At this point, rules such as that above should have been activated.
// The rules modify the original request fact, setting a flag to indicate
// whether it is valid and adding annotations to indicate if/why not.
// They may have added annotations to the request, which we can now read.
FxPaymentValidationResult result = new FxPaymentValidationResult();
// Get the annotations that were added to the request by the rules.
result.addAnnotations(request.getAnnotations());
return result;
An alternative in a stateful session would be that rules could insert facts into working memory. After executing the rules, you can then query the session via the API and retrieve one or more result objects. You can get all facts in the session using the getObjects() method of the KnowledgeSession. To get facts with particular properties, there is also a getObjects(ObjectFilter) method. The project linked below has examples of using these methods in the KnowledgeEnvironment and DroolsUtil classes.
Alternatively, you could insert a service as a global variable. The rules could then invoke methods on that service.
For an example of how to use Drools within a web application, I knocked up this web site recently, which provides a REST API to invoke Drools rules and get responses.
https://github.com/gratiartis/sctrcd-payment-validation-web
If you have Maven installed, you should be able to try it out pretty quickly, and play around with the code.

JRules Studio - Display values of IN_OUT parameters while testing

I'm using JRules Studio to develop some extremely simple rules. The rules populate an IN_OUT parameter. When the test finishes, is there a way of interrogating the values in the IN_OUT object?
Initially I'd like to interrogate it in the debugger, but any other ideas would be welcomed.
I am not sure to understand the question:
Your JAVA code is like this:
IlrSessionFactory factory = new IlrJ2SESessionFactory();
IlrStatelessSession session = factory.createStatelessSession();
IlrSessionRequest sessionRequest = factory.createRequest();
sessionRequest.setRulesetPath(“/RuleAppName/rulesetName”);
sessionRequest.setTraceEnabled(true);
sessionRequest.getTraceFilter().setInfoAllFilters(true);
Map inputParameters = new HashMap ();
Report in_report = new Report(); // no-arg constructor
// ... populate the Object ...
inputParameters.put("report", in_report);
sessionRequest.setInputParameters(inputParameters);
IlrSessionResponse sessionResponse = session.execute(sessionRequest);
Report out_report = (Report)sessionResponse.getOutputParameters().get("report“);
And then you play with your "out" parameters... As you would do with any JAVA object
If you want to see them at debug time, I would say:
1/ (not tested) Have a look on the "working memory tab" in the debugger perspective
I am not sure but this is the easiest way to find them if it is visible here
2/ (tested) in the initial action of the starting point of your ruleflow, add:
context.insert(the technical name of your parameter);
Not the "business name". Anyway avoid using BAL in technical artifact such as ruleflow, IRL rules!
By doing this you force the engine to insert your parameter in the working memory.
No duplication (don't worry, it will work like a charm) but as far as I can remember this is the shortest way to make them visible in the Eclipse debugger in JRules
Hope it helps

What does eclipse do when you inspect variables (while debugging)

I have an instance of org.hibernate.envers.entities.mapper.relation.lazy.proxy.ListProxy that is causing some grief: whenever I programmatically try to access it I get a null pointer exception (ie calling list.size()) but when I first inspect the object using Eclipse's variable inspector I see Hibernate generate a SQL statement and the list changes dynamically. Then everything works. How can I do the same thing programmatically? I've tried list.toString() but that doesn't seem to help.
Update 1
Don't know if this helps but when I first click on the list instance I see in the display:
com.sun.jdi.InvocationException occurred invoking method.
Then database query runs and when I click again I get the correct .toString() result.
Update 2
Here is the original exception I get (when I don't inspect the element in debug mode).
java.lang.NullPointerException
at org.hibernate.envers.query.impl.EntitiesAtRevisionQuery.list(EntitiesAtRevisionQuery.java:72)
at org.hibernate.envers.query.impl.AbstractAuditQuery.getSingleResult(AbstractAuditQuery.java:104)
at org.hibernate.envers.entities.mapper.relation.OneToOneNotOwningMapper.mapToEntityFromMap(OneToOneNotOwningMapper.java:74)
at org.hibernate.envers.entities.mapper.MultiPropertyMapper.mapToEntityFromMap(MultiPropertyMapper.java:118)
at org.hibernate.envers.entities.EntityInstantiator.createInstanceFromVersionsEntity(EntityInstantiator.java:93)
at org.hibernate.envers.entities.mapper.relation.component.MiddleRelatedComponentMapper.mapToObjectFromFullMap(MiddleRelatedComponentMapper.java:44)
at org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor.addToCollection(ListCollectionInitializor.java:67)
at org.hibernate.envers.entities.mapper.relation.lazy.initializor.ListCollectionInitializor.addToCollection(ListCollectionInitializor.java:39)
at org.hibernate.envers.entities.mapper.relation.lazy.initializor.AbstractCollectionInitializor.initialize(AbstractCollectionInitializor.java:67)
at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.checkInit(CollectionProxy.java:50)
at org.hibernate.envers.entities.mapper.relation.lazy.proxy.CollectionProxy.size(CollectionProxy.java:55)
at <MY CODE HERE, which checks list.size()>
Final Solution (Actually more of a temporary hack)
boolean worked = false;
while (!worked) {
try {
if(list.size() == 1) {
// do stuff
}
worked = true;
} catch (Exception e) {
// TODO: exception must be accessed or the loop will be infinite
e.getStackTrace();
}
}
Well what happends there is you're seing Hibernate's lazy loading in deep action :)
Basically hibernate loads proxy classes for you lazily associated relations, such that instead of a List of classes C you get a List (actually a PersistenceBag implementation) of Hibernate autogenerated proxie for your C class. THis is hibernate's way of deferring load of that association's values until they are actually accessed. So that's why when you access it in the eclipse debugger (which basically accesses an instance's fields/methids via introspection) you see the sql hibernate triggers to fetch the needed data.
The trick here is that depending on WHEN you access a lazy collection you might get different results. If you access it using the eclipse debugger you're more likely still in the Hibernate session that started loading that thing, so everything works as expected, an sql is (lazily) triggered when the thing is accessed and the data is loaded). Problem is that if you wanna access that same data in your code, but at a point where the session is already closed, you'll either get a LazyInitializationException or null (the latter if you're using some library for cleaning put hibenrate proxises such as Gilead)

Categories

Resources