/*
* Copyright 2015 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 org.hawkular.inventory.api.model.Relationship;
/**
* This is a wrapper class to hold various interfaces defining available functionality on relationships.
*
* @author Lukas Krejci
* @since 0.0.1
*/
public final class Relationships {
private Relationships() {
}
/**
* The list of well-known relationships (aka edges) between entities (aka vertices).
*/
public enum WellKnown {
/**
* Expresses encapsulation of a set of entities in another entity.
* Used for example to express the relationship between a tenant and the set of its environments.
*
* <p>Note that entities that are contained within another entity (by the virtue of there being this
* relationship between them) are deleted along with it.
*
* <p>Note also that it is prohibited to create loops in the contains relationships, i.e. an entity cannot
* (indirectly) contain itself. Also, containment is unique and therefore 1 entity cannot be contained in 2 or
* more other entities.
*/
contains,
/**
* Expresses "instantiation" of some entity based on the definition provided by "source" entity.
* For example, there is a defines relationship between a metric definition and all metrics that
* conform to it.
*
* <p>Note that as long as an entity defines other entities, it cannot be deleted.
*/
defines,
/**
* Expresses inclusion. For example a resource incorporates a set of metrics, or a resource type incorporates a
* set of metric definitions. They do not contain it though, because more resources can incorporate a single
* metric for example.
*/
incorporates,
/**
* Used to express hierarchy of resources.
*
* <p> There are 2 separate concepts that need to be understood when examining resource hierarchy:
* <ol>
* <li>The embedding of resources into each other - i.e. the child resources are inseparable from their
* parent, because they are its parts - e. g. memory subsystem of JVM. These are modelled using 2 separate
* relationships in inventory. The containment aspect is modelled by the {@link #contains} relationship and
* the hierarchy aspect is modelled by the {@code isParentOf} relationship. When a {@link #contains}
* relationship is established between 2 resources, the {@code isParentOf} is automagically added by the
* inventory.
*
* <li>Custom hierarchies can be defined between arbitrary resources, regardless of their containment in
* other resources. These can be useful to compose ad-hoc "groupings" of resources
* </ol>
*
* <p>This relationship cannot form loops (similarly to {@link #contains}) but allows for 1 resource having more
* than 1 parent. This is allowed so that custom/parallel resource hierarchies can be created that share the
* same resources (the most obvious example of this is that a resource that has been discovered and
* "hierarchized" by a feed can also be put "under" a custom, user-defined, resource).
*
*
* <p>When deleting a resource, all its contained child resources are deleted along with it as mandated by the
* contract of the {@link #contains} relationship.
*/
isParentOf,
/**
* This relationship is used to link the {@link org.hawkular.inventory.api.model.DataEntity} to its data.
* This relationship is invisible to the API users, because one cannot obtain a {@link Relationship} object
* of it using the API but it is specified here nevertheless because it is a part of the contract of the API
* with the backend storage.
*/
hasData
}
/**
* The list of possible relationship (aka edges) direction. Relationships are not bidirectional.
*/
public enum Direction {
/**
* Relative to the current position in the inventory traversal, this value expresses such relationships
* that has me (the entity(ies) on the current pos) as a source(s).
*/
outgoing,
/**
* Relative to the current position in the inventory traversal, this value expresses such relationships
* that has me (the entity(ies) on the current pos) as a target(s).
*/
incoming,
/**
* Relative to the current position in the inventory traversal, this value expresses all the relationships
* I (the entity(ies) on the current pos) have with other entity(ies).
*/
both;
public Direction opposite() {
switch (this) {
case outgoing:
return incoming;
case incoming:
return outgoing;
case both:
return both;
default:
throw new AssertionError("Incomplete opposite direction mapping.");
}
}
}
/**
* Interface for accessing a single relationship.
*/
public interface Single extends ResolvableToSingle<Relationship, Relationship.Update> {
}
/**
* Interface for traversing over a set of relationships.
*
* <p>Note that traversing over a set of entities enables only read-only access. If you need to use any of the
* modification methods, you first need to resolve the traversal to a single entity (using the
* {@link ReadInterface#get(Object)} method).
*/
public interface Multiple extends ResolvableToMany<Relationship> {
Tenants.Read tenants();
Environments.Read environments();
Feeds.Read feeds();
MetricTypes.Read metricTypes();
Metrics.Read metrics();
Resources.Read resources();
ResourceTypes.Read resourceTypes();
}
/**
* Provides read-write access to relationships.
*/
public interface ReadWrite extends ReadWriteRelationshipsInterface<Single, Multiple> {
Multiple named(String name);
Multiple named(WellKnown name);
}
/**
* Provides read access to relationships.
*/
public interface Read extends ReadRelationshipsInterface<Single, Multiple> {
Multiple named(String name);
Multiple named(WellKnown name);
}
}