Search in sources :

Example 11 with Node

use of org.structr.api.graph.Node in project structr by structr.

the class SyncCommand method importDatabase.

private static void importDatabase(final DatabaseService graphDb, final SecurityContext securityContext, final ZipInputStream zis, boolean doValidation, final Long batchSize) throws FrameworkException, IOException {
    final App app = StructrApp.getInstance();
    final DataInputStream dis = new DataInputStream(new BufferedInputStream(zis));
    final long internalBatchSize = batchSize != null ? batchSize : 200;
    final String uuidPropertyName = GraphObject.id.dbName();
    final Map<String, Node> uuidMap = new LinkedHashMap<>();
    final Set<Long> deletedNodes = new HashSet<>();
    double t0 = System.nanoTime();
    PropertyContainer currentObject = null;
    String currentKey = null;
    boolean finished = false;
    long totalNodeCount = 0;
    long totalRelCount = 0;
    do {
        try (final Tx tx = app.tx(doValidation)) {
            final List<Relationship> rels = new LinkedList<>();
            final List<Node> nodes = new LinkedList<>();
            long nodeCount = 0;
            long relCount = 0;
            do {
                try {
                    // store current position
                    dis.mark(4);
                    // read one byte
                    byte objectType = dis.readByte();
                    // skip newlines
                    if (objectType == '\n') {
                        continue;
                    }
                    if (objectType == 'N') {
                        // break loop after 200 objects, commit and restart afterwards
                        if (nodeCount + relCount >= internalBatchSize) {
                            dis.reset();
                            break;
                        }
                        currentObject = graphDb.createNode(Collections.EMPTY_SET, Collections.EMPTY_MAP);
                        nodeCount++;
                        // store for later use
                        nodes.add((Node) currentObject);
                    } else if (objectType == 'R') {
                        // break look after 200 objects, commit and restart afterwards
                        if (nodeCount + relCount >= internalBatchSize) {
                            dis.reset();
                            break;
                        }
                        String startId = (String) deserialize(dis);
                        String endId = (String) deserialize(dis);
                        String relTypeName = (String) deserialize(dis);
                        Node endNode = uuidMap.get(endId);
                        Node startNode = uuidMap.get(startId);
                        if (startNode != null && endNode != null) {
                            if (deletedNodes.contains(startNode.getId()) || deletedNodes.contains(endNode.getId())) {
                                System.out.println("NOT creating relationship between deleted nodes..");
                                currentObject = null;
                                currentKey = null;
                            } else {
                                RelationshipType relType = RelationshipType.forName(relTypeName);
                                currentObject = startNode.createRelationshipTo(endNode, relType);
                                // store for later use
                                rels.add((Relationship) currentObject);
                                relCount++;
                            }
                        } else {
                            System.out.println("NOT creating relationship of type " + relTypeName + ", start: " + startId + ", end: " + endId);
                            currentObject = null;
                            currentKey = null;
                        }
                    } else {
                        // reset if not at the beginning of a line
                        dis.reset();
                        if (currentKey == null) {
                            try {
                                currentKey = (String) deserialize(dis);
                            } catch (Throwable t) {
                                logger.warn("", t);
                            }
                        } else {
                            final Object obj = deserialize(dis);
                            if (obj != null && currentObject != null) {
                                if (uuidPropertyName.equals(currentKey) && currentObject instanceof Node) {
                                    final String uuid = (String) obj;
                                    uuidMap.put(uuid, (Node) currentObject);
                                }
                                if (currentKey.length() != 0) {
                                    // store object in DB
                                    currentObject.setProperty(currentKey, obj);
                                    // set type label
                                    if (currentObject instanceof Node && NodeInterface.type.dbName().equals(currentKey)) {
                                        ((Node) currentObject).addLabel(graphDb.forName(Label.class, (String) obj));
                                    }
                                } else {
                                    logger.error("Invalid property key for value {}, ignoring", obj);
                                }
                            } else {
                                logger.warn("No current object to store property in.");
                            }
                            currentKey = null;
                        }
                    }
                } catch (EOFException eofex) {
                    finished = true;
                }
            } while (!finished);
            totalNodeCount += nodeCount;
            totalRelCount += relCount;
            logger.info("Imported {} nodes and {} rels, committing transaction..", new Object[] { totalNodeCount, totalRelCount });
            tx.success();
        }
    } while (!finished);
    // build schema
    try (final Tx tx = app.tx()) {
        SchemaHelper.reloadSchema(new ErrorBuffer(), securityContext.getSessionId());
        tx.success();
    } catch (FrameworkException fex) {
        logger.warn("", fex);
    }
    final Map<String, Object> params = new HashMap<>();
    params.put("removeUnused", false);
    // set correct labels after schema has been compiled
    app.command(BulkCreateLabelsCommand.class).execute(params);
    double t1 = System.nanoTime();
    double time = ((t1 - t0) / 1000000000.0);
    DecimalFormat decimalFormat = new DecimalFormat("0.000000000", DecimalFormatSymbols.getInstance(Locale.ENGLISH));
    logger.info("Import done in {} s", decimalFormat.format(time));
}
Also used : App(org.structr.core.app.App) StructrApp(org.structr.core.app.StructrApp) PropertyContainer(org.structr.api.graph.PropertyContainer) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Node(org.structr.api.graph.Node) AbstractNode(org.structr.core.entity.AbstractNode) AbstractSchemaNode(org.structr.core.entity.AbstractSchemaNode) DecimalFormat(java.text.DecimalFormat) RelationshipType(org.structr.api.graph.RelationshipType) LinkedHashMap(java.util.LinkedHashMap) BufferedInputStream(java.io.BufferedInputStream) EOFException(java.io.EOFException) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet) FrameworkException(org.structr.common.error.FrameworkException) DataInputStream(java.io.DataInputStream) LinkedList(java.util.LinkedList) ErrorBuffer(org.structr.common.error.ErrorBuffer) AbstractRelationship(org.structr.core.entity.AbstractRelationship) Relationship(org.structr.api.graph.Relationship) GraphObject(org.structr.core.GraphObject)

