/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You 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 gobblin.runtime.api; import java.net.URI; import java.util.Collection; import com.codahale.metrics.Gauge; import com.google.common.collect.ImmutableMap; import gobblin.instrumented.GobblinMetricsKeys; import gobblin.instrumented.Instrumentable; import gobblin.metrics.ContextAwareCounter; import gobblin.metrics.ContextAwareGauge; import gobblin.metrics.GobblinTrackingEvent; import lombok.Getter; public interface SpecCatalog extends SpecCatalogListenersContainer, Instrumentable { /** Returns an immutable {@link Collection} of {@link Spec}s that are known to the catalog. */ Collection<Spec> getSpecs(); /** Metrics for the spec catalog; null if * ({@link #isInstrumentationEnabled()}) is false. */ SpecCatalog.StandardMetrics getMetrics(); /** * Get a {@link Spec} by uri. * @throws SpecNotFoundException if no such Spec exists **/ Spec getSpec(URI uri) throws SpecNotFoundException; public static class StandardMetrics implements SpecCatalogListener { public static final String NUM_ACTIVE_SPECS_NAME = "numActiveSpecs"; public static final String NUM_ADDED_SPECS = "numAddedSpecs"; public static final String NUM_DELETED_SPECS = "numDeletedSpecs"; public static final String NUM_UPDATED_SPECS = "numUpdatedSpecs"; public static final String TRACKING_EVENT_NAME = "SpecCatalogEvent"; public static final String SPEC_ADDED_OPERATION_TYPE = "SpecAdded"; public static final String SPEC_DELETED_OPERATION_TYPE = "SpecDeleted"; public static final String SPEC_UPDATED_OPERATION_TYPE = "SpecUpdated"; @Getter private final ContextAwareGauge<Integer> numActiveSpecs; @Getter private final ContextAwareCounter numAddedSpecs; @Getter private final ContextAwareCounter numDeletedSpecs; @Getter private final ContextAwareCounter numUpdatedSpecs; public StandardMetrics(final SpecCatalog parent) { this.numAddedSpecs = parent.getMetricContext().contextAwareCounter(NUM_ADDED_SPECS); this.numDeletedSpecs = parent.getMetricContext().contextAwareCounter(NUM_DELETED_SPECS); this.numUpdatedSpecs = parent.getMetricContext().contextAwareCounter(NUM_UPDATED_SPECS); this.numActiveSpecs = parent.getMetricContext().newContextAwareGauge(NUM_ACTIVE_SPECS_NAME, new Gauge<Integer>() { @Override public Integer getValue() { return parent.getSpecs().size(); } }); parent.addListener(this); } @Override public void onAddSpec(Spec addedSpec) { this.numAddedSpecs.inc(); submitTrackingEvent(addedSpec, SPEC_ADDED_OPERATION_TYPE); } private void submitTrackingEvent(Spec spec, String operType) { submitTrackingEvent(spec.getUri(), spec.getVersion(), operType); } private void submitTrackingEvent(URI specSpecURI, String specSpecVersion, String operType) { GobblinTrackingEvent e = GobblinTrackingEvent.newBuilder() .setName(TRACKING_EVENT_NAME) .setNamespace(SpecCatalog.class.getName()) .setMetadata(ImmutableMap.<String, String>builder() .put(GobblinMetricsKeys.OPERATION_TYPE_META, operType) .put(GobblinMetricsKeys.SPEC_URI_META, specSpecURI.toString()) .put(GobblinMetricsKeys.SPEC_VERSION_META, specSpecVersion) .build()) .build(); this.numAddedSpecs.getContext().submitEvent(e); } @Override public void onDeleteSpec(URI deletedSpecURI, String deletedSpecVersion) { this.numDeletedSpecs.inc(); submitTrackingEvent(deletedSpecURI, deletedSpecVersion, SPEC_DELETED_OPERATION_TYPE); } @Override public void onUpdateSpec(Spec updatedSpec) { this.numUpdatedSpecs.inc(); submitTrackingEvent(updatedSpec, SPEC_UPDATED_OPERATION_TYPE); } } }