Repository: ambari Updated Branches: refs/heads/branch-3.0-ams a42cbc5f3 -> 9431d568f
AMBARI-22359 : Fix Serialization issues in Metric Definition Service (avijayan). Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9431d568 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9431d568 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9431d568 Branch: refs/heads/branch-3.0-ams Commit: 9431d568ffa9095cca88656fbe27629db1b7be81 Parents: a42cbc5 Author: Aravindan Vijayan <[email protected]> Authored: Thu Nov 2 14:41:38 2017 -0700 Committer: Aravindan Vijayan <[email protected]> Committed: Thu Nov 2 14:41:38 2017 -0700 ---------------------------------------------------------------------- .../src/main/resources/config.yml | 4 +- .../app/AnomalyDetectionAppConfig.scala | 10 +- .../metrics/adservice/common/Season.scala | 4 +- .../MetricCollectorConfiguration.scala | 10 - .../MetricDefinitionServiceConfiguration.scala | 34 +++ .../MetricManagerServiceConfiguration.scala | 34 --- .../db/PhoenixAnomalyStoreAccessor.scala | 8 +- .../adservice/metadata/ADMetadataProvider.scala | 12 +- .../adservice/metadata/MetricDefinition.scala | 52 ++++- .../metadata/MetricDefinitionService.scala | 64 ++++++ .../metadata/MetricDefinitionServiceImpl.scala | 211 +++++++++++++++++++ .../metadata/MetricManagerService.scala | 64 ------ .../metadata/MetricManagerServiceImpl.scala | 183 ---------------- .../metadata/MetricSourceDefinition.scala | 38 +--- .../app/AnomalyDetectionAppConfigTest.scala | 2 +- .../metrics/adservice/common/SeasonTest.scala | 4 +- .../metadata/MetricDefinitionServiceTest.scala | 130 ++++++++++++ .../metadata/MetricManagerServiceTest.scala | 130 ------------ .../metadata/MetricSourceDefinitionTest.scala | 11 +- 19 files changed, 515 insertions(+), 490 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/resources/config.yml ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/resources/config.yml b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/resources/config.yml index 6953745..920c50c 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/resources/config.yml +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/resources/config.yml @@ -20,8 +20,8 @@ server: logging: type: external -metricManagerService: - inputDefinitionDirectory: /etc/adservice/conf/input-definitions-directory +metricDefinitionService: + inputDefinitionDirectory: /etc/ambari-metrics-anomaly-detection/conf metricsCollector: hostPortList: host1:6188,host2:6188 http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfig.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfig.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfig.scala index be8d027..c1ef0d1 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfig.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfig.scala @@ -20,7 +20,7 @@ package org.apache.ambari.metrics.adservice.app import javax.validation.Valid -import org.apache.ambari.metrics.adservice.configuration.{AdServiceConfiguration, HBaseConfiguration, MetricCollectorConfiguration, MetricManagerServiceConfiguration} +import org.apache.ambari.metrics.adservice.configuration.{AdServiceConfiguration, HBaseConfiguration, MetricCollectorConfiguration, MetricDefinitionServiceConfiguration} import com.fasterxml.jackson.annotation.JsonProperty @@ -35,7 +35,7 @@ class AnomalyDetectionAppConfig extends Configuration { Metric Definition Service configuration */ @Valid - private val metricManagerServiceConfiguration = new MetricManagerServiceConfiguration + private val metricDefinitionServiceConfiguration = new MetricDefinitionServiceConfiguration @Valid private val metricCollectorConfiguration = new MetricCollectorConfiguration @@ -53,9 +53,9 @@ class AnomalyDetectionAppConfig extends Configuration { HBaseConfiguration.getHBaseConf } - @JsonProperty("metricManagerService") - def getMetricManagerServiceConfiguration: MetricManagerServiceConfiguration = { - metricManagerServiceConfiguration + @JsonProperty("metricDefinitionService") + def getMetricDefinitionServiceConfiguration: MetricDefinitionServiceConfiguration = { + metricDefinitionServiceConfiguration } @JsonProperty("adQueryService") http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/common/Season.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/common/Season.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/common/Season.scala index aba2587..f875e3b 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/common/Season.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/common/Season.scala @@ -112,11 +112,11 @@ object Season { validSeasons.toList } - def serialize(season: Season) : String = { + def toJson(season: Season) : String = { mapper.writeValueAsString(season) } - def deserialize(seasonString: String) : Season = { + def fromJson(seasonString: String) : Season = { mapper.readValue[Season](seasonString) } } http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricCollectorConfiguration.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricCollectorConfiguration.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricCollectorConfiguration.scala index 50a0b72..9418897 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricCollectorConfiguration.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricCollectorConfiguration.scala @@ -39,14 +39,4 @@ class MetricCollectorConfiguration { @JsonProperty def getMetadataEndpoint: String = metadataEndpoint - @JsonProperty - def setHostPortList(hostPortList: String): Unit = { - this.hostPortList = hostPortList - } - - @JsonProperty - def setMetadataEndpoint(metadataEndpoint: String): Unit = { - this.metadataEndpoint = metadataEndpoint - } - } http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricDefinitionServiceConfiguration.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricDefinitionServiceConfiguration.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricDefinitionServiceConfiguration.scala new file mode 100644 index 0000000..b560713 --- /dev/null +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricDefinitionServiceConfiguration.scala @@ -0,0 +1,34 @@ +/* + * 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 org.apache.ambari.metrics.adservice.configuration + +import javax.validation.constraints.NotNull + +import com.fasterxml.jackson.annotation.JsonProperty + +/** + * Class to capture the Metric Definition Service configuration. + */ +class MetricDefinitionServiceConfiguration { + + @NotNull + private val inputDefinitionDirectory: String = "" + + @JsonProperty + def getInputDefinitionDirectory: String = inputDefinitionDirectory +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricManagerServiceConfiguration.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricManagerServiceConfiguration.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricManagerServiceConfiguration.scala deleted file mode 100644 index e5960d5..0000000 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/configuration/MetricManagerServiceConfiguration.scala +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 org.apache.ambari.metrics.adservice.configuration - -import javax.validation.constraints.NotNull - -import com.fasterxml.jackson.annotation.JsonProperty - -/** - * Class to capture the Metric Definition Service configuration. - */ -class MetricManagerServiceConfiguration { - - @NotNull - private val inputDefinitionDirectory: String = "" - - @JsonProperty - def getInputDefinitionDirectory: String = inputDefinitionDirectory -} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/db/PhoenixAnomalyStoreAccessor.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/db/PhoenixAnomalyStoreAccessor.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/db/PhoenixAnomalyStoreAccessor.scala index 1191e90..36aea21 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/db/PhoenixAnomalyStoreAccessor.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/db/PhoenixAnomalyStoreAccessor.scala @@ -94,11 +94,11 @@ object PhoenixAnomalyStoreAccessor { val timestamp: Long = rs.getLong("ANOMALY_TIMESTAMP") val metricValue: Double = rs.getDouble("METRIC_VALUE") val methodType: AnomalyDetectionMethod = AnomalyDetectionMethod.withName(rs.getString("METHOD_NAME")) - val season: Season = Season.deserialize(rs.getString("SEASONAL_INFO")) + val season: Season = Season.fromJson(rs.getString("SEASONAL_INFO")) val anomalyScore: Double = rs.getDouble("ANOMALY_SCORE") val modelSnapshot: String = rs.getString("MODEL_PARAMETERS") - val metricKey: MetricKey = null //MetricManager.getMetricKeyFromUuid(uuid) + val metricKey: MetricKey = null //MetricManager.getMetricKeyFromUuid(uuid) //TODO val anomalyInstance: SingleMetricAnomalyInstance = new PointInTimeAnomalyInstance(metricKey, timestamp, metricValue, methodType, anomalyScore, season, modelSnapshot) anomalies.+=(anomalyInstance) @@ -111,11 +111,11 @@ object PhoenixAnomalyStoreAccessor { val referenceStart: Long = rs.getLong("TEST_PERIOD_START") val referenceEnd: Long = rs.getLong("TEST_PERIOD_END") val methodType: AnomalyDetectionMethod = AnomalyDetectionMethod.withName(rs.getString("METHOD_NAME")) - val season: Season = Season.deserialize(rs.getString("SEASONAL_INFO")) + val season: Season = Season.fromJson(rs.getString("SEASONAL_INFO")) val anomalyScore: Double = rs.getDouble("ANOMALY_SCORE") val modelSnapshot: String = rs.getString("MODEL_PARAMETERS") - val metricKey: MetricKey = null //MetricManager.getMetricKeyFromUuid(uuid) + val metricKey: MetricKey = null //MetricManager.getMetricKeyFromUuid(uuid) //TODO val anomalyInstance: SingleMetricAnomalyInstance = TrendAnomalyInstance(metricKey, TimeRange(anomalyStart, anomalyEnd), TimeRange(referenceStart, referenceEnd), http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/ADMetadataProvider.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/ADMetadataProvider.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/ADMetadataProvider.scala index 801c5f5..3bcf4b0 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/ADMetadataProvider.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/ADMetadataProvider.scala @@ -56,11 +56,13 @@ class ADMetadataProvider extends MetricMetadataProvider { val metricKeySet: scala.collection.mutable.Set[MetricKey] = scala.collection.mutable.Set.empty[MetricKey] for (metricDef <- metricSourceDefinition.metricDefinitions) { - for (hostPort <- metricCollectorHostPorts) { - val metricKeys: Set[MetricKey] = getKeysFromMetricsCollector(hostPort + metricMetadataPath, metricDef) - if (metricKeys != null) { - keysMap += (metricDef -> metricKeys) - metricKeySet.++(metricKeys) + if (metricDef.isValid) { //Skip requesting metric keys for invalid definitions. + for (hostPort <- metricCollectorHostPorts) { + val metricKeys: Set[MetricKey] = getKeysFromMetricsCollector(hostPort + metricMetadataPath, metricDef) + if (metricKeys != null) { + keysMap += (metricDef -> metricKeys) + metricKeySet.++(metricKeys) + } } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinition.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinition.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinition.scala index 0a5e51f..036867b 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinition.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinition.scala @@ -18,9 +18,12 @@ package org.apache.ambari.metrics.adservice.metadata +import org.apache.commons.lang3.StringUtils /* { "metric-name": "mem_free", + "appId" : "HOST", + "hosts" : ["h1","h2"], "metric-description" : "Free memory on a Host.", "troubleshooting-info" : "Sudden drop / hike in free memory on a host.", "static-threshold" : 10, @@ -28,12 +31,33 @@ package org.apache.ambari.metrics.adservice.metadata } */ -case class MetricDefinition (metricName: String, - appId: String, - hosts: List[String], - metricDescription: String, - troubleshootingInfo: String, - staticThreshold: Double) { +@SerialVersionUID(1002L) +class MetricDefinition extends Serializable { + + var metricName: String = _ + var appId: String = _ + var hosts: List[String] = List.empty[String] + var metricDescription: String = "" + var troubleshootingInfo: String = "" + var staticThreshold: Double = _ + + //A Metric definition is valid if we can resolve a metricName and appId (defined or inherited) at runtime) + private var valid : Boolean = true + + def this(metricName: String, + appId: String, + hosts: List[String], + metricDescription: String, + troubleshootingInfo: String, + staticThreshold: Double) = { + this + this.metricName = metricName + this.appId = appId + this.hosts = hosts + this.metricDescription = metricDescription + this.troubleshootingInfo = troubleshootingInfo + this.staticThreshold = staticThreshold + } @Override override def equals(obj: scala.Any): Boolean = { @@ -46,10 +70,20 @@ case class MetricDefinition (metricName: String, if (!(metricName == that.metricName)) return false - if (!(appId == that.appId)) - return false + if (StringUtils.isNotEmpty(appId)) { + appId == that.appId + } + else { + StringUtils.isEmpty(that.appId) + } + } + + def isValid: Boolean = { + valid + } - true + def makeInvalid() : Unit = { + valid = false } } http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionService.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionService.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionService.scala new file mode 100644 index 0000000..635dc60 --- /dev/null +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionService.scala @@ -0,0 +1,64 @@ +/* + * 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 org.apache.ambari.metrics.adservice.metadata + +trait MetricDefinitionService { + + /** + * Given a 'UUID', return the metric key associated with it. + * @param uuid UUID + * @return + */ + def getMetricKeyFromUuid(uuid: Array[Byte]) : MetricKey + + /** + * Given a component definition name, return the definition associated with it. + * @param name component definition name + * @return + */ + def getDefinitionByName(name: String) : MetricSourceDefinition + + /** + * Add a new definition. + * @param definition component definition JSON + * @return + */ + def addDefinition(definition: MetricSourceDefinition) : Boolean + + /** + * Update a component definition by name. Only definitions which were added by API can be modified through API. + * @param definition component definition name + * @return + */ + def updateDefinition(definition: MetricSourceDefinition) : Boolean + + /** + * Delete a component definition by name. Only definitions which were added by API can be deleted through API. + * @param name component definition name + * @return + */ + def deleteDefinitionByName(name: String) : Boolean + + /** + * Given an appId, return set of definitions that are tracked for that appId. + * @param appId component definition appId + * @return + */ + def getDefinitionByAppId(appId: String) : List[MetricSourceDefinition] + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceImpl.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceImpl.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceImpl.scala new file mode 100644 index 0000000..ffa9944 --- /dev/null +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceImpl.scala @@ -0,0 +1,211 @@ +/* + * 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 org.apache.ambari.metrics.adservice.metadata + +import org.apache.ambari.metrics.adservice.app.AnomalyDetectionAppConfig +import org.apache.ambari.metrics.adservice.db.AdMetadataStoreAccessor + +import com.google.inject.{Inject, Singleton} + +@Singleton +class MetricDefinitionServiceImpl extends MetricDefinitionService { + + @Inject + var adMetadataStoreAccessor: AdMetadataStoreAccessor = _ + + var configuration: AnomalyDetectionAppConfig = _ + var metricMetadataProvider: MetricMetadataProvider = _ + + var metricSourceDefinitionMap: Map[String, MetricSourceDefinition] = Map() + var metricKeys: Set[MetricKey] = Set.empty[MetricKey] + var metricDefinitionMetricKeyMap: Map[MetricDefinition, Set[MetricKey]] = Map() + + @Inject + def this (anomalyDetectionAppConfig: AnomalyDetectionAppConfig) = { + this () + //TODO : Create AD Metadata instance here (or inject) + configuration = anomalyDetectionAppConfig + initializeService() + } + + def this (anomalyDetectionAppConfig: AnomalyDetectionAppConfig, adMetadataStoreAccessor: AdMetadataStoreAccessor) = { + this () + //TODO : Create AD Metadata instance here (or inject). Pass in Schema information. + configuration = anomalyDetectionAppConfig + this.adMetadataStoreAccessor = adMetadataStoreAccessor + initializeService() + } + + def initializeService() : Unit = { + + //Create AD Metadata Schema + //TODO Make sure AD Metadata DB is initialized here. + + //Initialize Metric Metadata Provider + metricMetadataProvider = new ADMetadataProvider(configuration.getMetricCollectorConfiguration) + + loadMetricSourceDefinitions() + } + + def loadMetricSourceDefinitions() : Unit = { + + //Load definitions from metadata store + val definitionsFromStore: List[MetricSourceDefinition] = adMetadataStoreAccessor.getSavedInputDefinitions + for (definition <- definitionsFromStore) { + validateAndSanitizeMetricSourceDefinition(definition) + } + + //Load definitions from configs + val definitionsFromConfig: List[MetricSourceDefinition] = getInputDefinitionsFromConfig + for (definition <- definitionsFromConfig) { + validateAndSanitizeMetricSourceDefinition(definition) + } + + //Union the 2 sources, with DB taking precedence. + //Save new definition list to DB. + metricSourceDefinitionMap = metricSourceDefinitionMap.++(combineDefinitionSources(definitionsFromConfig, definitionsFromStore)) + + //Reach out to AMS Metadata and get Metric Keys. Pass in List<CD> and get back (Map<MD,Set<MK>>, Set<MK>) + for (definition <- metricSourceDefinitionMap.values) { + val (definitionKeyMap: Map[MetricDefinition, Set[MetricKey]], keys: Set[MetricKey])= metricMetadataProvider.getMetricKeysForDefinitions(definition) + metricDefinitionMetricKeyMap = metricDefinitionMetricKeyMap.++(definitionKeyMap) + metricKeys = metricKeys.++(keys) + } + } + + def getMetricKeyFromUuid(uuid: Array[Byte]): MetricKey = { + var key: MetricKey = null + for (metricKey <- metricKeys) { + if (metricKey.uuid.sameElements(uuid)) { + key = metricKey + } + } + key + } + + @Override + def getDefinitionByName(name: String): MetricSourceDefinition = { + metricSourceDefinitionMap.apply(name) + } + + @Override + def addDefinition(definition: MetricSourceDefinition): Boolean = { + if (metricSourceDefinitionMap.contains(definition.definitionName)) { + return false + } + definition.definitionSource = MetricSourceDefinitionType.API + + val success: Boolean = adMetadataStoreAccessor.saveInputDefinition(definition) + if (success) { + metricSourceDefinitionMap += definition.definitionName -> definition + } + success + } + + @Override + def updateDefinition(definition: MetricSourceDefinition): Boolean = { + if (!metricSourceDefinitionMap.contains(definition.definitionName)) { + return false + } + + if (metricSourceDefinitionMap.apply(definition.definitionName).definitionSource != MetricSourceDefinitionType.API) { + return false + } + + val success: Boolean = adMetadataStoreAccessor.saveInputDefinition(definition) + if (success) { + metricSourceDefinitionMap += definition.definitionName -> definition + } + success + } + + @Override + def deleteDefinitionByName(name: String): Boolean = { + if (!metricSourceDefinitionMap.contains(name)) { + return false + } + + val definition : MetricSourceDefinition = metricSourceDefinitionMap.apply(name) + if (definition.definitionSource != MetricSourceDefinitionType.API) { + return false + } + + val success: Boolean = adMetadataStoreAccessor.removeInputDefinition(name) + if (success) { + metricSourceDefinitionMap += definition.definitionName -> definition + } + success + } + + @Override + def getDefinitionByAppId(appId: String): List[MetricSourceDefinition] = { + + val defList : List[MetricSourceDefinition] = metricSourceDefinitionMap.values.toList + defList.filter(_.appId == appId) + } + + def combineDefinitionSources(configDefinitions: List[MetricSourceDefinition], dbDefinitions: List[MetricSourceDefinition]) + : Map[String, MetricSourceDefinition] = { + + var combinedDefinitionMap: scala.collection.mutable.Map[String, MetricSourceDefinition] = + scala.collection.mutable.Map.empty[String, MetricSourceDefinition] + + for (definitionFromDb <- dbDefinitions) { + combinedDefinitionMap(definitionFromDb.definitionName) = definitionFromDb + } + + for (definition <- configDefinitions) { + if (!dbDefinitions.contains(definition)) { + adMetadataStoreAccessor.saveInputDefinition(definition) + combinedDefinitionMap(definition.definitionName) = definition + } + } + combinedDefinitionMap.toMap + } + + def getInputDefinitionsFromConfig: List[MetricSourceDefinition] = { + val configDirectory = configuration.getMetricDefinitionServiceConfiguration.getInputDefinitionDirectory + InputMetricDefinitionParser.parseInputDefinitionsFromDirectory(configDirectory) + } + + def setAdMetadataStoreAccessor (adMetadataStoreAccessor: AdMetadataStoreAccessor) : Unit = { + this.adMetadataStoreAccessor = adMetadataStoreAccessor + } + + def validateAndSanitizeMetricSourceDefinition(metricSourceDefinition: MetricSourceDefinition): Unit = { + val sourceLevelAppId: String = metricSourceDefinition.appId + val sourceLevelHostList: List[String] = metricSourceDefinition.hosts + + for (metricDef <- metricSourceDefinition.metricDefinitions.toList) { + if (metricDef.appId == null) { + if (sourceLevelAppId == null || sourceLevelAppId.isEmpty) { + metricDef.makeInvalid() + } else { + metricDef.appId = sourceLevelAppId + } + } + + if (metricDef.isValid && metricDef.hosts.isEmpty) { + if (sourceLevelHostList != null && sourceLevelHostList.nonEmpty) { + metricDef.hosts = sourceLevelHostList + } + } + } + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerService.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerService.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerService.scala deleted file mode 100644 index 12bd7e4..0000000 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerService.scala +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 org.apache.ambari.metrics.adservice.metadata - -trait MetricManagerService { - - /** - * Given a 'UUID', return the metric key associated with it. - * @param uuid UUID - * @return - */ - def getMetricKeyFromUuid(uuid: Array[Byte]) : MetricKey - - /** - * Given a component definition name, return the definition associated with it. - * @param name component definition name - * @return - */ - def getDefinitionByName(name: String) : MetricSourceDefinition - - /** - * Add a new definition. - * @param definition component definition JSON - * @return - */ - def addDefinition(definition: MetricSourceDefinition) : Boolean - - /** - * Update a component definition by name. Only definitions which were added by API can be modified through API. - * @param definition component definition name - * @return - */ - def updateDefinition(definition: MetricSourceDefinition) : Boolean - - /** - * Delete a component definition by name. Only definitions which were added by API can be deleted through API. - * @param name component definition name - * @return - */ - def deleteDefinitionByName(name: String) : Boolean - - /** - * Given an appId, return set of definitions that are tracked for that appId. - * @param appId component definition appId - * @return - */ - def getDefinitionByAppId(appId: String) : List[MetricSourceDefinition] - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceImpl.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceImpl.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceImpl.scala deleted file mode 100644 index ce02775..0000000 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceImpl.scala +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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 org.apache.ambari.metrics.adservice.metadata - -import org.apache.ambari.metrics.adservice.app.AnomalyDetectionAppConfig -import org.apache.ambari.metrics.adservice.db.AdMetadataStoreAccessor - -import com.google.inject.{Inject, Singleton} - -@Singleton -class MetricManagerServiceImpl extends MetricManagerService { - - @Inject - var adMetadataStoreAccessor: AdMetadataStoreAccessor = _ - - var configuration: AnomalyDetectionAppConfig = _ - var metricMetadataProvider: MetricMetadataProvider = _ - - var metricSourceDefinitionMap: Map[String, MetricSourceDefinition] = Map() - var metricKeys: Set[MetricKey] = Set.empty[MetricKey] - var metricDefinitionMetricKeyMap: Map[MetricDefinition, Set[MetricKey]] = Map() - - @Inject - def this (anomalyDetectionAppConfig: AnomalyDetectionAppConfig) = { - this () - //TODO : Create AD Metadata instance here (or inject) - configuration = anomalyDetectionAppConfig - initializeService() - } - - def this (anomalyDetectionAppConfig: AnomalyDetectionAppConfig, adMetadataStoreAccessor: AdMetadataStoreAccessor) = { - this () - //TODO : Create AD Metadata instance here (or inject). Pass in Schema information. - configuration = anomalyDetectionAppConfig - this.adMetadataStoreAccessor = adMetadataStoreAccessor - initializeService() - } - - def initializeService() : Unit = { - - //Create AD Metadata Schema - //TODO Make sure AD Metadata DB is initialized here. - - //Initialize Metric Metadata Provider - metricMetadataProvider = new ADMetadataProvider(configuration.getMetricCollectorConfiguration) - - loadMetricSourceDefinitions() - } - - def loadMetricSourceDefinitions() : Unit = { - - //Load definitions from metadata store - val definitionsFromStore: List[MetricSourceDefinition] = adMetadataStoreAccessor.getSavedInputDefinitions - - //Load definitions from configs - val definitionsFromConfig: List[MetricSourceDefinition] = getInputDefinitionsFromConfig - - //Union the 2 sources, with DB taking precedence. - //Save new definition list to DB. - metricSourceDefinitionMap = metricSourceDefinitionMap.++(combineDefinitionSources(definitionsFromConfig, definitionsFromStore)) - - //Reach out to AMS Metadata and get Metric Keys. Pass in List<CD> and get back Map<MD,Set<MK>> - for (definition <- metricSourceDefinitionMap.values) { - val (definitionKeyMap: Map[MetricDefinition, Set[MetricKey]], keys: Set[MetricKey])= metricMetadataProvider.getMetricKeysForDefinitions(definition) - metricDefinitionMetricKeyMap = metricDefinitionMetricKeyMap.++(definitionKeyMap) - metricKeys = metricKeys.++(keys) - } - } - - def getMetricKeyFromUuid(uuid: Array[Byte]): MetricKey = { - var key: MetricKey = null - for (metricKey <- metricKeys) { - if (metricKey.uuid.sameElements(uuid)) { - key = metricKey - } - } - key - } - - @Override - def getDefinitionByName(name: String): MetricSourceDefinition = { - metricSourceDefinitionMap.apply(name) - } - - @Override - def addDefinition(definition: MetricSourceDefinition): Boolean = { - if (metricSourceDefinitionMap.contains(definition.definitionName)) { - return false - } - definition.definitionSource = MetricSourceDefinitionType.API - - val success: Boolean = adMetadataStoreAccessor.saveInputDefinition(definition) - if (success) { - metricSourceDefinitionMap += definition.definitionName -> definition - } - success - } - - @Override - def updateDefinition(definition: MetricSourceDefinition): Boolean = { - if (!metricSourceDefinitionMap.contains(definition.definitionName)) { - return false - } - - if (metricSourceDefinitionMap.apply(definition.definitionName).definitionSource != MetricSourceDefinitionType.API) { - return false - } - - val success: Boolean = adMetadataStoreAccessor.saveInputDefinition(definition) - if (success) { - metricSourceDefinitionMap += definition.definitionName -> definition - } - success - } - - @Override - def deleteDefinitionByName(name: String): Boolean = { - if (!metricSourceDefinitionMap.contains(name)) { - return false - } - - val definition : MetricSourceDefinition = metricSourceDefinitionMap.apply(name) - if (definition.definitionSource != MetricSourceDefinitionType.API) { - return false - } - - val success: Boolean = adMetadataStoreAccessor.removeInputDefinition(name) - if (success) { - metricSourceDefinitionMap += definition.definitionName -> definition - } - success - } - - @Override - def getDefinitionByAppId(appId: String): List[MetricSourceDefinition] = { - - val defList : List[MetricSourceDefinition] = metricSourceDefinitionMap.values.toList - defList.filter(_.appId == appId) - } - - def combineDefinitionSources(configDefinitions: List[MetricSourceDefinition], dbDefinitions: List[MetricSourceDefinition]) - : Map[String, MetricSourceDefinition] = { - - var combinedDefinitionMap: scala.collection.mutable.Map[String, MetricSourceDefinition] = - scala.collection.mutable.Map.empty[String, MetricSourceDefinition] - - for (definitionFromDb <- dbDefinitions) { - combinedDefinitionMap(definitionFromDb.definitionName) = definitionFromDb - } - - for (definition <- configDefinitions) { - if (!dbDefinitions.contains(definition)) { - adMetadataStoreAccessor.saveInputDefinition(definition) - combinedDefinitionMap(definition.definitionName) = definition - } - } - combinedDefinitionMap.toMap - } - - def getInputDefinitionsFromConfig: List[MetricSourceDefinition] = { - val configDirectory = configuration.getMetricManagerServiceConfiguration.getInputDefinitionDirectory - InputMetricDefinitionParser.parseInputDefinitionsFromDirectory(configDirectory) - } - - def setAdMetadataStoreAccessor (adMetadataStoreAccessor: AdMetadataStoreAccessor) : Unit = { - this.adMetadataStoreAccessor = adMetadataStoreAccessor - } -} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinition.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinition.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinition.scala index 60198e0..47b1499 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinition.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/main/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinition.scala @@ -22,10 +22,6 @@ import javax.xml.bind.annotation.XmlRootElement import org.apache.ambari.metrics.adservice.metadata.MetricSourceDefinitionType.MetricSourceDefinitionType import org.apache.ambari.metrics.adservice.model.AnomalyType.AnomalyType -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.module.scala.DefaultScalaModule -import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper - /* { "definition-name": "host-memory", @@ -45,27 +41,10 @@ import com.fasterxml.jackson.module.scala.experimental.ScalaObjectMapper } */ -/* - -On Startup -Read input definitions directory, parse the JSONs -Create / Update the metric definitions in DB -Convert metric definitions to Map<MetricKey, MetricDefinition> - -What to do want to have in memory? -Map of Metric Key -> List<Component Definitions> - -What do we use metric definitions for? -Anomaly GET - Associate definition information as well. -Definition CRUD - Get definition given definition name -Get set of metrics that are being tracked -Return definition information for a metric key -Given a metric definition name, return set of metrics. - -*/ +@SerialVersionUID(10001L) @XmlRootElement -class MetricSourceDefinition { +class MetricSourceDefinition extends Serializable{ var definitionName: String = _ var appId: String = _ @@ -103,17 +82,4 @@ class MetricSourceDefinition { val that = obj.asInstanceOf[MetricSourceDefinition] definitionName.equals(that.definitionName) } -} - -object MetricSourceDefinition { - val mapper = new ObjectMapper() with ScalaObjectMapper - mapper.registerModule(DefaultScalaModule) - - def serialize(definition: MetricSourceDefinition) : String = { - mapper.writeValueAsString(definition) - } - - def deserialize(definitionString: String) : MetricSourceDefinition = { - mapper.readValue[MetricSourceDefinition](definitionString) - } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfigTest.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfigTest.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfigTest.scala index 8e3a949..104ccea 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfigTest.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/app/AnomalyDetectionAppConfigTest.scala @@ -44,7 +44,7 @@ class AnomalyDetectionAppConfigTest extends FunSuite { assert(config.isInstanceOf[AnomalyDetectionAppConfig]) - assert(config.getMetricManagerServiceConfiguration.getInputDefinitionDirectory == "/etc/adservice/conf/input-definitions-directory") + assert(config.getMetricDefinitionServiceConfiguration.getInputDefinitionDirectory == "/etc/ambari-metrics-anomaly-detection/conf") assert(config.getMetricCollectorConfiguration.getHostPortList == "host1:6188,host2:6188") http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/common/SeasonTest.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/common/SeasonTest.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/common/SeasonTest.scala index 4d542e8..a823c73 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/common/SeasonTest.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/common/SeasonTest.scala @@ -78,9 +78,9 @@ class SeasonTest extends FunSuite { test("testSerialize") { val season1 : Season = Season(Range(Calendar.MONDAY,Calendar.FRIDAY), Range(9,17)) - val seasonString = Season.serialize(season1) + val seasonString = Season.toJson(season1) - val season2 : Season = Season.deserialize(seasonString) + val season2 : Season = Season.fromJson(seasonString) assert(season1 == season2) val season3 : Season = Season(Range(Calendar.MONDAY,Calendar.THURSDAY), Range(9,17)) http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceTest.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceTest.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceTest.scala new file mode 100644 index 0000000..d3454f2 --- /dev/null +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricDefinitionServiceTest.scala @@ -0,0 +1,130 @@ +/** + * 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 org.apache.ambari.metrics.adservice.metadata + +import org.apache.ambari.metrics.adservice.app.AnomalyDetectionAppConfig +import org.apache.ambari.metrics.adservice.db.AdMetadataStoreAccessor +import org.easymock.EasyMock.{anyObject, expect, expectLastCall, replay} +import org.scalatest.FunSuite +import org.scalatest.easymock.EasyMockSugar + +class MetricDefinitionServiceTest extends FunSuite { + + test("testAddDefinition") { + + val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] + + for (i <- 1 to 3) { + val msd1 : MetricSourceDefinition = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) + definitions.+=(msd1) + } + + val newDef : MetricSourceDefinition = new MetricSourceDefinition("NewDefinition", "testAppId", MetricSourceDefinitionType.API) + + val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] + expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() + expect(adMetadataStoreAccessor.saveInputDefinition(newDef)).andReturn(true).once() + replay(adMetadataStoreAccessor) + + val metricDefinitionService: MetricDefinitionServiceImpl = new MetricDefinitionServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) + + metricDefinitionService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) + + metricDefinitionService.addDefinition(newDef) + + assert(metricDefinitionService.metricSourceDefinitionMap.size == 4) + assert(metricDefinitionService.metricSourceDefinitionMap.get("testDefinition") != null) + } + + test("testGetDefinitionByName") { + val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] + + for (i <- 1 to 3) { + val msd1 : MetricSourceDefinition = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) + definitions.+=(msd1) + } + + val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] + expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() + replay(adMetadataStoreAccessor) + + val metricDefinitionService: MetricDefinitionServiceImpl = new MetricDefinitionServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) + + metricDefinitionService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) + for (i <- 1 to 3) { + val definition: MetricSourceDefinition = metricDefinitionService.getDefinitionByName("TestDefinition" + i) + assert(definition != null) + } + } + + test("testGetDefinitionByAppId") { + val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] + + for (i <- 1 to 3) { + var msd1 : MetricSourceDefinition = null + if (i == 2) { + msd1 = new MetricSourceDefinition("TestDefinition" + i, null, MetricSourceDefinitionType.API) + } else { + msd1 = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) + } + definitions.+=(msd1) + } + + val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] + expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() + replay(adMetadataStoreAccessor) + + val metricDefinitionService: MetricDefinitionServiceImpl = new MetricDefinitionServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) + + metricDefinitionService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) + val definitionsByAppId: List[MetricSourceDefinition] = metricDefinitionService.getDefinitionByAppId("testAppId") + assert(definitionsByAppId.size == 2) + } + + test("testDeleteDefinitionByName") { + val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] + + for (i <- 1 to 3) { + var msd1 : MetricSourceDefinition = null + if (i == 2) { + msd1 = new MetricSourceDefinition("TestDefinition" + i, null, MetricSourceDefinitionType.CONFIG) + } else { + msd1 = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) + } + definitions.+=(msd1) + } + + val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] + expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() + expect(adMetadataStoreAccessor.removeInputDefinition(anyObject[String])).andReturn(true).times(2) + replay(adMetadataStoreAccessor) + + val metricDefinitionService: MetricDefinitionServiceImpl = new MetricDefinitionServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) + + metricDefinitionService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) + + var success: Boolean = metricDefinitionService.deleteDefinitionByName("TestDefinition1") + assert(success) + success = metricDefinitionService.deleteDefinitionByName("TestDefinition2") + assert(!success) + success = metricDefinitionService.deleteDefinitionByName("TestDefinition3") + assert(success) + } + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceTest.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceTest.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceTest.scala deleted file mode 100644 index 8e19a0f..0000000 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricManagerServiceTest.scala +++ /dev/null @@ -1,130 +0,0 @@ -/** - * 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 org.apache.ambari.metrics.adservice.metadata - -import org.apache.ambari.metrics.adservice.app.AnomalyDetectionAppConfig -import org.apache.ambari.metrics.adservice.db.AdMetadataStoreAccessor -import org.easymock.EasyMock.{anyObject, expect, expectLastCall, replay} -import org.scalatest.FunSuite -import org.scalatest.easymock.EasyMockSugar - -class MetricManagerServiceTest extends FunSuite { - - test("testAddDefinition") { - - val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] - - for (i <- 1 to 3) { - val msd1 : MetricSourceDefinition = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) - definitions.+=(msd1) - } - - val newDef : MetricSourceDefinition = new MetricSourceDefinition("NewDefinition", "testAppId", MetricSourceDefinitionType.API) - - val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] - expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() - expect(adMetadataStoreAccessor.saveInputDefinition(newDef)).andReturn(true).once() - replay(adMetadataStoreAccessor) - - val metricManagerService: MetricManagerServiceImpl = new MetricManagerServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) - - metricManagerService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) - - metricManagerService.addDefinition(newDef) - - assert(metricManagerService.metricSourceDefinitionMap.size == 4) - assert(metricManagerService.metricSourceDefinitionMap.get("testDefinition") != null) - } - - test("testGetDefinitionByName") { - val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] - - for (i <- 1 to 3) { - val msd1 : MetricSourceDefinition = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) - definitions.+=(msd1) - } - - val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] - expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() - replay(adMetadataStoreAccessor) - - val metricManagerService: MetricManagerServiceImpl = new MetricManagerServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) - - metricManagerService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) - for (i <- 1 to 3) { - val definition: MetricSourceDefinition = metricManagerService.getDefinitionByName("TestDefinition" + i) - assert(definition != null) - } - } - - test("testGetDefinitionByAppId") { - val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] - - for (i <- 1 to 3) { - var msd1 : MetricSourceDefinition = null - if (i == 2) { - msd1 = new MetricSourceDefinition("TestDefinition" + i, null, MetricSourceDefinitionType.API) - } else { - msd1 = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) - } - definitions.+=(msd1) - } - - val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] - expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() - replay(adMetadataStoreAccessor) - - val metricManagerService: MetricManagerServiceImpl = new MetricManagerServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) - - metricManagerService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) - val definitionsByAppId: List[MetricSourceDefinition] = metricManagerService.getDefinitionByAppId("testAppId") - assert(definitionsByAppId.size == 2) - } - - test("testDeleteDefinitionByName") { - val definitions : scala.collection.mutable.MutableList[MetricSourceDefinition] = scala.collection.mutable.MutableList.empty[MetricSourceDefinition] - - for (i <- 1 to 3) { - var msd1 : MetricSourceDefinition = null - if (i == 2) { - msd1 = new MetricSourceDefinition("TestDefinition" + i, null, MetricSourceDefinitionType.CONFIG) - } else { - msd1 = new MetricSourceDefinition("TestDefinition" + i, "testAppId", MetricSourceDefinitionType.API) - } - definitions.+=(msd1) - } - - val adMetadataStoreAccessor: AdMetadataStoreAccessor = EasyMockSugar.niceMock[AdMetadataStoreAccessor] - expect(adMetadataStoreAccessor.getSavedInputDefinitions).andReturn(definitions.toList).once() - expect(adMetadataStoreAccessor.removeInputDefinition(anyObject[String])).andReturn(true).times(2) - replay(adMetadataStoreAccessor) - - val metricManagerService: MetricManagerServiceImpl = new MetricManagerServiceImpl(new AnomalyDetectionAppConfig, adMetadataStoreAccessor) - - metricManagerService.setAdMetadataStoreAccessor(adMetadataStoreAccessor) - - var success: Boolean = metricManagerService.deleteDefinitionByName("TestDefinition1") - assert(success) - success = metricManagerService.deleteDefinitionByName("TestDefinition2") - assert(!success) - success = metricManagerService.deleteDefinitionByName("TestDefinition3") - assert(success) - } - -} http://git-wip-us.apache.org/repos/asf/ambari/blob/9431d568/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinitionTest.scala ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinitionTest.scala b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinitionTest.scala index c4d639c..0149673 100644 --- a/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinitionTest.scala +++ b/ambari-metrics/ambari-metrics-anomaly-detection-service/src/test/scala/org/apache/ambari/metrics/adservice/metadata/MetricSourceDefinitionTest.scala @@ -17,6 +17,7 @@ package org.apache.ambari.metrics.adservice.metadata +import org.apache.commons.lang.SerializationUtils import org.scalatest.FunSuite class MetricSourceDefinitionTest extends FunSuite { @@ -46,6 +47,10 @@ class MetricSourceDefinitionTest extends FunSuite { val msd1 : MetricSourceDefinition = new MetricSourceDefinition("testDefinition", "testAppId", MetricSourceDefinitionType.API) val msd2 : MetricSourceDefinition = new MetricSourceDefinition("testDefinition", "testAppId2", MetricSourceDefinitionType.API) assert(msd1 == msd2) + + val msd3 : MetricSourceDefinition = new MetricSourceDefinition("testDefinition1", "testAppId", MetricSourceDefinitionType.API) + val msd4 : MetricSourceDefinition = new MetricSourceDefinition("testDefinition2", "testAppId2", MetricSourceDefinitionType.API) + assert(msd3 != msd4) } test("testRemoveMetricDefinition") { @@ -61,10 +66,10 @@ class MetricSourceDefinitionTest extends FunSuite { test("serializeDeserialize") { val msd : MetricSourceDefinition = new MetricSourceDefinition("testDefinition", "testAppId", MetricSourceDefinitionType.API) - val msdString: String = MetricSourceDefinition.serialize(msd) - assert(msdString.nonEmpty) + val msdByteArray: Array[Byte] = SerializationUtils.serialize(msd) + assert(msdByteArray.nonEmpty) - val msd2: MetricSourceDefinition = MetricSourceDefinition.deserialize(msdString) + val msd2: MetricSourceDefinition = SerializationUtils.deserialize(msdByteArray).asInstanceOf[MetricSourceDefinition] assert(msd2 != null) assert(msd == msd2)
