if (tx.hasRelationship(e, outgoing, defines.name())) { verticesToDeleteThatDefineSomething.add(e); } else { tx.getRelationships(e, outgoing, hasData.name()).forEach(rel -> { dataToBeDeleted.add(tx.getRelationshipTarget(rel)); }); tx.getTransitiveClosureOver(entity, outgoing, contains.name()) .forEachRemaining(categorizer::accept); if (tx.hasRelationship(e, outgoing, defines.name())) {
break; case metric: it = v.vertices(Direction.IN, Relationships.WellKnown.defines.name()); Vertex mdv = closeAfter(it, it::next); MetricType md = convert(mdv, MetricType.class); break; case resource: it = v.vertices(Direction.IN, Relationships.WellKnown.defines.name()); Vertex rtv = closeAfter(it, it::next); ResourceType rt = convert(rtv, ResourceType.class);
containsRel = tx.relate(parent, entityObject, contains.name(), Collections.emptyMap()); Relationship rel = tx.convert(containsRel, Relationship.class); tx.getPreCommit().addNotifications(
}; Iterator<Vertex> it = context.getGraph().traversal().V(root).out(contains.name()).order().by(orderFn); while (it.hasNext()) { Vertex v = it.next();
}; Iterator<Vertex> it = context.getGraph().traversal().V(root).out(contains.name()).order().by(orderFn);
BE r = tx.relate(resourceTypeObject, entity, defines.name(), null); tx.extractId(entity)).get(), null, null, null, resourceType, blueprint.getProperties()); Relationship definesRel = new Relationship(tx.extractId(r), defines.name(), resourceTypePath, entityPath); String relationshipName = isParentOf.name(); RelationshipRules.checkCreate(tx, parent, outgoing, relationshipName, entity); r = tx.relate(parent, entity, relationshipName, null); Relationship parentRel = new Relationship(tx.extractId(r), isParentOf.name(), parentPath, entityPath);
BE r = tx.relate(metricTypeObject, entity, defines.name(), null); blueprint.getProperties()); Relationship rel = new Relationship(tx.extractId(r), defines.name(), parentPath, entityPath); r = tx.relate(parent, entity, incorporates.name(), null); rel = new Relationship(tx.extractId(r), incorporates.name(), parentPath, entityPath); notifs.add(new Notification<>(rel, rel, created()));
@SuppressWarnings("unchecked") public void visit(GraphTraversal<?, ?> query, With.DataAt dataPos, QueryTranslationState state) { goBackFromEdges(query, state); query.out(hasData.name()); for (Path.Segment seg : dataPos.getDataPath().getPath()) { if (SegmentType.up.equals(seg.getElementType())) { query.in(contains.name()); } else { query.out(contains.name()); } query.has(__type.name(), Constants.Type.structuredData.name()); // map members have both index and key (so that the order of the elements is preserved) // list members have only the index Integer index = toInteger(seg.getElementId()); if (index == null) { query.has(Constants.Property.__structuredDataKey.name(), seg.getElementId()); } else { //well, the map could have a numeric key, so we cannot say it has to be a list index here. GraphTraversal<?, ?>[] indexOrKey = new GraphTraversal<?, ?>[2]; indexOrKey[0] = __.has(Constants.Property.__structuredDataIndex.name(), index) .hasNot(Constants.Property.__structuredDataKey.name()); indexOrKey[1] = __.has(Constants.Property.__structuredDataKey.name(), seg.getElementId()); query.or((Traversal[]) indexOrKey); } } }
@Override protected EntityAndPendingNotifications<BE, MetadataPack> wireUpNewEntity(BE entity, MetadataPack.Blueprint blueprint, CanonicalPath parentPath, BE parent, Transaction<BE> tx) { Set<Notification<?, ?>> newRels = new HashSet<>(); blueprint.getMembers().forEach((p) -> { try { BE member = tx.find(p); BE rel = tx.relate(entity, member, incorporates.name(), null); Relationship r = tx.convert(rel, Relationship.class); newRels.add(new Notification<>(r, r, created())); } catch (ElementNotFoundException e) { throw new EntityNotFoundException(p.getSegment().getElementType().getSimpleName(), Query.filters(Query.to(p))); } }); MetadataPack entityObject = tx.convert(entity, MetadataPack.class); return new EntityAndPendingNotifications<>(entity, entityObject, newRels); }
/** * Certain constructs in backend are not representable in API - such as the * {@link org.hawkular.inventory.api.Relationships.WellKnown#hasData} relationship. * * @param tx the context using which to access backend * @param entity the entity to decide on * @param <BE> the type of the backend entity * @return true if the entity can be represented in API results, false otherwise */ public static <BE> boolean isRepresentableInAPI(Transaction<BE> tx, BE entity) { if (tx.isBackendInternal(entity)) { return false; } if (Relationship.class.equals(tx.extractType(entity))) { if (Relationships.WellKnown.hasData.name().equals(tx.extractRelationshipName(entity))) { return false; } } return true; }
private Map.Entry<InventoryStructure<B>, SyncHash.Tree> treeHashAndStructure(Transaction<BE> tx) { BE root = tx.querySingle(context.select().get()); E entity = tx.convert(root, context.entityClass); SyncHash.Tree.Builder bld = SyncHash.Tree.builder(); InventoryStructure.Builder<B> structBld = InventoryStructure.of(Inventory.asBlueprint(entity)); bld.withPath(RelativePath.empty().get()).withHash(entity.getSyncHash()); //the closure is returned in a breadth-first manner Iterator<BE> closure = tx.getTransitiveClosureOver(root, outgoing, contains.name()); if (closure.hasNext()) { Function<BE, Entity<? extends Entity.Blueprint, ?>> convert = e -> (Entity<Entity.Blueprint, ?>) tx.convert(e, tx.extractType(e)); Stream<BE> st = StreamSupport.stream(Spliterators.spliteratorUnknownSize(closure, 0), false); Iterator<Entity<? extends Entity.Blueprint, ?>> entities = st.map(convert).iterator(); buildChildTree(tx, entity.getPath(), singletonList(bld), singletonList(structBld), new ArrayList<>(), new ArrayList<>(), entities.next(), entities); } return new SimpleImmutableEntry<>(structBld.build(), bld.build()); }
private Incorporated(CanonicalPath entity) { super(entity, Relationships.WellKnown.incorporates.name(), EntityRole.TARGET); }
private static <E> void disallowCreateOfIfFeedAlreadyIncorporatedInAnotherEnvironment(Transaction<E> backend, E origin, Relationships.Direction direction, String relationship, E target) { if (!incorporates.name().equals(relationship)) { return; } Class<?> originType = backend.extractType(origin); Class<?> targetType = backend.extractType(target); if (Environment.class.equals(originType) && Feed.class.equals(targetType) && backend.hasRelationship(target, incoming, relationship)) { throw new IllegalArgumentException("Relationship '" + relationship + "' between " + originType.getSimpleName() + " and " + targetType.getSimpleName() + " is 1:N." + " The target entity - " + backend.extractCanonicalPath(target) + " - is already a target of" + " another relationship of this name. Creating another would be illegal."); } }
public static <E> void checkCreate(Transaction<E> backend, E origin, Relationships.Direction direction, Relationships.WellKnown relationship, E target) { check(backend, origin, direction, relationship.name(), target, CheckType.CREATE); }
private Defined(CanonicalPath entity) { super(entity, Relationships.WellKnown.defines.name(), EntityRole.TARGET); }
private Contained(CanonicalPath entity) { super(entity, Relationships.WellKnown.contains.name(), EntityRole.TARGET); }
@Override protected EntityAndPendingNotifications<BE, DataEntity> wireUpNewEntity(BE entity, DataEntity.Blueprint<R> blueprint, CanonicalPath parentPath, BE parent, Transaction<BE> tx) { Validator.validate(tx, blueprint.getValue(), entity); BE value = tx.persist(blueprint.getValue()); //don't report this relationship, it is implicit //also, don't run the RelationshipRules checks - we're in the "privileged code" that is allowed to do //this tx.relate(entity, value, hasData.name(), null); DataEntity data = new DataEntity(parentPath, blueprint.getRole(), blueprint.getValue(), null, null, null, blueprint.getProperties()); return new EntityAndPendingNotifications<>(entity, data, emptyList()); }
@Override public void deleteStructuredData(Element dataRepresentation) { if (!StructuredData.class.equals(extractType(dataRepresentation))) { throw new IllegalArgumentException("The supplied element is not a data entity's data."); } Iterator<Element> dataElements = getTransitiveClosureOver(dataRepresentation, outgoing, contains.name()); closeAfter(dataElements, () -> { // we know the closure is constructed eagerly in this impl, so this loop is OK. while (dataElements.hasNext()) { delete(dataElements.next()); } delete(dataRepresentation); return null; }); }