Example 12 with Node

use of org.structr.api.graph.Node in project structr by structr.

the class SyncCommand method groupByTypeAndName.

private static Map<String, List<Node>> groupByTypeAndName(final Iterable<Node> nodes) {
    final Map<String, List<Node>> groupedNodes = new LinkedHashMap<>();
    for (final Node node : nodes) {
        if (node.hasProperty("name") && node.hasProperty("type")) {
            final String typeAndName = node.getProperty("type") + "." + node.getProperty("name");
            List<Node> nodeList = groupedNodes.get(typeAndName);
            if (nodeList == null) {
                nodeList = new LinkedList<>();
                groupedNodes.put(typeAndName, nodeList);
            }
            nodeList.add(node);
        }
    }
    return groupedNodes;
}
Also used : Node(org.structr.api.graph.Node) AbstractNode(org.structr.core.entity.AbstractNode) AbstractSchemaNode(org.structr.core.entity.AbstractSchemaNode) List(java.util.List) LinkedList(java.util.LinkedList) LinkedHashMap(java.util.LinkedHashMap)

Example 13 with Node

use of org.structr.api.graph.Node in project structr by structr.

the class BulkFixNodePropertiesCommand method execute.

@Override
public void execute(Map<String, Object> attributes) throws FrameworkException {
    final String propertyName = (String) attributes.get("name");
    final String entityTypeName = (String) attributes.get("type");
    if (entityTypeName != null) {
        final Class type = SchemaHelper.getEntityClassForRawType(entityTypeName);
        if (type != null) {
            final DatabaseService db = StructrApp.getInstance(securityContext).getDatabaseService();
            final NodeFactory factory = new NodeFactory(securityContext);
            final Iterator<AbstractNode> nodeIterator = Iterables.map(factory, db.getNodesByLabel(entityTypeName)).iterator();
            logger.info("Trying to fix properties of all {} nodes", type.getSimpleName());
            long nodeCount = bulkGraphOperation(securityContext, nodeIterator, 100, "FixNodeProperties", new BulkGraphOperation<AbstractNode>() {

                private void fixProperty(AbstractNode node, Property propertyToFix) {
                    Node databaseNode = node.getNode();
                    if (databaseNode.hasProperty(propertyToFix.dbName())) {
                        // check value with property converter
                        PropertyConverter converter = propertyToFix.databaseConverter(securityContext, node);
                        if (converter != null) {
                            try {
                                Object value = databaseNode.getProperty(propertyToFix.dbName());
                                converter.revert(value);
                            } catch (ClassCastException cce) {
                                // exception, needs fix
                                String databaseName = propertyToFix.dbName();
                                Object databaseValue = databaseNode.getProperty(databaseName);
                                Object correctedValue = propertyToFix.fixDatabaseProperty(databaseValue);
                                if (databaseValue != null && correctedValue != null) {
                                    try {
                                        // try to set database value to corrected value
                                        databaseNode.setProperty(databaseName, correctedValue);
                                    } catch (Throwable t) {
                                        logger.warn("Unable to fix property {} of {} with UUID {} which is of type {}", new Object[] { propertyToFix.dbName(), type.getSimpleName(), node.getUuid(), databaseValue != null ? databaseValue.getClass() : "null" });
                                    }
                                }
                            } catch (Throwable t) {
                                // log exceptions of other types
                                logger.warn("", t);
                            }
                        }
                    }
                }

                @Override
                public void handleGraphObject(SecurityContext securityContext, AbstractNode node) {
                    if (propertyName != null) {
                        PropertyKey key = StructrApp.getConfiguration().getPropertyKeyForDatabaseName(type, propertyName);
                        if (key != null) {
                            // needs type cast to Property to use fixDatabaseProperty method
                            if (key instanceof Property) {
                                fixProperty(node, (Property) key);
                            }
                        }
                    } else {
                        for (PropertyKey key : node.getPropertyKeys(PropertyView.All)) {
                            // needs type cast to Property to use fixDatabaseProperty method
                            if (key instanceof Property) {
                                fixProperty(node, (Property) key);
                            }
                        }
                    }
                }
            });
            logger.info("Fixed {} nodes", nodeCount);
            return;
        }
    }
    logger.info("Unable to determine property and/or entity type to fix.");
}
Also used : AbstractNode(org.structr.core.entity.AbstractNode) Node(org.structr.api.graph.Node) AbstractNode(org.structr.core.entity.AbstractNode) DatabaseService(org.structr.api.DatabaseService) PropertyConverter(org.structr.core.converter.PropertyConverter) SecurityContext(org.structr.common.SecurityContext) Property(org.structr.core.property.Property) PropertyKey(org.structr.core.property.PropertyKey)

