/* * Copyright 2015-2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.hawkular.inventory.api; import static java.util.stream.Collectors.toList; import java.util.List; import java.util.stream.StreamSupport; import org.hawkular.inventory.api.model.Relationship; import org.hawkular.inventory.paths.Path; /** * An interface providing methods to add a pre-existing entity into relation with the single entity in the current * position on the inventory traversal. * * <p>Note that this interface should never be inherited by the actual {@code Single} interface together with the * {@link WriteInterface}. Having both {@code create} and {@code associate} or {@code disassociate} and {@code delete} * methods would be semantically incorrect (in addition to being confusing to the API consumer). * * @author Lukas Krejci * @since 0.0.1 */ interface AssociationInterface { /** * Adds a pre-existing entity into the relation with the current entity. * * The current entity is determined by the current position in the inventory traversal as is the type of the entity * being related to it. Consider this example: * * <pre><code> * inventory.tenants().get(tenantId).environments().get(envId).resources().get(rId).metrics().associate( * RelativePath.to().up().metric(metricId)); * </code></pre> * * <p>In here the {@code associate} method will add a new metric (identified by the {@code metricId}) to the * resource identified by the {@code rId}. * * <p>The provided path can be a {@link org.hawkular.inventory.paths.RelativePath} (as in the above example) * which is evaluated against the current position in the graph - the * {@link org.hawkular.inventory.paths.RelativePath#up() up()} call will move up the path from the resource * to the environment and the {@code metric()} call will the move to a metric in that environment. * * <p>The provided path can also be a {@link org.hawkular.inventory.paths.CanonicalPath} in which case it is * fully evaluated and the entity on that path is associated (provided the path points to the correct type of * entity and all the rules specific for the association of the two types of entities are fulfilled). * * @param path the path to a pre-existing entity to be related to the entity on the current position in the * inventory traversal. * @return the relationship that was created as the consequence of the association. */ Relationship associate(Path path) throws EntityNotFoundException, RelationAlreadyExistsException; /** * Associates a number of paths with the entity on the current position in the traversal. * <p> * The default implementation merely calls {@link #associate(Path)} for each of the paths. * * @param paths the paths to the entities to associate * @return the list of the relationships in the iteration order of the supplied paths * @see #associate(Path) */ default List<Relationship> associate(Iterable<Path> paths) { return StreamSupport.stream(paths.spliterator(), false).map(this::associate).collect(toList()); } /** * Removes an entity from the relation with the current entity. * * The current entity and the type of the entity to remove from the relation is determined by the current position * in the inventory traversal. * * @see #associate(Path) for explanation of how the current entity and the relation is determined. * * @param path the id of the entity to remove from the relation with the current entity. * * @return the relationship that was deleted as a result of the disassociation */ Relationship disassociate(Path path) throws EntityNotFoundException; /** * Similar to {@link #associate(Iterable)}, this method disassociates the provided paths. * <p> * The default implementation merely calls {@link #disassociate(Path)} for each of the provided paths. * * @param paths the paths to disassociate * @return the list of the removed relationships in the iteration order of the paths * @see #disassociate(Path) */ default List<Relationship> disassociate(Iterable<Path> paths) { return StreamSupport.stream(paths.spliterator(), false).map(this::disassociate).collect(toList()); } /** * Finds the relationship with the entity with the provided id. * * @see #associate(Path) for the discussion of how the entity and the relationship is determined * * @param path the id of the entity to find the relation with * * @return the relationship found * * @throws RelationNotFoundException if a relation with an entity of given id doesn't exist */ Relationship associationWith(Path path) throws RelationNotFoundException; }