Neo4j TimeTree en Spring Data Neo4j 4.0
spring-data-neo4j graphaware (2)
La definición de las posibles etiquetas para TimeTree tiene una sintaxis un poco diferente, tal como se explica en la documentación de InclusionPolicy https://github.com/graphaware/neo4j-framework/tree/master/common#inclusion-policies
La sintaxis es la siguiente:
com.graphaware.module.TT.event=hasLabel(''StructureVersionChange'')||hasLabel(''RuleVersionChange'')||hasLabel(''FilterVersionChange'')
Para fines de depuración, puede agregar estas líneas a su archivo conf / custom-logback.xml :
<appender name="EXTENSIONLOG" class="ch.qos.logback.core.FileAppender">
<file>data/log/extensions.log</file>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSSZ} %-5level [%logger{15}]: %message%n</pattern>
</encoder>
</appender>
<logger name="com.graphaware" level="debug">
<appender-ref ref="EXTENSIONLOG"/>
</logger>
y mira el archivo extensions.log
Estoy tratando de utilizar la biblioteca timetree en mi proyecto de datos de primavera neo4j 4.0.0.
Tal como se detalla en esta página, https://github.com/graphaware/neo4j-timetree , he editado mi archivo neo4j.properties para habilitar la vinculación automática de eventos, agregar la dependencia de timetree a mi gradle y establecer una propiedad ''creationDate'' en el nodo de evento con tipo de datos Long. Aunque todo parece como debería ser, todavía no crea ningún Timetree.
Aquí está mi archivo neo4j.property:
# Runtime must be enabled like this
com.graphaware.runtime.enabled=true
# A Runtime module that takes care of attaching the events like this (TT is the ID of the module)
com.graphaware.module.TT.1=com.graphaware.module.timetree.module.TimeTreeModuleBootstrapper
# Nodes which represent events and should be attached automatically have to be defined
com.graphaware.module.TT.event=hasLabel(''StructureVersionChange''),hasLabel(''RuleVersionChange''),hasLabel(''FilterVersionChange'')
# Optionally, a property on the event nodes that represents the the time (long) at which the event took place must be specified (defaults to "timestamp")
com.graphaware.module.TT.timestamp=creationDate
# Optionally, a resolution can be specified (defaults to DAY)
com.graphaware.module.TT.resolution=SECOND
# Optionally, a time zone can be specified (defaults to UTC)
com.graphaware.module.TT.timezone=CEST
# Optionally, a relationship type with which the events will be attached to the tree can be specified (defaults to AT_TIME)
com.graphaware.module.TT.relationship=CREATED_ON
# autoAttach must be set to true
com.graphaware.module.TT.autoAttach=true
En realidad, antes de esto, traté de usar la versión JAVA API de Timetree para mi proyecto, pero luego estaba realmente confundido por el tipo de parámetro del constructor timetree, que es Nodo. Mientras que en primavera mis Nodos tienen tipos de sus clases.
¡Gracias de antemano y su sugerencia sería muy apreciada!
EDITAR:
neo4j.properties
# Runtime must be enabled like this
com.graphaware.runtime.enabled=true
# A Runtime module that takes care of attaching the events like this (TT is the ID of the module)
com.graphaware.module.TT.1=com.graphaware.module.timetree.module.TimeTreeModuleBootstrapper
# Nodes which represent events and should be attached automatically have to be defined
com.graphaware.module.TT.event=hasLabel(''FilterVersionChange'') || hasLabel(''StructureVersionChange'') || hasLabel(''CodeUnitVersionChange'') || hasLabel(''RuleVersionChange'') || hasLabel(''EpisodeVersion'')
# Optionally, a property on the event nodes that represents the the time (long) at which the event took place must be specified (defaults to "timestamp")
com.graphaware.module.TT.timestamp=creationDate
# Optionally, a resolution can be specified (defaults to DAY)
com.graphaware.module.TT.resolution=SECOND
# Optionally, a time zone can be specified (defaults to UTC)
com.graphaware.module.TT.timezone=CEST
# Optionally, a relationship type with which the events will be attached to the tree can be specified (defaults to AT_TIME)
com.graphaware.module.TT.relationship=CREATED_ON
# autoAttach must be set to true
com.graphaware.module.TT.autoAttach=true
data / log / neo4j.0.0
May 17, 2015 4:07:42 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:07:42 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:07:43 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:11:39 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:11:39 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:11:39 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:28:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:28:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
May 17, 2015 4:28:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version ''Jersey: 1.18.1 02/19/2014 03:28 AM''
data / graph.db / messages
2015-05-17 14:28:46.537+0000 INFO [o.n.k.i.DiagnosticsManager]: --- INITIALIZED diagnostics START ---
2015-05-17 14:28:46.538+0000 INFO [o.n.k.i.DiagnosticsManager]: Neo4j Kernel properties:
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.resolution=DAY
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.timestamp=creationDate
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.relationship=CREATED_ON
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.event=hasLabel(''FilterVersionChange'') || hasLabel(''ArchitectureUnitVersionChange'') || hasLabel(''CodeUnitVersionChange'') || hasLabel(''RuleVersionChange'') || hasLabel(''EpisodeVersion'')
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: store_dir=C:/NEO4J-~1.1/data/graph.db
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.runtime.enabled=true
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.autoAttach=true
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: remote_shell_enabled=true
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.timezone=CEST
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.1=com.graphaware.module.timetree.module.TimeTreeModuleBootstrapper
2015-05-17 14:28:46.544+0000 INFO [o.n.k.i.DiagnosticsManager]: Diagnostics providers:
2015-05-17 14:28:46.544+0000 INFO [o.n.k.i.DiagnosticsManager]: org.neo4j.kernel.configuration.Config
...
...
2015-05-17 14:28:48.656+0000 INFO [o.n.k.i.DiagnosticsManager]: --- STARTED diagnostics for KernelDiagnostics:StoreFiles END ---
2015-05-17 14:28:48.696+0000 INFO [o.n.k.EmbeddedGraphDatabase]: Database is now ready
2015-05-17 14:28:48.696+0000 INFO [o.n.s.d.LifecycleManagingDatabase]: Successfully started database
2015-05-17 14:28:48.699+0000 INFO [o.n.k.i.DiagnosticsManager]: --- SERVER STARTED START ---
2015-05-17 14:28:48.736+0000 INFO [o.n.s.CommunityNeoServer]: Starting HTTP on port :7474 with 8 threads available
2015-05-17 14:28:48.872+0000 INFO [o.n.s.CommunityNeoServer]: Enabling HTTPS on port :7473
2015-05-17 14:28:48.989+0000 INFO [o.n.s.w.Jetty9WebServer]: Mounting static content at [/webadmin] from [webadmin-html]
2015-05-17 14:28:49.023+0000 INFO [o.n.s.w.Jetty9WebServer]: Mounting static content at [/browser] from [browser]
2015-05-17 14:28:49.956+0000 INFO [o.n.s.CommunityNeoServer]: Server started on: http://localhost:7474/
2015-05-17 14:28:49.956+0000 INFO [o.n.s.CommunityNeoServer]: Remote interface ready and available at [http://localhost:7474/]
2015-05-17 14:28:49.956+0000 INFO [o.n.k.i.DiagnosticsManager]: --- SERVER STARTED END ---
Entidad de clase
@NodeEntity
public class FilterVersionChange extends UnitVersion {
@GraphId
private Long id;
public FilterVersionChange() {
super();
}
public FilterVersionChange(String description, Date creationDate)
{
super(description, creationDate);
}
@Relationship(type="CONTAINS", direction = Relationship.OUTGOING)
private Set<FilterState> filterStates;
@Relationship(type="PREVIOUS", direction = Relationship.OUTGOING)
private FilterVersionChange previousFilterVersionChange;
@Relationship(type="REFERENCES", direction = Relationship.OUTGOING)
private FilterVersionChange referencedFilterVersionChange;
@Relationship(type="ADDED", direction = Relationship.OUTGOING)
private Set<FilterState> newFilterStates;
@Relationship(type="DELETED", direction = Relationship.OUTGOING)
private Set<FilterState> deletedFilterStates;
@Relationship(type="MODIFIED", direction = Relationship.OUTGOING)
private Set<ModifiedUnitState> modifiedFilterStates;
public void contains(Set<FilterState> filterStates) {
this.filterStates = filterStates;
}
public void previous(FilterVersionChange previousFilterVersionChange) {
this.previousFilterVersionChange = previousFilterVersionChange;
}
public void references(FilterVersionChange referencedFilterVersionChange) {
this.referencedFilterVersionChange = referencedFilterVersionChange;
}
public void added(Set<FilterState> newFilterStates) {
this.newFilterStates = newFilterStates;
}
public void deleted(Set<FilterState> deletedFilterStates) {
this.deletedFilterStates = deletedFilterStates;
}
public void modified(Set<ModifiedUnitState> modifiedFilterStates) {
this.modifiedFilterStates = modifiedFilterStates;
}
}
Repositorio
@Repository
public interface FilterVersionRepository extends GraphRepository<FilterVersion> {
@Query("MATCH (project:Project {name:{0}})-[:HAS_FILTER_VERSION]->(filterVersion:FilterVersion {name:{1}}) RETURN filterVersion")
FilterVersion findFilterVersionByName(String projectName, String filterVersionName);
}
Función de llamada
public FilterVersionChange createNewFilterVersionChange(String projectName,
String filterVersionName,
String filterVersionChangeDescription,
Set<FilterState> filterStates)
{
FilterVersion filterVersion = filterVersionRepository.findFilterVersionByName(projectName, filterVersionName);
if(filterVersion != null)
{
for(FilterState filterState : filterStates)
{
Filter filter = new Filter(filterState.getMatchingString(), filterState.getMatchingType());
filterState.stateOf(filter);
}
Set<FilterVersionChange> filterVersionChanges = new HashSet<FilterVersionChange>();
FilterVersionChange filterVersionChange = new FilterVersionChange(filterVersionChangeDescription, new Date());
filterVersionChange.contains(filterStates);
filterVersionChange.added(filterStates);
filterVersionChanges.add(filterVersionChange);
filterVersion.tracks(filterVersionChanges);
filterVersionRepository.save(filterVersion);
return filterVersionChange;
}
else
{
return null;
}
}
FilterVersion.class
@NodeEntity
public class FilterVersion {
@GraphId
private Long id;
private String name;
private String description;
private Date creationDate;
public FilterVersion() {
}
public FilterVersion(String name, String description, Date creationDate) {
this.name = name;
this.description = description;
this.creationDate = creationDate;
}
@Relationship(type = "TRACKS", direction = Relationship.OUTGOING)
private Set<FilterVersionChange> filterVersionChanges;
@Relationship(type = "HAS_FILTER_VERSION", direction = Relationship.INCOMING)
private Project project;
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public void tracks(Set<FilterVersionChange> filterVersionChanges) {
this.filterVersionChanges = filterVersionChanges;
}
public void belongsTo(Project project) {
this.project = project;
}
public Project getProject() {
return project;
}
}
UnitVersion.class
@NodeEntity
public class UnitVersion {
@GraphId
protected Long id;
private String description;
private Long creationDate;
public UnitVersion() {
}
public UnitVersion(String description, Date creationDate) {
this.description = description;
this.creationDate = creationDate.getTime();
}
@Relationship(type = "MAPPED_ON", direction = Relationship.OUTGOING)
private UnitVersion unitVersion;
public void setDescription(String description) {
this.description = description;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate.getTime();
}
public void mappedOn(UnitVersion unitVersion) {
this.unitVersion = unitVersion;
}
}
La dependencia solo es útil si está utilizando el programa timetree programáticamente. Si su aplicación se ejecuta en un servidor Neo4j, debe descargarla y guardarla en su directorio de complementos del servidor Neo4j:
a) El marco GraphAware (elija Comunidad o Empresa)
b) El módulo TimeTree
Ambos se pueden descargar de http://graphaware.com/products/
Sin esto, incluso con una configuración en neo4j.properties, GraphAware Runtime no se inicia y el timetree no funcionará.
Si desea ejecutar su código mediante una prueba, debe incluir las dependencias para TimeTree y GraphAware Runtime e iniciar GraphAware Runtime usted mismo, con un código como:
GraphAwareRuntime runtime = GraphAwareRuntimeFactory.createRuntime(getDatabase());
runtime.registerModule(new TimeTreeModule("timetree",
TimeTreeConfiguration
.defaultConfiguration()
.with(new NodeInclusionPolicy() {
@Override
public boolean include(Node node) {
return node.hasLabel(DynamicLabel.label("User"));
}
})
})
.withRelationshipType(DynamicRelationshipType.withName("CREATED_ON"))
.withTimeZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("GMT+1")))
.withTimestampProperty("createdOn")
.withResolution(Resolution.DAY)
,
getDatabase()));
runtime.start();
Entonces puedes escribir pruebas como
@Test
public void shouldSaveUser()
{
User user = new User( "Michal" );
user.setCreatedOn(1431937636995l);
userRepository.save( user );
assertSameGraph( getDatabase(), "CREATE (u:User:Person {name:''Michal'', createdOn:1431937636995})," +
"(root:TimeTreeRoot)," +
"(root)-[:FIRST]->(year:Year {value:2015})," +
"(root)-[:CHILD]->(year)," +
"(root)-[:LAST]->(year)," +
"(year)-[:FIRST]->(month:Month {value:5})," +
"(year)-[:CHILD]->(month)," +
"(year)-[:LAST]->(month)," +
"(month)-[:FIRST]->(day:Day {value:18})," +
"(month)-[:CHILD]->(day)," +
"(month)-[:LAST]->(day)," +
"(day)<-[:CREATED_ON]-(u)"
);
}