Example 14 with Node

use of org.structr.api.graph.Node in project structr by structr.

the class CreateNodeCommand method createNode.

// ----- private methods -----
private Node createNode(final DatabaseService graphDb, final Principal user, final Set<String> labels, final Map<String, Object> properties) throws FrameworkException {
    final Map<String, Object> parameters = new HashMap<>();
    final Map<String, Object> ownsProperties = new HashMap<>();
    final Map<String, Object> securityProperties = new HashMap<>();
    final StringBuilder buf = new StringBuilder();
    final String newUuid = (String) properties.get("id");
    final String tenantId = graphDb.getTenantIdentifier();
    if (user != null && user.shouldSkipSecurityRelationships() == false) {
        buf.append("MATCH (u:Principal) WHERE id(u) = {userId}");
        buf.append(" CREATE (u)-[o:OWNS {ownsProperties}]->(n");
        if (tenantId != null) {
            buf.append(":");
            buf.append(tenantId);
        }
        for (final String label : labels) {
            buf.append(":");
            buf.append(label);
        }
        buf.append(" {nodeProperties})<-[s:SECURITY {securityProperties}]-(u)");
        buf.append(" RETURN n");
        // configure OWNS relationship
        ownsProperties.put(GraphObject.id.dbName(), getNextUuid());
        ownsProperties.put(GraphObject.type.dbName(), PrincipalOwnsNode.class.getSimpleName());
        ownsProperties.put(AbstractRelationship.sourceId.dbName(), user.getUuid());
        ownsProperties.put(AbstractRelationship.targetId.dbName(), newUuid);
        // configure SECURITY relationship
        securityProperties.put(Security.allowed.dbName(), new String[] { Permission.read.name(), Permission.write.name(), Permission.delete.name(), Permission.accessControl.name() });
        securityProperties.put(GraphObject.id.dbName(), getNextUuid());
        securityProperties.put(GraphObject.type.dbName(), Security.class.getSimpleName());
        securityProperties.put(AbstractRelationship.sourceId.dbName(), user.getUuid());
        securityProperties.put(AbstractRelationship.targetId.dbName(), newUuid);
        // store properties in statement
        parameters.put("userId", user.getId());
        parameters.put("ownsProperties", ownsProperties);
        parameters.put("securityProperties", securityProperties);
    } else {
        buf.append("CREATE (n");
        if (tenantId != null) {
            buf.append(":");
            buf.append(tenantId);
        }
        for (final String label : labels) {
            buf.append(":");
            buf.append(label);
        }
        buf.append(" {nodeProperties})");
        buf.append(" RETURN n");
    }
    // make properties available to Cypher statement
    parameters.put("nodeProperties", properties);
    final NativeResult result = graphDb.execute(buf.toString(), parameters);
    try {
        if (result.hasNext()) {
            final Map<String, Object> data = result.next();
            final Node newNode = (Node) data.get("n");
            return newNode;
        }
    } catch (DataFormatException dex) {
        throw new FrameworkException(422, dex.getMessage());
    } catch (ConstraintViolationException qex) {
        throw new FrameworkException(422, qex.getMessage());
    }
    throw new RuntimeException("Unable to create new node.");
}
Also used : FrameworkException(org.structr.common.error.FrameworkException) HashMap(java.util.HashMap) NativeResult(org.structr.api.NativeResult) Node(org.structr.api.graph.Node) AbstractNode(org.structr.core.entity.AbstractNode) PrincipalOwnsNode(org.structr.core.entity.relationship.PrincipalOwnsNode) Security(org.structr.core.entity.Security) PrincipalOwnsNode(org.structr.core.entity.relationship.PrincipalOwnsNode) DataFormatException(org.structr.api.DataFormatException) ConstraintViolationException(org.structr.api.ConstraintViolationException) GraphObject(org.structr.core.GraphObject)

