bayofmany / peapod Goto Github PK
View Code? Open in Web Editor NEWA new object-graph-wrapper for the Tinkerpop 3 graph stack.
License: Apache License 2.0
A new object-graph-wrapper for the Tinkerpop 3 graph stack.
License: Apache License 2.0
Hey, I was reading your readme and just wanted to offer some insight on Ferma and also offer to collaborate in anyway you guys would like.
The one thing I think you guys are bringing that is unique, and potentially powerful, is the DSL idea. Unfortunately my own projects have a very specific need for the type of typing provided in Ferma so I wouldnt be able to abandon Ferma to work on peapod instead, but if you'd be interested in combining our projects in some way let me know. It would be cool to see a DSL in action along side Ferma's other features. Either way, good luck on the project!
I get this error everytime I try to run the example
https://github.com/bayofmany/peapod/blob/master/demo/src/test/java/peapod/demo/classic/ShowcaseClassicTest.java
I tried to take all these classes in a totally new project. And I get the same error. I don't know if this is a library error or a mistake I'm making.
Error:
java.lang.RuntimeException: No framer found for TinkerVertex with label vertex
at peapod.internal.runtime.FramerRegistry.get(FramerRegistry.java:81)
at peapod.FramedGraph.frame(FramedGraph.java:138)
at peapod.FramedGraph.v(FramedGraph.java:129)
at com.mohataher.peapod.test.ShowcaseClassicTest.init(ShowcaseClassicTest.java:34)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
pom.xml (FYI)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mohataher</groupId>
<artifactId>peapod-test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>gremlin-core</artifactId>
<version>3.0.0.M9-incubating</version>
</dependency>
<dependency>
<groupId>org.apache.tinkerpop</groupId>
<artifactId>tinkergraph-gremlin</artifactId>
<version>3.0.0.M9-incubating</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.bayofmany.peapod</groupId>
<artifactId>peapod</artifactId>
<version>0.2.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<version>2.0.0.0</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
I tried to use peapod in combination with the TP3 layer which michael pollmeier wrote:
<dependency>
<groupId>com.michaelpollmeier</groupId>
<artifactId>orientdb-gremlin</artifactId>
<version>3.1.1-incubating.1</version>
</dependency>
I added the following test case:
public class OrientDBSuite extends GraphTestSuite {
public static final String URL = "memory:" + OrientDBSuite.class.getSimpleName();
@ClassRule
public static TemporaryFolder folder = new TemporaryFolder();
@BeforeClass
public static void setGraphProvider() throws IOException {
GraphTest.graphProvider = new GraphProvider() {
public Graph getGraph() throws IOException {
return new OrientGraphFactory(URL + folder.newFolder().getAbsolutePath(), "root", "root").getNoTx();
}
};
}
}
So far 4 tests are failing. OrientDB only supports Strings or OrientID objects for Ids. In some cases Peapod is using Class objects.
Hey there, one thing i do not understand about peapod is why you chose to annotate methods with @in,@out or @Property instead of fields. Also why do my annotated classes need to be abstract? I find this pretty confusing as i am coming from dependency injection frameworks, where youd inject foreing DomainModel objects as fields and the framework generates the add/remove/get functions for you, regardless of their positioning and regardless of abstract or not. But there probably is a reason to this, so maybe youd like to share.
I am getting this runtime exception "No framer found for TinkerVertex with label vertex" while running my demo app.
I have already checked your solution to similar issue. I followed your comment providing steps to setup automatic annotation processing, but no luck.
Here is my console out
java.lang.RuntimeException: No framer found for TinkerVertex with label vertex
at peapod.internal.runtime.FramerRegistry.get(FramerRegistry.java:97)
at peapod.FramedGraph.frame(FramedGraph.java:142)
at peapod.FramedGraph.v(FramedGraph.java:133)
at tinkerpopSample.App.main(App.java:20)
We ran into this with Frames a while ago -- I believe the object inheritance structure should be taken into account when querying for objects. So take the example:
ClassB extends ClassA
When you query for ClassA, you should get all objects ClassA & ClassB. There are two ways to handle this, I assume; the first is to modify Peapod to make the Label of class type contain both ClassA and ClassB. Alternatively, and I think this is the better solution: determine at run time the object structure of all @vertex objects, and store that in a cache. At query time, query for all types extended or implemented by the given type. I think this is a better solution because if you change the object structure and redeploy, the graph will stay consistent.
Assuming I have done something like this
Person p=framedGraph.V(Person.class).next();
And I need to do some traversal based on p.id()
. Using the interface style to create my model, the id()
method doesn't exist, is there anyone to get the base Vertex or get ID of the vertex in peapod?
When peapod generates the Impl classes for my project, the classes contain compilation errors. The root of the compilation problems exists in the class defined to represent an edge. When not framing edges, the classes come out ok.
The offending class is
import peapod.annotations.Edge;
import peapod.annotations.In;
import peapod.annotations.Out;
@Edge
public abstract class Uses {
public abstract String getRole();
public abstract void setRole(String role);
@Out
public abstract ConfigurationData getUses();
public abstract void setUses(ConfigurationData uses);
@In
public abstract ConfigurationData getUsedBy();
public abstract void setUsedBy(ConfigurationData usedBy);
}
for the sake of continuity, here is the ConfigurationData class
import java.util.List;
import peapod.annotations.Edge;
import peapod.annotations.In;
import peapod.annotations.Out;
import peapod.annotations.Vertex;
@Vertex
public abstract class ConfigurationData {
@Out @Edge("configures")
public abstract EntityData getEntity();
public abstract void setEntity(EntityData entity);
@Out
public abstract List<Uses> getUses();
public abstract Uses addUses();
public abstract Uses removeUses();
@In
public abstract List<Uses> getUsedBy();
}
The generated Uses$Impl class has the following errors:
FramedVertex cannot be resolved to a type
Direction cannot be resolved to a type
Further, the generated setUses() and setUsedBy() methods both reference an undefined field v
The POM file I am using is as follows
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>au.gov.defence.dst.cewd</groupId>
<artifactId>jats.peapod</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.bayofmany.peapod</groupId>
<artifactId>peapod</artifactId>
<version>0.2.2</version>
</dependency>
<dependency>
<groupId>com.thinkaurelius.titan</groupId>
<artifactId>titan-core</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.thinkaurelius.titan</groupId>
<artifactId>titan-cassandra</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</project>
And for completeness, the generated Uses$Impl class
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Element;
import peapod.FramedEdge;
import peapod.FramedElement;
import peapod.FramedGraph;
import peapod.internal.runtime.Framer;
import peapod.internal.runtime.IFramer;
@SuppressWarnings("unused")
public final class Uses$Impl extends Uses
implements FramedEdge {
private FramedGraph graph;
private Edge e;
public Uses$Impl(Edge e, FramedGraph graph) {
this.e = e;
this.graph = graph;
}
public FramedGraph graph() {
return graph;
}
public Element element() {
return e;
}
public String getRole() {
return e.<String>property("role").orElse(null);
}
public void setRole(String role) {
if (role == null) {
e.property("role").remove();
} else {
e.property("role", role);
}
}
public ConfigurationData getUses() {
// edge-getter-vertex
return graph().frame(e.outVertex(), ConfigurationData.class);
}
public void setUses(ConfigurationData uses) {
// vertex-setter-vertex
v.edges(Direction.OUT, "uses").forEachRemaining(e -> e.remove());
if (uses != null) {
v.addEdge("uses", ((FramedVertex)uses).vertex());
}
}
public ConfigurationData getUsedBy() {
// edge-getter-vertex
return graph().frame(e.inVertex(), ConfigurationData.class);
}
public void setUsedBy(ConfigurationData usedBy) {
// vertex-setter-vertex
v.edges(Direction.OUT, "usedBy").forEachRemaining(e -> e.remove());
if (usedBy != null) {
v.addEdge("usedBy", ((FramedVertex)usedBy).vertex());
}
}
public int hashCode() {
return e.hashCode();
}
public boolean equals(Object other) {
return (other instanceof FramedElement) && e.equals(((FramedElement) other).element());
}
public String toString() {
return e.label() + "[" + e.id() + "]";
}
@Framer
public static final class UsesFramer
implements IFramer<Edge, Uses> {
public Class<Edge> type() {
return Edge.class;
}
public Class<Uses> frameClass() {
return Uses.class;
}
public String label() {
return "uses";
}
public Uses frame(Edge e, FramedGraph graph) {
return new Uses$Impl(e, graph);
}
public Uses frameNew(Edge e, FramedGraph graph) {
return frame(e, graph);
}
}
}
For people who are not using maven, could you describe the dependencies of peapop in the readme file?
Even for people using maven, they can have an idea by looking at it.
Thanks.
Hi,
I'm attempting to use peapod to write a lightweight data-stream adapter + data framer for the graph.
My problem:
@Vertex
public interface Person {
public String getName();
public void setName(String name);
@Edge("worksAt")
public List<Location> geLocations();
public void addLocation(Location loc);
public void removeLocation(Location loc);
}
what i'd like to do:
Person p1 = readNextObject(stream);
framedGraph.addVertex(p1);
the above would also take care of my next (and more interesting problem): unique entities
@Vertex
public interface Location{
public String getName();//Would use a @UniqueID kind of annotation for this property
public void setName(String name);
}
that is already represented in the graph (a vertex labeld "location", name: "NYC").
in this case, framedGraph.addVertex(p1)
would note that p1 has the location "NYC", which is already in the graph. framedGraph would then make sure to create the "worksAt" edge between the new p1 node, and the existing location.
I have solved this issue by "wrapping" the framed class (interface, actually):
public class WLocation {
private String name;
public WLocation(String name){
this.name = name;
}
public Location writeToGraph(FramedGraph fg) throws SchemaViolationException{
//location is unique
Location loc = null;
List<Location> locs = fg.V(Location.class).has("name", name).toList();
if(locs.size() == 0){
loc = fg.addVertex(Location.class);
loc.setName(name);
}
else if(locs.size() == 1){
loc = locs.get(0);
}
else{
throw new SchemaViolationException("more than location with name " + name);
}
return loc;
}
}
and something very similar for Person (only relevant code in WPerson class):
public Person writeToGraph(FramedGraph fg) throws SchemaViolationException{
//person is unique(by email)
List<Person> pers = fg.V(Person.class).has("email", email).toList();
if(pers.size() == 0){
Person per = fg.addVertex(Person.class);
locations.forEach( (loc) -> per.addLocation(loc.writeToGraph(fg)) );
per.setEmail(email);
per.setName(name);
return per;
}
else if(pers.size() == 1){
return pers.get(0);
}
else{
throw new SchemaViolationException("multiple ppl with same email: " + email);
}
}
i can now call:
WPerson p1 = readNextObject(stream);
p1.writeToGraph(framedGraph);
now i have successfully enforced uniqueness for locations using my own wrappers.
The Downside:
for every framed class, i now have to write a wrapping class, and enforce schema in quite a complex, messy all-over-the-place way.
I'd like to know if i missed something (read most your tests) that does this, and if not, if you're planning on this for the next round, and if not, if you would mind i (attempted to) add this and create a pull request.
I was not able to use the peapod tag on stackoverflow, so im just linking it here.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.