/* * 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.impl.tinkerpop.spi; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__contentHash; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__from; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__identityHash; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__metric_data_type; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__metric_interval; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__sourceCp; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__sourceEid; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__sourceType; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataIndex; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataKey; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataType; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataValue_b; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataValue_f; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataValue_i; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__structuredDataValue_s; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__syncHash; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__targetCp; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__targetEid; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__targetType; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__to; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.__unit; import static org.hawkular.inventory.impl.tinkerpop.spi.Constants.Property.name; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import org.hawkular.inventory.api.model.AbstractElement; import org.hawkular.inventory.api.model.DataEntity; import org.hawkular.inventory.api.model.ElementVisitor; import org.hawkular.inventory.api.model.Environment; import org.hawkular.inventory.api.model.Feed; import org.hawkular.inventory.api.model.MetadataPack; import org.hawkular.inventory.api.model.Metric; import org.hawkular.inventory.api.model.MetricType; import org.hawkular.inventory.api.model.OperationType; import org.hawkular.inventory.api.model.Relationship; import org.hawkular.inventory.api.model.Resource; import org.hawkular.inventory.api.model.ResourceType; import org.hawkular.inventory.api.model.StructuredData; import org.hawkular.inventory.api.model.Tenant; import org.hawkular.inventory.paths.ElementTypeVisitor; import org.hawkular.inventory.paths.SegmentType; /** * @author Lukas Krejci * @since 0.0.1 */ public final class Constants { private Constants() { //no instances, thank you } /** * The vertices in the graph have certain well-known properties. The __foo form is used internally to decrease the * chance of collision with any user defined properties. However, for sorting purposes it's quite cumbersome to use * it directly, so the property can have also the user-friendly name (sortName). */ public enum Property { /** * The user-defined human-readable name of the entity. We don't use the "__" prefix here as with the rest of * the properties, because this is not really hidden. */ name(String.class), /** * This is the name of the property that we use to store the type of the entity represented by the vertex */ __type("type", String.class), /** * This is the name of the property that we use to store the user-defined ID of the entity represented by the * vertex. These ID are required to be unique only amongst their "siblings" as determined by the "contains" * hierarchy. */ __eid("id", String.class), /** * Present on metric type, this is the name of the propety that we use to store the unit of the metric type * represented by the vertex. */ __unit("unit", String.class), /** * Property used on metric type to distinguish type of metric e.g. gauge, counter... */ __metric_data_type("metricDataType", String.class), /** * Property used to store interval in seconds at which metrics are collected */ __metric_interval("collectionInterval", Long.class), /** * Property used to store the canonical path of an element. */ __cp("path", String.class), /** * The type of the data stored by the structured data vertex */ __structuredDataType(String.class), /** * The key using which a structured data value is stored in a map. */ __structuredDataKey(String.class), /** * The index on which a structured data value is stored in a list. */ __structuredDataIndex(Integer.class), /** * The name of the property on the structured data vertex that holds the primitive value of that vertex. * List and maps don't hold the value directly but instead have edges going out to the child vertices. */ __structuredDataValue_b(Boolean.class), __structuredDataValue_i(Long.class), __structuredDataValue_f(Double.class), __structuredDataValue_s(String.class), __sourceType("sourceType", String.class), __targetType("targetType", String.class), __sourceCp("source", String.class), __targetCp("target", String.class), __sourceEid(String.class), __targetEid(String.class), __identityHash("identityHash", String.class), __targetIdentityHash(String.class), __contentHash("contentHash", String.class), __syncHash("syncHash", String.class), __from(Long.class), __to(Long.class), __changeKind(int.class) ; private final String sortName; private final Class<?> propertyType; Property(Class<?> type) { this(null, type); } Property(String sortName, Class<?> type) { this.sortName = sortName; this.propertyType = type; } public String getSortName() { return sortName; } public Class<?> getPropertyType() { return propertyType; } private static final HashSet<String> MIRRORED_PROPERTIES = new HashSet<>(Arrays.asList(__type.name(), __eid.name(), __cp.name())); private static Map<String, String> NAME_TO_PROPERTY = new HashMap<>(); static { try { NAME_TO_PROPERTY = Collections.unmodifiableMap(Arrays.asList(values()).stream() .filter(prop -> prop.getSortName() != null) .collect(Collectors.toMap(Property::getSortName, Property::name))); } catch (Exception e) { // this may happen if there is a duplicate key when doing Collectors.toMap -> duplicated sortName // it's better to swallow the exception and let the backend initialize properly Log.LOG.error("Unable to initialize Constants.Property enum: " + e.getMessage()); } } public static String mapUserDefined(String property) { if (NAME_TO_PROPERTY.get(property) != null) { return NAME_TO_PROPERTY.get(property); } return property; } public static boolean isMirroredInEdges(String property) { return MIRRORED_PROPERTIES.contains(property); } } /** * The type of entities known to Hawkular. */ public enum Type { tenant(Tenant.class, name, __contentHash), environment(Environment.class, name, __contentHash), feed(Feed.class, name, __identityHash, __contentHash, __syncHash), resourceType(ResourceType.class, name, __identityHash, __contentHash, __syncHash), metricType(MetricType.class, name, __unit, __metric_data_type, __metric_interval, __identityHash, __contentHash, __syncHash), operationType(OperationType.class, name, __identityHash, __contentHash, __syncHash), resource(Resource.class, name, __identityHash, __contentHash, __syncHash), metric(Metric.class, name, __metric_interval, __identityHash, __contentHash, __syncHash), metadatapack(MetadataPack.class, name), relationship(Relationship.class, __sourceType, __targetType, __sourceCp, __targetCp, __sourceEid, __targetEid, __from, __to), dataEntity(DataEntity.class, name, __identityHash, __contentHash, __syncHash), structuredData(StructuredData.class, __structuredDataType, __structuredDataValue_b, __structuredDataValue_i, __structuredDataValue_f, __structuredDataValue_s, __structuredDataIndex, __structuredDataKey); private final String[] mappedProperties; private final Class<?> entityType; private static final List<String> identityVertexProperties = Arrays.asList(Property.__type.name(), Property.__eid.name(), Property.__cp.name()); Type(Class<?> entityType, Property... mappedProperties) { this.entityType = entityType; this.mappedProperties = new String[mappedProperties.length + 3]; Arrays.setAll(this.mappedProperties, i -> { switch (i) { case 0: return Property.__type.name(); case 1: return Property.__eid.name(); case 2: return Property.__cp.name(); default: return mappedProperties[i - 3].name(); } }); } public static Type of(AbstractElement<?, ?> e) { return e.accept(new ElementVisitor<Type, Void>() { @Override public Type visitRelationship(Relationship relationship, Void parameter) { return Type.relationship; } @Override public Type visitTenant(Tenant tenant, Void parameter) { return Type.tenant; } @Override public Type visitEnvironment(Environment environment, Void parameter) { return Type.environment; } @Override public Type visitFeed(Feed feed, Void parameter) { return Type.feed; } @Override public Type visitMetric(Metric metric, Void parameter) { return Type.metric; } @Override public Type visitMetricType(MetricType definition, Void parameter) { return Type.metricType; } @Override public Type visitResource(Resource resource, Void parameter) { return Type.resource; } @Override public Type visitResourceType(ResourceType type, Void parameter) { return Type.resourceType; } @Override public Type visitData(DataEntity data, Void parameter) { return Type.dataEntity; } @Override public Type visitOperationType(OperationType operationType, Void parameter) { return Type.operationType; } @Override public Type visitMetadataPack(MetadataPack metadataPack, Void parameter) { return Type.metadatapack; } @Override public Type visitUnknown(Object entity, Void parameter) { return null; } }, null); } public static Type of(Class<?> ec) { return of(AbstractElement.segmentTypeFromType(ec)); } public static Type of(SegmentType st) { return ElementTypeVisitor.accept(st, new ElementTypeVisitor<Type, Void>() { @Override public Type visitTenant(Void parameter) { return tenant; } @Override public Type visitEnvironment(Void parameter) { return environment; } @Override public Type visitFeed(Void parameter) { return feed; } @Override public Type visitMetric(Void parameter) { return metric; } @Override public Type visitMetricType(Void parameter) { return metricType; } @Override public Type visitResource(Void parameter) { return resource; } @Override public Type visitResourceType(Void parameter) { return resourceType; } @Override public Type visitRelationship(Void parameter) { return relationship; } @Override public Type visitData(Void parameter) { return dataEntity; } @Override public Type visitOperationType(Void parameter) { return operationType; } @Override public Type visitMetadataPack(Void parameter) { return Type.metadatapack; } @Override public Type visitUnknown(Void parameter) { if (st == SegmentType.sd) { return structuredData; } throw new IllegalArgumentException("Unsupported entity type " + st); } }, null); } public Class<?> getEntityType() { return entityType; } /** * @return list of properties that are explicitly mapped to entity class properties. */ public String[] getMappedProperties() { return mappedProperties; } public String identityVertexLabel() { return name(); } public String stateVertexLabel() { return identityVertexLabel() + "_state"; } public static List<String> getIdentityVertexProperties() { return identityVertexProperties; } } public enum InternalEdge { __withIdentityHash, __containsIdentityHash, __inState } public enum InternalType { __identityHash } }