Example 15 with Node

use of org.structr.api.graph.Node in project structr by structr.

the class CreateRelationshipCommand method createRelationship.

private synchronized <A extends NodeInterface, B extends NodeInterface, R extends Relation<A, B, ?, ?>> R createRelationship(final A fromNode, final B toNode, final Class<R> relType, final PropertyMap attributes) throws FrameworkException {
    // disable updating access time when creating relationships
    securityContext.disableModificationOfAccessTime();
    final RelationshipFactory<R> factory = new RelationshipFactory(securityContext);
    final PropertyMap properties = new PropertyMap(attributes);
    final CreationContainer tmp = new CreationContainer();
    final R template = instantiate(relType);
    final Node startNode = fromNode.getNode();
    final Node endNode = toNode.getNode();
    final Date now = new Date();
    final Principal user = securityContext.getCachedUser();
    template.ensureCardinality(securityContext, fromNode, toNode);
    // date properties need converter
    AbstractRelationship.createdDate.setProperty(securityContext, tmp, now);
    AbstractRelationship.lastModifiedDate.setProperty(securityContext, tmp, now);
    // set initial properties manually (caution, this can only be used for primitive properties!)
    tmp.getData().put(GraphObject.id.jsonName(), getNextUuid());
    tmp.getData().put(GraphObject.type.jsonName(), relType.getSimpleName());
    tmp.getData().put(AbstractRelationship.relType.jsonName(), template.name());
    tmp.getData().put(AbstractRelationship.sourceId.jsonName(), fromNode.getUuid());
    tmp.getData().put(AbstractRelationship.targetId.jsonName(), toNode.getUuid());
    tmp.getData().put(AbstractRelationship.visibleToPublicUsers.jsonName(), false);
    tmp.getData().put(AbstractRelationship.visibleToAuthenticatedUsers.jsonName(), false);
    tmp.getData().put(AbstractRelationship.cascadeDelete.jsonName(), template.getCascadingDeleteFlag());
    if (user != null) {
        tmp.getData().put(AbstractRelationship.createdBy.jsonName(), user.getUuid());
    }
    // create relationship including initial properties
    final Relationship rel = startNode.createRelationshipTo(endNode, template, tmp.getData());
    final R newRel = factory.instantiateWithType(rel, relType, null, true);
    if (newRel != null) {
        newRel.setProperties(securityContext, properties);
        // notify transaction handler
        TransactionCommand.relationshipCreated(user, newRel);
        // notify relationship of its creation
        newRel.onRelationshipCreation();
        // iterate post creation transformations
        for (Transformation<GraphObject> transformation : StructrApp.getConfiguration().getEntityCreationTransformations(newRel.getClass())) {
            transformation.apply(securityContext, newRel);
        }
    }
    // enable access time update again for subsequent calls
    securityContext.enableModificationOfAccessTime();
    return newRel;
}
Also used : PropertyMap(org.structr.core.property.PropertyMap) Node(org.structr.api.graph.Node) AbstractRelationship(org.structr.core.entity.AbstractRelationship) Relationship(org.structr.api.graph.Relationship) GraphObject(org.structr.core.GraphObject) Date(java.util.Date) Principal(org.structr.core.entity.Principal)

Aggregations

Node (org.structr.api.graph.Node)24 Relationship (org.structr.api.graph.Relationship)13 AbstractNode (org.structr.core.entity.AbstractNode)11 LinkedList (java.util.LinkedList)8 GraphObject (org.structr.core.GraphObject)8 DatabaseService (org.structr.api.DatabaseService)7 LinkedHashSet (java.util.LinkedHashSet)5 AbstractRelationship (org.structr.core.entity.AbstractRelationship)5 LinkedHashMap (java.util.LinkedHashMap)4 List (java.util.List)4 FrameworkException (org.structr.common.error.FrameworkException)4 AbstractSchemaNode (org.structr.core.entity.AbstractSchemaNode)4 PropertyKey (org.structr.core.property.PropertyKey)4 Test (org.junit.Test)3 Transaction (org.structr.api.Transaction)3 App (org.structr.core.app.App)3 StructrApp (org.structr.core.app.StructrApp)3 IOException (java.io.IOException)2 Date (java.util.Date)2 HashMap (java.util.HashMap)2