/* * 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.model; import java.util.Collections; import java.util.Map; import java.util.Objects; import java.util.Set; import org.hawkular.inventory.paths.CanonicalPath; import org.hawkular.inventory.paths.SegmentType; import io.swagger.annotations.ApiModel; /** * Metric describes a single metric that is sent out from a feed. Each metric has a unique ID and a type. Metrics live * in an environment and can be "incorporated" by {@link Resource resources} (surprisingly, many resources can * incorporate a single metric). * * @author Lukas Krejci * @since 0.0.1 */ @ApiModel(description = "A metric represents a monitored \"quality\". Its metric type specifies the unit in which" + " the metric reports its values and the collection interval specifies how often the feed should be collecting" + " the metric for changes in value.", parent = SyncedEntity.class) public final class Metric extends SyncedEntity<Metric.Blueprint, Metric.Update> { public static final SegmentType SEGMENT_TYPE = SegmentType.m; private final MetricType type; private final Long collectionInterval; /** * Jackson support */ @SuppressWarnings("unused") private Metric() { type = null; collectionInterval = null; } public Metric(CanonicalPath path, String identityHash, String contentHash, String syncHash, MetricType type) { this(null, path, identityHash, contentHash, syncHash, type, null, null); } public Metric(String name, CanonicalPath path, String identityHash, String contentHash, String syncHash, MetricType type) { this(name, path, identityHash, contentHash, syncHash, type, null ,null); } public Metric(CanonicalPath path, String identityHash, String contentHash, String syncHash, MetricType type, Long collectionInterval) { this(null, path, identityHash, contentHash, syncHash, type, collectionInterval, null); } public Metric(CanonicalPath path, String identityHash, String contentHash, String syncHash, MetricType type, Map<String, Object> properties) { this(null, path, identityHash, contentHash, syncHash, type, null, properties); } public Metric(String name, CanonicalPath path, String identityHash, String contentHash, String syncHash, MetricType type, Long collectionInterval, Map<String, Object> properties) { super(name, path, identityHash, contentHash, syncHash, properties); this.type = type; this.collectionInterval = collectionInterval; } @Override public Updater<Update, Metric> update() { return new Updater<>((u) -> new Metric(u.getName(), getPath(), getIdentityHash(), getContentHash(), getSyncHash(), getType(), u.getCollectionInterval(), u.getProperties()), this, Update.builder()); } public MetricType getType() { return type; } public Long getCollectionInterval() { return collectionInterval; } @Override protected void appendToString(StringBuilder toStringBuilder) { super.appendToString(toStringBuilder); toStringBuilder.append(", definition=").append(type); } @Override public <R, P> R accept(ElementVisitor<R, P> visitor, P parameter) { return visitor.visitMetric(this, parameter); } /** * Data required to create a new metric. * * <p>Note that tenantId, etc., are not needed here because they are provided by the context in which the * {@link org.hawkular.inventory.api.WriteInterface#create(org.hawkular.inventory.api.model.Blueprint)} method is * called. */ @ApiModel("MetricBlueprint") public static final class Blueprint extends Entity.Blueprint { private final String metricTypePath; private final Long collectionInterval; public static Builder builder() { return new Builder(); } /** * Jackson support */ @SuppressWarnings("unused") private Blueprint() { metricTypePath = null; collectionInterval = null; } public Blueprint(String metricTypePath, String id) { this(metricTypePath, id, Collections.emptyMap()); } public Blueprint(String metricTypePath, String id, Map<String, Object> properties) { super(id, properties); this.metricTypePath = metricTypePath; this.collectionInterval = null; } public Blueprint(String metricTypePath, String id, Map<String, Object> properties, Map<String, Set<CanonicalPath>> outgoing, Map<String, Set<CanonicalPath>> incoming) { super(id, properties, outgoing, incoming); this.metricTypePath = metricTypePath; this.collectionInterval = null; } public Blueprint(String metricTypePath, String id, String name, Map<String, Object> properties, Map<String, Set<CanonicalPath>> outgoing, Map<String, Set<CanonicalPath>> incoming) { super(id, name, properties, outgoing, incoming); this.metricTypePath = metricTypePath; this.collectionInterval = null; } public Blueprint(String metricTypePath, String id, String name, Long collectionInterval, Map<String, Object> properties, Map<String, Set<CanonicalPath>> outgoing, Map<String, Set<CanonicalPath>> incoming) { super(id, name, properties, outgoing, incoming); this.metricTypePath = metricTypePath; this.collectionInterval = collectionInterval; } public String getMetricTypePath() { return metricTypePath; } public Long getCollectionInterval() { return collectionInterval; } @Override public <R, P> R accept(ElementBlueprintVisitor<R, P> visitor, P parameter) { return visitor.visitMetric(this, parameter); } public static final class Builder extends Entity.Blueprint.Builder<Blueprint, Builder> { private String metricTypeId; private Long collectionInterval; public Builder withMetricTypePath(String metricTypePath) { this.metricTypeId = metricTypePath; return this; } public Builder withInterval(Long interval) { this.collectionInterval = interval; return this; } @Override public Blueprint build() { return new Blueprint(metricTypeId, id, name, collectionInterval, properties, outgoing, incoming); } } } @ApiModel("MetricUpdate") public static final class Update extends Entity.Update { private final Long collectionInterval; public static Builder builder() { return new Builder(); } //JAXB support @SuppressWarnings("unused") private Update() { this(null, null); } public Update(Map<String, Object> properties, Long collectionInterval) { super(null, properties); this.collectionInterval = collectionInterval; } public Update(String name, Map<String, Object> properties, Long collectionInterval) { super(name, properties); this.collectionInterval = collectionInterval; } public Long getCollectionInterval() { return collectionInterval; } @Override public <R, P> R accept(ElementUpdateVisitor<R, P> visitor, P parameter) { return visitor.visitMetric(this, parameter); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Update)) return false; if (!super.equals(o)) return false; Update update = (Update) o; return collectionInterval != null ? collectionInterval.equals(update.collectionInterval) : update.collectionInterval == null; } @Override public int hashCode() { int result = super.hashCode(); result = 31 * result + (collectionInterval != null ? collectionInterval.hashCode() : 0); return result; } public static final class Builder extends Entity.Update.Builder<Metric, Update, Builder> { private Long collectionInterval; public Builder withInterval(Long interval) { this.collectionInterval = interval; return this; } @Override public Update build() { return new Update(name, properties, collectionInterval); } @Override public Builder withDifference(Metric original, Metric updated) { if (!Objects.equals(original.getCollectionInterval(), updated.getCollectionInterval())) { withInterval(updated.getCollectionInterval()); } return super.withDifference(original, updated); } } } }