You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2014/07/18 14:13:49 UTC
[1/2] AMBARI-6528. Add AlertDefinition endpoint and resource provider
(ncole)
Repository: ambari
Updated Branches:
refs/heads/trunk 7bdb1e42c -> 39a92eb49
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
new file mode 100644
index 0000000..de48756
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProviderTest.java
@@ -0,0 +1,162 @@
+/**
+ * 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.server.controller.internal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.alert.MetricAlert;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * AlertDefinition tests
+ */
+public class AlertDefinitionResourceProviderTest {
+
+ AlertDefinitionDAO dao = null;
+
+ @Before
+ public void before() {
+ dao = EasyMock.createStrictMock(AlertDefinitionDAO.class);
+
+ AlertDefinitionResourceProvider.init(dao);
+ }
+
+ @Test
+ public void testGetResourcesNoPredicate() throws Exception {
+ AlertDefinitionResourceProvider provider = createProvider(null);
+
+ Request request = PropertyHelper.getReadRequest("AlertDefinition/cluster_name",
+ "AlertDefinition/id");
+
+ EasyMock.expect(dao.findAll()).andReturn(getMockEntities());
+
+ EasyMock.replay(dao);
+
+ Set<Resource> results = provider.getResources(request, null);
+
+ assertEquals(0, results.size());
+ }
+
+ @Test
+ public void testGetResourcesClusterPredicate() throws Exception {
+ Request request = PropertyHelper.getReadRequest(
+ AlertDefinitionResourceProvider.ALERT_DEF_CLUSTER_NAME,
+ AlertDefinitionResourceProvider.ALERT_DEF_ID,
+ AlertDefinitionResourceProvider.ALERT_DEF_NAME);
+
+ AmbariManagementController amc = EasyMock.createMock(AmbariManagementController.class);
+ Clusters clusters = EasyMock.createMock(Clusters.class);
+ Cluster cluster = EasyMock.createMock(Cluster.class);
+ EasyMock.expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
+ EasyMock.expect(clusters.getCluster(EasyMock.<String>anyObject())).andReturn(cluster).atLeastOnce();
+ EasyMock.expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertDefinitionResourceProvider.ALERT_DEF_CLUSTER_NAME).equals("c1").toPredicate();
+
+ EasyMock.expect(dao.findAll(1L)).andReturn(getMockEntities());
+
+ EasyMock.replay(amc, clusters, cluster, dao);
+
+ AlertDefinitionResourceProvider provider = createProvider(amc);
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+
+ Assert.assertEquals("my_def", r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_NAME));
+ }
+
+ @Test
+ public void testGetSingleResource() throws Exception {
+ Request request = PropertyHelper.getReadRequest(
+ AlertDefinitionResourceProvider.ALERT_DEF_CLUSTER_NAME,
+ AlertDefinitionResourceProvider.ALERT_DEF_ID,
+ AlertDefinitionResourceProvider.ALERT_DEF_NAME,
+ AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE);
+
+ AmbariManagementController amc = EasyMock.createMock(AmbariManagementController.class);
+ Clusters clusters = EasyMock.createMock(Clusters.class);
+ Cluster cluster = EasyMock.createMock(Cluster.class);
+ EasyMock.expect(amc.getClusters()).andReturn(clusters).atLeastOnce();
+ EasyMock.expect(clusters.getCluster(EasyMock.<String>anyObject())).andReturn(cluster).atLeastOnce();
+ EasyMock.expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes();
+
+ Predicate predicate = new PredicateBuilder().property(
+ AlertDefinitionResourceProvider.ALERT_DEF_CLUSTER_NAME).equals("c1")
+ .and().property(AlertDefinitionResourceProvider.ALERT_DEF_ID).equals("1").toPredicate();
+
+ EasyMock.expect(dao.findById(1L)).andReturn(getMockEntities().get(0));
+
+ EasyMock.replay(amc, clusters, cluster, dao);
+
+ AlertDefinitionResourceProvider provider = createProvider(amc);
+ Set<Resource> results = provider.getResources(request, predicate);
+
+ assertEquals(1, results.size());
+
+ Resource r = results.iterator().next();
+
+ Assert.assertEquals("my_def", r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_NAME));
+ Assert.assertEquals("metric", r.getPropertyValue(AlertDefinitionResourceProvider.ALERT_DEF_SOURCE_TYPE));
+ Assert.assertNotNull(r.getPropertyValue("AlertDefinition/metric"));
+ Assert.assertEquals(MetricAlert.class, r.getPropertyValue("AlertDefinition/metric").getClass());
+ }
+
+ private AlertDefinitionResourceProvider createProvider(AmbariManagementController amc) {
+ return new AlertDefinitionResourceProvider(
+ PropertyHelper.getPropertyIds(Resource.Type.AlertDefinition),
+ PropertyHelper.getKeyPropertyIds(Resource.Type.AlertDefinition),
+ amc);
+ }
+
+ private List<AlertDefinitionEntity> getMockEntities() {
+ AlertDefinitionEntity entity = new AlertDefinitionEntity();
+ entity.setClusterId(Long.valueOf(1L));
+ entity.setComponentName(null);
+ entity.setDefinitionId(Long.valueOf(1L));
+ entity.setDefinitionName("my_def");
+ entity.setEnabled(true);
+ entity.setHash("tmphash");
+ entity.setScheduleInterval(Long.valueOf(2L));
+ entity.setServiceName(null);
+ entity.setSourceType("metric");
+ entity.setSource("{'jmx': 'beanName/attributeName', 'host': '{{aa:123445}}'}");
+
+ return Arrays.asList(entity);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index b34a7dd..ca2d24e 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -81,7 +81,9 @@ public class AlertDefinitionDAOTest {
public void testFindByName() {
AlertDefinitionEntity entity = new AlertDefinitionEntity();
TypedQuery<AlertDefinitionEntity> query = createStrictMock(TypedQuery.class);
-
+
+ expect(query.setParameter("clusterId", 12345L)).andReturn(query);
+
expect(query.setParameter("definitionName", "alert-definition-1")).andReturn(
query);
@@ -93,7 +95,7 @@ public class AlertDefinitionDAOTest {
replay(query, entityManager);
- AlertDefinitionEntity result = dao.findByName("alert-definition-1");
+ AlertDefinitionEntity result = dao.findByName(12345L, "alert-definition-1");
assertSame(result, entity);
verify(entityManagerProvider, entityManager);
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
new file mode 100644
index 0000000..7988d8b
--- /dev/null
+++ b/ambari-server/src/test/resources/stacks/HDP/2.0.5/services/HDFS/alerts.json
@@ -0,0 +1,52 @@
+{
+ "service": [
+ ],
+ "SECONDARY_NAMENODE": [
+ {
+ "name": "secondary_namenode_process",
+ "label": "Secondary NameNode process",
+ "interval": 1,
+ "scope": "service",
+ "source": "port",
+ "port": {
+ "config": "{{hdfs-site/dfs.namenode.secondary.http-address}}:50071",
+ "default": 50071
+ }
+ }
+ ],
+ "NAMENODE": [
+ {
+ "name": "namenode_cpu",
+ "label": "NameNode host CPU Utilization",
+ "scope": "host",
+ "source": "metric",
+ "metric": {
+ "jmx": "java.lang:type=OperatingSystem/SystemCpuLoad",
+ "host": "{{hdfs-site/dfs.namenode.secondary.http-address}}"
+ }
+ },
+ {
+ "name": "namenode_process",
+ "label": "NameNode process",
+ "interval": 1,
+ "scope": "host",
+ "source": "port",
+ "port": {
+ "uri": "{{hdfs-site/dfs.namenode.http-address}}:50070"
+ }
+ },
+ {
+ "name": "hdfs_last_checkpoint",
+ "label": "Last Checkpoint Time",
+ "interval": 1,
+ "scope": "service",
+ "source": "script",
+ "enabled": false,
+ "script": {
+ "path": "scripts/alerts/last_checkpoint.py"
+ }
+ }
+ ],
+ "DATANODE": [
+ ]
+}
[2/2] git commit: AMBARI-6528. Add AlertDefinition endpoint and
resource provider (ncole)
Posted by nc...@apache.org.
AMBARI-6528. Add AlertDefinition endpoint and resource provider (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/39a92eb4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/39a92eb4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/39a92eb4
Branch: refs/heads/trunk
Commit: 39a92eb492833ace0b997b2cc4c9523c61832cc0
Parents: 7bdb1e4
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Jul 17 15:18:05 2014 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Jul 18 07:47:48 2014 -0400
----------------------------------------------------------------------
.../resources/AlertDefResourceDefinition.java | 44 ++++
.../resources/ClusterResourceDefinition.java | 1 +
.../resources/ResourceInstanceFactoryImpl.java | 4 +
.../api/services/AlertDefinitionService.java | 93 ++++++++
.../server/api/services/AmbariMetaInfo.java | 43 ++++
.../server/api/services/ClusterService.java | 9 +
.../server/api/util/StackExtensionHelper.java | 12 +-
.../ambari/server/controller/AmbariServer.java | 3 +
.../AbstractControllerResourceProvider.java | 2 +
.../AlertDefinitionResourceProvider.java | 178 ++++++++++++++
.../ambari/server/controller/spi/Resource.java | 6 +-
.../server/orm/dao/AlertDefinitionDAO.java | 27 ++-
.../ambari/server/orm/dao/AlertDispatchDAO.java | 230 ++++++++++++++++++-
.../apache/ambari/server/orm/dao/AlertsDAO.java | 138 +++++++++++
.../server/orm/entities/AlertCurrentEntity.java | 27 +++
.../orm/entities/AlertDefinitionEntity.java | 78 ++++++-
.../server/orm/entities/AlertGroupEntity.java | 46 +++-
.../server/orm/entities/AlertHistoryEntity.java | 36 ++-
.../server/orm/entities/AlertNoticeEntity.java | 29 +++
.../server/orm/entities/AlertTargetEntity.java | 38 ++-
.../apache/ambari/server/state/ServiceInfo.java | 18 +-
.../server/state/alert/AlertDefinition.java | 117 ++++++++++
.../ambari/server/state/alert/MetricAlert.java | 57 +++++
.../apache/ambari/server/state/alert/Scope.java | 33 +++
.../ambari/server/state/alert/SourceType.java | 40 ++++
.../resources/Ambari-DDL-Postgres-CREATE.sql | 1 +
.../Ambari-DDL-Postgres-EMBEDDED-CREATE.sql | 1 +
.../src/main/resources/key_properties.json | 4 +
.../src/main/resources/properties.json | 11 +
.../stacks/HDP/2.0.6/services/HDFS/alerts.json | 59 +++++
.../ClusterResourceDefinitionTest.java | 3 +-
.../server/api/services/AmbariMetaInfoTest.java | 22 ++
.../AlertDefinitionResourceProviderTest.java | 162 +++++++++++++
.../server/orm/dao/AlertDefinitionDAOTest.java | 6 +-
.../stacks/HDP/2.0.5/services/HDFS/alerts.json | 52 +++++
35 files changed, 1594 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
new file mode 100644
index 0000000..1a63097
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertDefResourceDefinition.java
@@ -0,0 +1,44 @@
+/**
+ * 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.server.api.resources;
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Resource Definition for AlertDefinition types.
+ * @author ncole
+ *
+ */
+public class AlertDefResourceDefinition extends BaseResourceDefinition {
+
+ public AlertDefResourceDefinition() {
+ super(Resource.Type.AlertDefinition);
+ }
+
+ @Override
+ public String getPluralName() {
+ // TODO Auto-generated method stub
+ return "alert_definitions";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "alert_definition";
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
index 43578c6..644e8d2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
@@ -65,6 +65,7 @@ public class ClusterResourceDefinition extends BaseResourceDefinition {
setChildren.add(new SubResourceDefinition(Resource.Type.Request));
setChildren.add(new SubResourceDefinition(Resource.Type.Workflow));
setChildren.add(new SubResourceDefinition(Resource.Type.ConfigGroup));
+ setChildren.add(new SubResourceDefinition(Resource.Type.AlertDefinition));
return setChildren;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 2a87c4f..4532919 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -233,6 +233,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
case Permission:
resourceDefinition = new PermissionResourceDefinition();
break;
+
+ case AlertDefinition:
+ resourceDefinition = new AlertDefResourceDefinition();
+ break;
default:
throw new IllegalArgumentException("Unsupported resource type: " + type);
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertDefinitionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertDefinitionService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertDefinitionService.java
new file mode 100644
index 0000000..ee3d29a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertDefinitionService.java
@@ -0,0 +1,93 @@
+/**
+ * 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.server.api.services;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * Endpoint for alert definitions.
+ */
+public class AlertDefinitionService extends BaseService {
+
+ private String m_clusterName = null;
+
+ AlertDefinitionService(String clusterName) {
+ m_clusterName = clusterName;
+ }
+
+ @GET
+ @Produces("text/plain")
+ public Response getDefinitions(String body,
+ @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createResourceInstance(m_clusterName, null));
+ }
+
+ @POST
+ @Produces("text/plain")
+ public Response createDefinition(String body,
+ @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createResourceInstance(m_clusterName, null));
+ }
+
+
+ @GET
+ @Path("{alertDefinitionId}")
+ @Produces("text/plain")
+ public Response getDefinitions(String body,
+ @Context HttpHeaders headers,
+ @Context UriInfo ui,
+ @PathParam("alertDefinitionId") Long id) {
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createResourceInstance(m_clusterName, id));
+ }
+
+
+ /**
+ * Create a request schedule resource instance
+ * @param clusterName
+ * @param requestScheduleId
+ * @return
+ */
+ private ResourceInstance createResourceInstance(String clusterName,
+ Long definitionId) {
+ Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>();
+ mapIds.put(Resource.Type.Cluster, clusterName);
+ mapIds.put(Resource.Type.AlertDefinition, null == definitionId ? null : definitionId.toString());
+
+ return createResource(Resource.Type.AlertDefinition, mapIds);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
index 9bbebf5..c8ccf9a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java
@@ -31,6 +31,7 @@ import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ExecutorService;
@@ -58,6 +59,7 @@ import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.Stack;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.stack.LatestRepoCallable;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.ambari.server.state.stack.RepositoryXml;
@@ -86,6 +88,7 @@ public class AmbariMetaInfo {
public static final String SERVICE_CONFIG_FILE_NAME_POSTFIX = ".xml";
public static final String RCO_FILE_NAME = "role_command_order.json";
public static final String SERVICE_METRIC_FILE_NAME = "metrics.json";
+ public static final String SERVICE_ALERT_FILE_NAME = "alerts.json";
/**
* This string is used in placeholder in places that are common for
* all operating systems or in situations where os type is not important.
@@ -1049,5 +1052,45 @@ public class AmbariMetaInfo {
}
return requiredProperties;
}
+
+ public Set<AlertDefinition> getAlertDefinitions(String stackName, String stackVersion,
+ String serviceName) throws AmbariException {
+
+ ServiceInfo svc = getService(stackName, stackVersion, serviceName);
+
+ if (null == svc.getAlertsFile() || !svc.getAlertsFile().exists()) {
+ LOG.debug("Alerts file for " + stackName + "/" + stackVersion + "/" + serviceName + " not found.");
+ return null;
+ }
+
+
+ Map<String, List<AlertDefinition>> map = null;
+
+ Type type = new TypeToken<Map<String, List<AlertDefinition>>>(){}.getType();
+
+ Gson gson = new Gson();
+
+ try {
+ map = gson.fromJson(new FileReader(svc.getAlertsFile()), type);
+
+ } catch (Exception e) {
+ LOG.error ("Could not read the alert definition file", e);
+ throw new AmbariException("Could not read alert definition file", e);
+ }
+
+ Set<AlertDefinition> defs = new HashSet<AlertDefinition>();
+
+ for (Entry<String, List<AlertDefinition>> entry : map.entrySet()) {
+ for (AlertDefinition ad : entry.getValue()) {
+ ad.setServiceName(serviceName);
+ if (!entry.getKey().equals("service")) {
+ ad.setComponentName(entry.getKey());
+ }
+ }
+ defs.addAll(entry.getValue());
+ }
+
+ return defs;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index 29ca8a0..b7da169 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -207,6 +207,15 @@ public class ClusterService extends BaseService {
(@PathParam ("clusterName") String clusterName) {
return new RequestScheduleService(clusterName);
}
+
+ /**
+ * Gets the alert definition service
+ */
+ @Path("{clusterName}/alert_definitions")
+ public AlertDefinitionService getAlertDefinitionService(
+ @PathParam("clusterName") String clusterName) {
+ return new AlertDefinitionService(clusterName);
+ }
/**
* Create a cluster resource instance.
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
index 15c382b..8b41a1b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/util/StackExtensionHelper.java
@@ -185,6 +185,10 @@ public class StackExtensionHelper {
// metrics
if (null == childService.getMetricsFile() && null != parentService.getMetricsFile())
mergedServiceInfo.setMetricsFile(parentService.getMetricsFile());
+
+ // alerts
+ if (null == childService.getAlertsFile() && null != parentService.getAlertsFile())
+ mergedServiceInfo.setAlertsFile(parentService.getAlertsFile());
populateComponents(mergedServiceInfo, parentService, childService);
@@ -407,6 +411,9 @@ public class StackExtensionHelper {
// get metrics file, if it exists
File metricsJson = new File(serviceFolder.getAbsolutePath()
+ File.separator + AmbariMetaInfo.SERVICE_METRIC_FILE_NAME);
+
+ File alertsJson = new File(serviceFolder.getAbsolutePath() +
+ File.separator + AmbariMetaInfo.SERVICE_ALERT_FILE_NAME);
//Reading v2 service metainfo (may contain multiple services)
// Get services from metadata
@@ -426,7 +433,10 @@ public class StackExtensionHelper {
// process metrics.json
if (metricsJson.exists())
serviceInfo.setMetricsFile(metricsJson);
-
+
+ if (alertsJson.exists())
+ serviceInfo.setAlertsFile(alertsJson);
+
// Get all properties from all "configs/*-site.xml" files
setPropertiesFromConfigs(serviceFolder, serviceInfo);
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index d71cb8c..2011367 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -44,6 +44,7 @@ import org.apache.ambari.server.bootstrap.BootStrapImpl;
import org.apache.ambari.server.configuration.ComponentSSLConfiguration;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.internal.AbstractControllerResourceProvider;
+import org.apache.ambari.server.controller.internal.AlertDefinitionResourceProvider;
import org.apache.ambari.server.controller.internal.BlueprintResourceProvider;
import org.apache.ambari.server.controller.internal.ClusterResourceProvider;
import org.apache.ambari.server.controller.internal.StackDefinedPropertyProvider;
@@ -51,6 +52,7 @@ import org.apache.ambari.server.controller.internal.StackDependencyResourceProvi
import org.apache.ambari.server.controller.nagios.NagiosPropertyProvider;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.PersistenceType;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.dao.BlueprintDAO;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
import org.apache.ambari.server.orm.dao.ViewDAO;
@@ -527,6 +529,7 @@ public class AmbariServer {
StackDependencyResourceProvider.init(ambariMetaInfo);
ClusterResourceProvider.init(injector.getInstance(BlueprintDAO.class), ambariMetaInfo);
ViewRegistry.init(injector.getInstance(ViewDAO.class), injector.getInstance(ViewInstanceDAO.class));
+ AlertDefinitionResourceProvider.init(injector.getInstance(AlertDefinitionDAO.class));
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index f68f21c..5ba926c 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -144,6 +144,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
return new HostComponentProcessResourceProvider(propertyIds, keyPropertyIds, managementController);
case Blueprint:
return new BlueprintResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case AlertDefinition:
+ return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController);
default:
throw new IllegalArgumentException("Unknown type " + type);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
new file mode 100644
index 0000000..c83615a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertDefinitionResourceProvider.java
@@ -0,0 +1,178 @@
+/**
+ * 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.server.controller.internal;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
+import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.alert.MetricAlert;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+
+/**
+ * ResourceProvider for Alert Definitions
+ */
+public class AlertDefinitionResourceProvider extends AbstractControllerResourceProvider {
+
+ protected static final String ALERT_DEF_CLUSTER_NAME = "AlertDefinition/cluster_name";
+ protected static final String ALERT_DEF_ID = "AlertDefinition/id";
+ protected static final String ALERT_DEF_NAME = "AlertDefinition/name";
+ protected static final String ALERT_DEF_INTERVAL = "AlertDefinition/interval";
+ protected static final String ALERT_DEF_SOURCE_TYPE = "AlertDefinition/source";
+ protected static final String ALERT_DEF_SERVICE_NAME = "AlertDefinition/service_name";
+ protected static final String ALERT_DEF_COMPONENT_NAME = "AlertDefinition/component_name";
+ protected static final String ALERT_DEF_ENABLED = "AlertDefinition/enabled";
+ protected static final String ALERT_DEF_SCOPE = "AlertDefinition/scope";
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(ALERT_DEF_ID, ALERT_DEF_NAME));
+ private static AlertDefinitionDAO alertDefinitionDAO = null;
+
+ /**
+ * @param instance
+ */
+ @Inject
+ public static void init(AlertDefinitionDAO instance) {
+ alertDefinitionDAO = instance;
+ }
+
+ AlertDefinitionResourceProvider(Set<String> propertyIds,
+ Map<Resource.Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+ @Override
+ public RequestStatus createResources(Request request) throws SystemException,
+ UnsupportedPropertyException, ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+ Set<Resource> results = new HashSet<Resource>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ String clusterName = (String) propertyMap.get(ALERT_DEF_CLUSTER_NAME);
+
+ if (null == clusterName || clusterName.isEmpty())
+ throw new IllegalArgumentException("Invalid argument, cluster name is required");
+
+ String id = (String) propertyMap.get(ALERT_DEF_ID);
+ if (null != id) {
+ AlertDefinitionEntity entity = alertDefinitionDAO.findById(Long.parseLong(id));
+ if (null != entity) {
+ results.add(toResource(false, clusterName, entity, requestPropertyIds));
+ }
+ } else {
+
+ Cluster cluster = null;
+ try {
+ cluster = getManagementController().getClusters().getCluster(clusterName);
+ } catch (AmbariException e) {
+ throw new NoSuchResourceException("Parent Cluster resource doesn't exist", e);
+ }
+
+ List<AlertDefinitionEntity> entities = alertDefinitionDAO.findAll(
+ cluster.getClusterId());
+
+ for (AlertDefinitionEntity entity : entities) {
+ results.add(toResource(true, clusterName, entity, requestPropertyIds));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not currently supported.");
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+ throw new UnsupportedOperationException("Not currently supported.");
+ }
+
+
+ private Resource toResource(boolean isCollection, String clusterName,
+ AlertDefinitionEntity entity, Set<String> requestedIds) {
+ Resource resource = new ResourceImpl(Resource.Type.AlertDefinition);
+
+ setResourceProperty(resource, ALERT_DEF_CLUSTER_NAME, clusterName, requestedIds);
+ setResourceProperty(resource, ALERT_DEF_ID, entity.getDefinitionId(), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_NAME, entity.getDefinitionName(), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_INTERVAL, entity.getScheduleInterval(), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_SOURCE_TYPE, entity.getSourceType(), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_SERVICE_NAME, entity.getServiceName(), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_COMPONENT_NAME, entity.getComponentName(), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_ENABLED, Boolean.valueOf(entity.getEnabled()), requestedIds);
+ setResourceProperty(resource, ALERT_DEF_SCOPE, entity.getScope(), requestedIds);
+
+ if (!isCollection && null != resource.getPropertyValue(ALERT_DEF_SOURCE_TYPE)) {
+ Gson gson = new Gson();
+
+ if (entity.getSourceType().equals("metric")) {
+ try {
+ MetricAlert ma = gson.fromJson(entity.getSource(), MetricAlert.class);
+ resource.setProperty("AlertDefinition/metric", ma);
+ } catch (Exception e) {
+ LOG.error("Could not coerce alert source into a type");
+ }
+ }
+ }
+
+ return resource;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
index b70f335..a61ab37 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -22,6 +22,8 @@ package org.apache.ambari.server.controller.spi;
import java.util.LinkedHashMap;
import java.util.Map;
+import org.apache.ambari.server.controller.spi.Resource.Type;
+
/**
* The resource object represents a requested resource. The resource
* contains a collection of values for the requested properties.
@@ -110,7 +112,8 @@ public interface Resource {
ViewInstance,
Blueprint,
HostComponentProcess,
- Permission;
+ Permission,
+ AlertDefinition;
/**
* Get the {@link Type} that corresponds to this InternalType.
@@ -182,6 +185,7 @@ public interface Resource {
public static final Type Blueprint = InternalType.Blueprint.getType();
public static final Type HostComponentProcess = InternalType.HostComponentProcess.getType();
public static final Type Permission = InternalType.Permission.getType();
+ public static final Type AlertDefinition = InternalType.AlertDefinition.getType();
/**
* The type name.
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index 6f084df..9163d6e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -62,17 +62,21 @@ public class AlertDefinitionDAO {
}
/**
- * Gets an alert definition with the specified name.
+ * Gets an alert definition with the specified name. Alert definition names
+ * are unique within a cluster.
*
+ * @param clusterId
+ * the ID of the cluster.
* @param definitionName
* the name of the definition (not {@code null}).
* @return the alert definition or {@code null} if none exists.
*/
@RequiresSession
- public AlertDefinitionEntity findByName(String definitionName) {
+ public AlertDefinitionEntity findByName(long clusterId, String definitionName) {
TypedQuery<AlertDefinitionEntity> query = entityManagerProvider.get().createNamedQuery(
"AlertDefinitionEntity.findByName", AlertDefinitionEntity.class);
+ query.setParameter("clusterId", clusterId);
query.setParameter("definitionName", definitionName);
return daoUtils.selectSingle(query);
@@ -81,7 +85,8 @@ public class AlertDefinitionDAO {
/**
* Gets all alert definitions stored in the database.
*
- * @return all alert definitions or {@code null} if none exist.
+ * @return all alert definitions or an empty list if none exist (never
+ * {@code null}).
*/
@RequiresSession
public List<AlertDefinitionEntity> findAll() {
@@ -92,6 +97,22 @@ public class AlertDefinitionDAO {
}
/**
+ * Gets all alert definitions stored in the database.
+ *
+ * @return all alert definitions or empty list if none exist (never
+ * {@code null}).
+ */
+ @RequiresSession
+ public List<AlertDefinitionEntity> findAll(long clusterId) {
+ TypedQuery<AlertDefinitionEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertDefinitionEntity.findAllInCluster", AlertDefinitionEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
* Persists a new alert definition.
*
* @param alertDefinition
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
index c5a9186..0fa803b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDispatchDAO.java
@@ -17,14 +17,23 @@
*/
package org.apache.ambari.server.orm.dao;
+import java.util.List;
+
import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.AlertGroupEntity;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
/**
- *
+ * The {@link AlertDispatchDAO} class manages the {@link AlertTargetEntity},
+ * {@link AlertGroupEntity}, and the associations between them.
*/
@Singleton
public class AlertDispatchDAO {
@@ -33,4 +42,223 @@ public class AlertDispatchDAO {
*/
@Inject
Provider<EntityManager> entityManagerProvider;
+
+ /**
+ * DAO utilities for dealing mostly with {@link TypedQuery} results.
+ */
+ @Inject
+ DaoUtils daoUtils;
+
+ /**
+ * Gets an alert group with the specified ID.
+ *
+ * @param groupId
+ * the ID of the group to retrieve.
+ * @return the group or {@code null} if none exists.
+ */
+ @RequiresSession
+ public AlertGroupEntity findGroupById(long groupId) {
+ return entityManagerProvider.get().find(AlertGroupEntity.class, groupId);
+ }
+
+ /**
+ * Gets an alert target with the specified ID.
+ *
+ * @param targetId
+ * the ID of the target to retrieve.
+ * @return the target or {@code null} if none exists.
+ */
+ @RequiresSession
+ public AlertTargetEntity findTargetById(long targetId) {
+ return entityManagerProvider.get().find(AlertTargetEntity.class, targetId);
+ }
+
+ /**
+ * Gets an alert group with the specified name across all clusters. Alert
+ * group names are unique within a cluster.
+ *
+ * @param groupName
+ * the name of the group (not {@code null}).
+ * @return the alert group or {@code null} if none exists.
+ */
+ @RequiresSession
+ public AlertGroupEntity findGroupByName(String groupName) {
+ TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroup.findByName", AlertGroupEntity.class);
+
+ query.setParameter("groupName", groupName);
+
+ return daoUtils.selectSingle(query);
+ }
+
+ /**
+ * Gets an alert group with the specified name for the given cluster. Alert
+ * group names are unique within a cluster.
+ *
+ * @param clusterId
+ * the ID of the cluster.
+ * @param groupName
+ * the name of the group (not {@code null}).
+ * @return the alert group or {@code null} if none exists.
+ */
+ @RequiresSession
+ public AlertGroupEntity findGroupByName(long clusterId, String groupName) {
+ TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroup.findByNameInCluster", AlertGroupEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+ query.setParameter("groupName", groupName);
+
+ return daoUtils.selectSingle(query);
+ }
+
+ /**
+ * Gets an alert target with the specified name. Alert target names are unique
+ * across all clusters.
+ *
+ * @param targetName
+ * the name of the target (not {@code null}).
+ * @return the alert target or {@code null} if none exists.
+ */
+ @RequiresSession
+ public AlertTargetEntity findTargetByName(String targetName) {
+ TypedQuery<AlertTargetEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroup.findByName", AlertTargetEntity.class);
+
+ query.setParameter("targetName", targetName);
+
+ return daoUtils.selectSingle(query);
+ }
+
+ /**
+ * Gets all alert groups stored in the database across all clusters.
+ *
+ * @return all alert groups or empty list if none exist (never {@code null}).
+ */
+ @RequiresSession
+ public List<AlertGroupEntity> findAllGroups() {
+ TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroupEntity.findAll", AlertGroupEntity.class);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Gets all alert groups stored in the database for the specified cluster.
+ *
+ * @return all alert groups in the specified cluster or empty list if none
+ * exist (never {@code null}).
+ */
+ @RequiresSession
+ public List<AlertGroupEntity> findAllGroups(long clusterId) {
+ TypedQuery<AlertGroupEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertGroupEntity.findAllInCluster", AlertGroupEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Gets all alert targets stored in the database.
+ *
+ * @return all alert targets or empty list if none exist (never {@code null}).
+ */
+ @RequiresSession
+ public List<AlertTargetEntity> findAllTargets() {
+ TypedQuery<AlertTargetEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertTargetEntity.findAll", AlertTargetEntity.class);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Persists a new alert group.
+ *
+ * @param alertGroup
+ * the group to persist (not {@code null}).
+ */
+ @Transactional
+ public void create(AlertGroupEntity alertGroup) {
+ entityManagerProvider.get().persist(alertGroup);
+ }
+
+ /**
+ * Refresh the state of the alert group from the database.
+ *
+ * @param alertGroup
+ * the group to refresh (not {@code null}).
+ */
+ @Transactional
+ public void refresh(AlertGroupEntity alertGroup) {
+ entityManagerProvider.get().refresh(alertGroup);
+ }
+
+ /**
+ * Merge the speicified alert group with the existing group in the database.
+ *
+ * @param alertGroup
+ * the group to merge (not {@code null}).
+ * @return the updated group with merged content (never {@code null}).
+ */
+ @Transactional
+ public AlertGroupEntity merge(AlertGroupEntity alertGroup) {
+ return entityManagerProvider.get().merge(alertGroup);
+ }
+
+ /**
+ * Removes the specified alert group from the database.
+ *
+ * @param alertGroup
+ * the group to remove.
+ */
+ @Transactional
+ public void remove(AlertGroupEntity alertGroup) {
+ entityManagerProvider.get().remove(merge(alertGroup));
+ }
+
+ /**
+ * Persists a new alert target.
+ *
+ * @param alertTarget
+ * the target to persist (not {@code null}).
+ */
+ @Transactional
+ public void create(AlertTargetEntity alertTarget) {
+ entityManagerProvider.get().persist(alertTarget);
+ }
+
+ /**
+ * Refresh the state of the alert target from the database.
+ *
+ * @param alertTarget
+ * the target to refresh (not {@code null}).
+ */
+ @Transactional
+ public void refresh(AlertTargetEntity alertTarget) {
+ entityManagerProvider.get().refresh(alertTarget);
+ }
+
+ /**
+ * Merge the speicified alert target with the existing target in the database.
+ *
+ * @param alertTarget
+ * the target to merge (not {@code null}).
+ * @return the updated target with merged content (never {@code null}).
+ */
+ @Transactional
+ public AlertTargetEntity merge(AlertTargetEntity alertTarget) {
+ return entityManagerProvider.get().merge(alertTarget);
+ }
+
+ /**
+ * Removes the specified alert target from the database.
+ *
+ * @param alertTarget
+ * the target to remove.
+ */
+ @Transactional
+ public void remove(AlertTargetEntity alertTarget) {
+ entityManagerProvider.get().remove(merge(alertTarget));
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
new file mode 100644
index 0000000..9f36860
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertsDAO.java
@@ -0,0 +1,138 @@
+/**
+ * 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.server.orm.dao;
+
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.AlertCurrentEntity;
+import org.apache.ambari.server.orm.entities.AlertHistoryEntity;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import com.google.inject.persist.Transactional;
+
+/**
+ * The {@link AlertsDAO} class manages the {@link AlertHistoryEntity} and
+ * {@link AlertCurrentEntity} instances.Each {@link AlertHistoryEntity} is known
+ * as an "alert" that has been triggered and received.
+ */
+@Singleton
+public class AlertsDAO {
+ /**
+ * JPA entity manager
+ */
+ @Inject
+ Provider<EntityManager> entityManagerProvider;
+
+ /**
+ * DAO utilities for dealing mostly with {@link TypedQuery} results.
+ */
+ @Inject
+ DaoUtils daoUtils;
+
+ /**
+ * Gets an alert with the specified ID.
+ *
+ * @param alertId
+ * the ID of the alert to retrieve.
+ * @return the alert or {@code null} if none exists.
+ */
+ @RequiresSession
+ public AlertHistoryEntity findById(long alertId) {
+ return entityManagerProvider.get().find(AlertHistoryEntity.class, alertId);
+ }
+
+ /**
+ * Gets all alerts stored in the database across all clusters.
+ *
+ * @return all alerts or empty list if none exist (never {@code null}).
+ */
+ @RequiresSession
+ public List<AlertHistoryEntity> findAll() {
+ TypedQuery<AlertHistoryEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertHistoryEntity.findAll", AlertHistoryEntity.class);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Gets all alerts stored in the database for the given cluster.
+ *
+ * @return all alerts in the specified cluster or empty list if none exist
+ * (never {@code null}).
+ */
+ @RequiresSession
+ public List<AlertHistoryEntity> findAll(long clusterId) {
+ TypedQuery<AlertHistoryEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AlertHistoryEntity.findAllInCluster", AlertHistoryEntity.class);
+
+ query.setParameter("clusterId", clusterId);
+
+ return daoUtils.selectList(query);
+ }
+
+ /**
+ * Persists a new alert.
+ *
+ * @param alert
+ * the alert to persist (not {@code null}).
+ */
+ @Transactional
+ public void create(AlertHistoryEntity alert) {
+ entityManagerProvider.get().persist(alert);
+ }
+
+ /**
+ * Refresh the state of the alert from the database.
+ *
+ * @param alert
+ * the alert to refresh (not {@code null}).
+ */
+ @Transactional
+ public void refresh(AlertHistoryEntity alert) {
+ entityManagerProvider.get().refresh(alert);
+ }
+
+ /**
+ * Merge the speicified alert with the existing alert in the database.
+ *
+ * @param alert
+ * the alert to merge (not {@code null}).
+ * @return the updated alert with merged content (never {@code null}).
+ */
+ @Transactional
+ public AlertHistoryEntity merge(AlertHistoryEntity alert) {
+ return entityManagerProvider.get().merge(alert);
+ }
+
+ /**
+ * Removes the specified alert from the database.
+ *
+ * @param alert
+ * the alert to remove.
+ */
+ @Transactional
+ public void remove(AlertHistoryEntity alert) {
+ entityManagerProvider.get().remove(merge(alert));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
index aa99a08..65c2d0f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertCurrentEntity.java
@@ -175,4 +175,31 @@ public class AlertCurrentEntity {
this.alertHistory = alertHistory;
}
+ /**
+ *
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object)
+ return true;
+
+ if (object == null || getClass() != object.getClass())
+ return false;
+
+ AlertCurrentEntity that = (AlertCurrentEntity) object;
+
+ if (alertId != null ? !alertId.equals(that.alertId) : that.alertId != null)
+ return false;
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+ int result = null != alertId ? alertId.hashCode() : 0;
+ return result;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index 98af71d..997fdfd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -17,7 +17,7 @@
*/
package org.apache.ambari.server.orm.entities;
-import java.util.List;
+import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -40,7 +40,8 @@ import javax.persistence.UniqueConstraint;
"cluster_id", "definition_name" }))
@NamedQueries({
@NamedQuery(name = "AlertDefinitionEntity.findAll", query = "SELECT alertDefinition FROM AlertDefinitionEntity alertDefinition"),
- @NamedQuery(name = "AlertDefinitionEntity.findByName", query = "SELECT alertDefinition FROM AlertDefinitionEntity alertDefinition WHERE alertDefinition.definitionName = :definitionName"), })
+ @NamedQuery(name = "AlertDefinitionEntity.findAllInCluster", query = "SELECT alertDefinition FROM AlertDefinitionEntity alertDefinition WHERE alertDefinition.clusterId = :clusterId"),
+ @NamedQuery(name = "AlertDefinitionEntity.findByName", query = "SELECT alertDefinition FROM AlertDefinitionEntity alertDefinition WHERE alertDefinition.definitionName = :definitionName AND alertDefinition.clusterId = :clusterId"), })
public class AlertDefinitionEntity {
@Id
@@ -49,7 +50,7 @@ public class AlertDefinitionEntity {
private Long definitionId;
@Column(name = "alert_source", nullable = false, length = 2147483647)
- private String alertSource;
+ private String source;
@Column(name = "cluster_id", nullable = false)
private Long clusterId;
@@ -59,6 +60,9 @@ public class AlertDefinitionEntity {
@Column(name = "definition_name", nullable = false, length = 255)
private String definitionName;
+
+ @Column(name = "scope", length = 255)
+ private String scope;
@Column(nullable = false)
private Integer enabled = Integer.valueOf(1);
@@ -79,7 +83,7 @@ public class AlertDefinitionEntity {
* Bi-directional many-to-many association to {@link AlertGroupEntity}
*/
@ManyToMany(mappedBy = "alertDefinitions")
- private List<AlertGroupEntity> alertGroups;
+ private Set<AlertGroupEntity> alertGroups;
/**
* Constructor.
@@ -113,8 +117,8 @@ public class AlertDefinitionEntity {
*
* @return the alert source (never {@code null}).
*/
- public String getAlertSource() {
- return alertSource;
+ public String getSource() {
+ return source;
}
/**
@@ -124,8 +128,8 @@ public class AlertDefinitionEntity {
* @param alertSource
* the alert source (not {@code null}).
*/
- public void setAlertSource(String alertSource) {
- this.alertSource = alertSource;
+ public void setSource(String alertSource) {
+ this.source = alertSource;
}
/**
@@ -173,6 +177,27 @@ public class AlertDefinitionEntity {
}
/**
+ * Gets the scope of the alert definition. The scope is defined as either
+ * being for a SERVICE or a HOST.
+ *
+ * @return the scope, or {@code null} if not defined.
+ */
+ public String getScope() {
+ return scope;
+ }
+
+ /**
+ * Sets the scope of the alert definition. The scope is defined as either
+ * being for a SERVICE or a HOST.
+ *
+ * @param scope
+ * the scope to set, or {@code null} for none.
+ */
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ /**
* Gets the name of this alert definition. Alert definition names are unique
* within a cluster.
*
@@ -201,8 +226,8 @@ public class AlertDefinitionEntity {
* @return {@code true} if this alert definition is enabled, {@code false}
* otherwise.
*/
- public Integer getEnabled() {
- return enabled;
+ public boolean getEnabled() {
+ return enabled == 0 ? false : true;
}
/**
@@ -298,7 +323,7 @@ public class AlertDefinitionEntity {
*
* @return the groups, or {@code null} if none.
*/
- public List<AlertGroupEntity> getAlertGroups() {
+ public Set<AlertGroupEntity> getAlertGroups() {
return alertGroups;
}
@@ -308,7 +333,36 @@ public class AlertDefinitionEntity {
* @param alertGroups
* the groups, or {@code null} for none.
*/
- public void setAlertGroups(List<AlertGroupEntity> alertGroups) {
+ public void setAlertGroups(Set<AlertGroupEntity> alertGroups) {
this.alertGroups = alertGroups;
}
+
+ /**
+ *
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object)
+ return true;
+
+ if (object == null || getClass() != object.getClass())
+ return false;
+
+ AlertDefinitionEntity that = (AlertDefinitionEntity) object;
+
+ if (definitionId != null ? !definitionId.equals(that.definitionId)
+ : that.definitionId != null)
+ return false;
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+ int result = null != definitionId ? definitionId.hashCode() : 0;
+ return result;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
index 6df6be2..12b1fff 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertGroupEntity.java
@@ -17,7 +17,7 @@
*/
package org.apache.ambari.server.orm.entities;
-import java.util.List;
+import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -42,7 +42,9 @@ import javax.persistence.UniqueConstraint;
"cluster_id", "group_name" }))
@NamedQueries({
@NamedQuery(name = "AlertGroupEntity.findAll", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup"),
- @NamedQuery(name = "AlertGroupEntity.findByName", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName"), })
+ @NamedQuery(name = "AlertGroupEntity.findAllInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.clusterId = :clusterId"),
+ @NamedQuery(name = "AlertGroupEntity.findByName", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName"),
+ @NamedQuery(name = "AlertGroupEntity.findByNameInCluster", query = "SELECT alertGroup FROM AlertGroupEntity alertGroup WHERE alertGroup.groupName = :groupName AND alertGroup.clusterId = :clusterId"), })
public class AlertGroupEntity {
@Id
@@ -64,13 +66,13 @@ public class AlertGroupEntity {
*/
@ManyToMany
@JoinTable(name = "alert_grouping", joinColumns = { @JoinColumn(name = "group_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "definition_id", nullable = false) })
- private List<AlertDefinitionEntity> alertDefinitions;
+ private Set<AlertDefinitionEntity> alertDefinitions;
/**
* Bi-directional many-to-many association to {@link AlertTargetEntity}
*/
@ManyToMany(mappedBy = "alertGroups")
- private List<AlertTargetEntity> alertTargets;
+ private Set<AlertTargetEntity> alertTargets;
/**
* Constructor.
@@ -164,7 +166,7 @@ public class AlertGroupEntity {
*
* @return the alert definitions or {@code null} if none.
*/
- public List<AlertDefinitionEntity> getAlertDefinitions() {
+ public Set<AlertDefinitionEntity> getAlertDefinitions() {
return alertDefinitions;
}
@@ -174,7 +176,7 @@ public class AlertGroupEntity {
* @param alertDefinitions
* the definitions, or {@code null} for none.
*/
- public void setAlertDefinitions(List<AlertDefinitionEntity> alertDefinitions) {
+ public void setAlertDefinitions(Set<AlertDefinitionEntity> alertDefinitions) {
this.alertDefinitions = alertDefinitions;
}
@@ -184,7 +186,7 @@ public class AlertGroupEntity {
*
* @return the targets, or {@code null} if there are none.
*/
- public List<AlertTargetEntity> getAlertTargets() {
+ public Set<AlertTargetEntity> getAlertTargets() {
return alertTargets;
}
@@ -195,7 +197,35 @@ public class AlertGroupEntity {
* @param alertTargets
* the targets, or {@code null} if there are none.
*/
- public void setAlertTargets(List<AlertTargetEntity> alertTargets) {
+ public void setAlertTargets(Set<AlertTargetEntity> alertTargets) {
this.alertTargets = alertTargets;
}
+
+ /**
+ *
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object)
+ return true;
+
+ if (object == null || getClass() != object.getClass())
+ return false;
+
+ AlertGroupEntity that = (AlertGroupEntity) object;
+
+ if (groupId != null ? !groupId.equals(that.groupId) : that.groupId != null)
+ return false;
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+ int result = null != groupId ? groupId.hashCode() : 0;
+ return result;
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
index c1e346a..2b01514 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity.java
@@ -26,6 +26,7 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
+import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@@ -41,7 +42,9 @@ import org.apache.ambari.server.state.AlertState;
*/
@Entity
@Table(name = "alert_history")
-@NamedQuery(name = "AlertHistoryEntity.findAll", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory")
+@NamedQueries({
+ @NamedQuery(name = "AlertHistoryEntity.findAll", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory"),
+ @NamedQuery(name = "AlertHistoryEntity.findAllInCluster", query = "SELECT alertHistory FROM AlertHistoryEntity alertHistory WHERE alertHistory.clusterId = :clusterId") })
public class AlertHistoryEntity {
@Id
@@ -80,7 +83,7 @@ public class AlertHistoryEntity {
/**
* Bi-directional one-to-one association to {@link AlertCurrentEntity}.
*/
- @OneToOne(mappedBy = "alertHistory")
+ @OneToOne(mappedBy = "alertHistory", orphanRemoval = true)
private AlertCurrentEntity alertCurrent;
/**
@@ -341,4 +344,33 @@ public class AlertHistoryEntity {
public void setAlertDefinition(AlertDefinitionEntity alertDefinition) {
this.alertDefinition = alertDefinition;
}
+
+ /**
+ *
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object)
+ return true;
+
+ if (object == null || getClass() != object.getClass())
+ return false;
+
+ AlertHistoryEntity that = (AlertHistoryEntity) object;
+
+ if (alertId != null ? !alertId.equals(that.alertId) : that.alertId != null)
+ return false;
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+ int result = null != alertId ? alertId.hashCode() : 0;
+ return result;
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
index bc3958e..8f84b49 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertNoticeEntity.java
@@ -152,4 +152,33 @@ public class AlertNoticeEntity {
this.alertTarget = alertTarget;
}
+ /**
+ *
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object)
+ return true;
+
+ if (object == null || getClass() != object.getClass())
+ return false;
+
+ AlertNoticeEntity that = (AlertNoticeEntity) object;
+
+ if (notificationId != null ? !notificationId.equals(that.notificationId)
+ : that.notificationId != null)
+ return false;
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+ int result = null != notificationId ? notificationId.hashCode() : 0;
+ return result;
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
index 595a3b8..32a2979 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertTargetEntity.java
@@ -17,7 +17,7 @@
*/
package org.apache.ambari.server.orm.entities;
-import java.util.List;
+import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
@@ -64,7 +64,7 @@ public class AlertTargetEntity {
*/
@ManyToMany
@JoinTable(name = "alert_group_target", joinColumns = { @JoinColumn(name = "target_id", nullable = false) }, inverseJoinColumns = { @JoinColumn(name = "group_id", nullable = false) })
- private List<AlertGroupEntity> alertGroups;
+ private Set<AlertGroupEntity> alertGroups;
/**
* Constructor.
@@ -163,7 +163,7 @@ public class AlertTargetEntity {
* @return the groups that will send to this target when an alert in that
* group is received, or {@code null} for none.
*/
- public List<AlertGroupEntity> getAlertGroups() {
+ public Set<AlertGroupEntity> getAlertGroups() {
return alertGroups;
}
@@ -174,7 +174,37 @@ public class AlertTargetEntity {
* the groups that will send to this target when an alert in that
* group is received, or {@code null} for none.
*/
- public void setAlertGroups(List<AlertGroupEntity> alertGroups) {
+ public void setAlertGroups(Set<AlertGroupEntity> alertGroups) {
this.alertGroups = alertGroups;
}
+
+ /**
+ *
+ */
+ @Override
+ public boolean equals(Object object) {
+ if (this == object)
+ return true;
+
+ if (object == null || getClass() != object.getClass())
+ return false;
+
+ AlertTargetEntity that = (AlertTargetEntity) object;
+
+ if (targetId != null ? !targetId.equals(that.targetId)
+ : that.targetId != null)
+ return false;
+
+ return true;
+ }
+
+ /**
+ *
+ */
+ @Override
+ public int hashCode() {
+ int result = null != targetId ? targetId.hashCode() : 0;
+ return result;
+ }
+
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
index 44bc369..2ac4a14 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java
@@ -81,7 +81,9 @@ public class ServiceInfo {
private File metricsFile = null;
@XmlTransient
private Map<String, Map<String, List<MetricDefinition>>> metrics = null;
-
+
+ @XmlTransient
+ private File alertsFile = null;
/**
* Internal list of os-specific details (loaded from xml). Added at schema ver 2
@@ -405,4 +407,18 @@ public class ServiceInfo {
public void setMonitoringService(Boolean monitoringService) {
this.monitoringService = monitoringService;
}
+
+ /**
+ * @param file the file containing the alert definitions
+ */
+ public void setAlertsFile(File file) {
+ alertsFile = file;
+ }
+
+ /**
+ * @return the alerts file, or <code>null</code> if none exists
+ */
+ public File getAlertsFile() {
+ return alertsFile;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
new file mode 100644
index 0000000..f8df108
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/AlertDefinition.java
@@ -0,0 +1,117 @@
+/**
+® * 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.server.state.alert;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * @author ncole
+ *
+ */
+public class AlertDefinition {
+
+ private String serviceName = null;
+ private String componentName = null;
+
+ private String name = null;
+ private String label = null;
+ private String scope = null;
+ private String source = null;
+ private int interval = 1;
+ private boolean enabled = true;
+
+ @SerializedName("metric")
+ private MetricAlert metricAlert = null;
+
+ public String getServiceName() {
+ return serviceName;
+ }
+
+ public void setServiceName(String name) {
+ serviceName = name;
+ }
+
+ public String getComponentName() {
+ return componentName;
+ }
+
+ public void setComponentName(String name) {
+ componentName = name;
+ }
+
+ /**
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return the label
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * @return the scope
+ */
+ public String getScope() {
+ return scope;
+ }
+
+ /**
+ * @return the source
+ */
+ public String getSource() {
+ return source;
+ }
+
+ /**
+ * @return the interval
+ */
+ public int getInterval() {
+ return interval;
+ }
+
+ /**
+ * @return <code>true</code> if enabled
+ */
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (null == obj || !obj.getClass().equals(AlertDefinition.class))
+ return false;
+
+ return name.equals(((AlertDefinition) obj).name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricAlert.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricAlert.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricAlert.java
new file mode 100644
index 0000000..b565a3f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/MetricAlert.java
@@ -0,0 +1,57 @@
+/**
+ * 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.server.state.alert;
+
+import com.google.gson.annotations.SerializedName;
+
+/**
+ * Alert when the source type is defined as {@link SourceType#METRIC}
+ */
+public class MetricAlert {
+
+ private String host = null;
+
+ @SerializedName("jmx")
+ private String jmxInfo = null;
+
+ @SerializedName("ganglia")
+ private String gangliaInfo = null;
+
+ /**
+ * @return the jmx info, if this metric is jmx-based
+ */
+ public String getJmxInfo() {
+ return jmxInfo;
+ }
+
+ /**
+ * @return the ganglia info, if this metric is ganglia-based
+ */
+ public String getGangliaInfo() {
+ return gangliaInfo;
+ }
+
+ /**
+ * @return the host info, which may include port information
+ */
+ public String getHost() {
+ return host;
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Scope.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Scope.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Scope.java
new file mode 100644
index 0000000..4b06b62
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/Scope.java
@@ -0,0 +1,33 @@
+/**
+ * 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.server.state.alert;
+
+/**
+ * Assigns a scope to an alert.
+ *
+ */
+public enum Scope {
+ /**
+ * Definition is scoped to a host only
+ */
+ HOST,
+ /**
+ * Definition is scoped to a service only
+ */
+ SERVICE
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/java/org/apache/ambari/server/state/alert/SourceType.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/alert/SourceType.java b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/SourceType.java
new file mode 100644
index 0000000..8289d6f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/alert/SourceType.java
@@ -0,0 +1,40 @@
+/**
+ * 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.server.state.alert;
+
+/**
+ * Source type refers to how the alert is to be collected.
+ */
+public enum SourceType {
+ /**
+ * Source is from metric data.
+ */
+ METRIC,
+ /**
+ * Source is generated using of a script
+ */
+ SCRIPT,
+ /**
+ * Source is a simple port check
+ */
+ PORT,
+ /**
+ * Source is an aggregate of a collection of other alert states
+ */
+ AGGREGATE
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 5a42153..09cb052 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -150,6 +150,7 @@ CREATE TABLE alert_definition (
definition_name VARCHAR(255) NOT NULL,
service_name VARCHAR(255) NOT NULL,
component_name VARCHAR(255),
+ scope VARCHAR(255),
enabled SMALLINT DEFAULT 1 NOT NULL,
schedule_interval BIGINT NOT NULL,
source_type VARCHAR(255) NOT NULL,
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
index deb70ab..f837e0a 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-EMBEDDED-CREATE.sql
@@ -207,6 +207,7 @@ CREATE TABLE ambari.alert_definition (
definition_name VARCHAR(255) NOT NULL,
service_name VARCHAR(255) NOT NULL,
component_name VARCHAR(255),
+ scope VARCHAR(255),
enabled SMALLINT DEFAULT 1 NOT NULL,
schedule_interval BIGINT NOT NULL,
source_type VARCHAR(255) NOT NULL,
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/resources/key_properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/key_properties.json b/ambari-server/src/main/resources/key_properties.json
index 68aa632..13adde8 100644
--- a/ambari-server/src/main/resources/key_properties.json
+++ b/ambari-server/src/main/resources/key_properties.json
@@ -130,5 +130,9 @@
"Component": "HostComponentProcess/component_name",
"HostComponent": "HostComponentProcess/component_name",
"HostComponentProcess": "HostComponentProcess/name"
+ },
+ "AlertDefinition": {
+ "Cluster": "AlertDefinition/cluster_name",
+ "AlertDefinition": "AlertDefinition/id"
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/resources/properties.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/properties.json b/ambari-server/src/main/resources/properties.json
index a6cdac4..4d5407c 100644
--- a/ambari-server/src/main/resources/properties.json
+++ b/ambari-server/src/main/resources/properties.json
@@ -355,5 +355,16 @@
"HostComponentProcess/component_name",
"HostComponentProcess/name",
"HostComponentProcess/status"
+ ],
+ "AlertDefinition": [
+ "AlertDefinition/cluster_name",
+ "AlertDefinition/service_name",
+ "AlertDefinition/component_name",
+ "AlertDefinition/id",
+ "AlertDefinition/name",
+ "AlertDefinition/interval",
+ "AlertDefinition/source",
+ "AlertDefinition/enabled",
+ "AlertDefinition/scope"
]
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
new file mode 100644
index 0000000..c1918e5
--- /dev/null
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/HDFS/alerts.json
@@ -0,0 +1,59 @@
+{
+ "service": [
+ // datanode space aggregate
+ // datanode process aggregate
+ ],
+ "SECONDARY_NAMENODE": [
+ {
+ "name": "secondary_namenode_process",
+ "label": "Secondary NameNode process",
+ "interval": 1,
+ "scope": "service",
+ "source": "port",
+ "port": {
+ "config": "{{hdfs-site/dfs.namenode.secondary.http-address}}:50071",
+ "default": 50071
+ }
+ }
+ ],
+ "NAMENODE": [
+ // name node cpu utilization (metric)
+ {
+ "name": "namenode_cpu",
+ "label": "NameNode host CPU Utilization",
+ "scope": "host",
+ "source": "metric",
+ "metric": {
+ "jmx_object": "java.lang:type=OperatingSystem",
+ "jmx_attribute": "SystemCpuLoad",
+ "host": "{{hdfs-site/dfs.namenode.secondary.http-address}}"
+ }
+ },
+ // namenode process (port check)
+ {
+ "name": "namenode_process",
+ "label": "NameNode process",
+ "interval": 1,
+ "scope": "host",
+ "source": "port",
+ "port": {
+ "uri": "{{hdfs-site/dfs.namenode.http-address}}:50070"
+ }
+ },
+ {
+ "name": "hdfs_last_checkpoint",
+ "label": "Last Checkpoint Time",
+ "interval": 1,
+ "scope": "service",
+ "source": "script",
+ "enabled": false
+ "script": {
+ "path": "scripts/alerts/last_checkpoint.py"
+ }
+ }
+ ],
+ "DATANODE": [
+ // datanode process (port check)
+ // datanode space
+ ]
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
index a4ee74b..6a48134 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/resources/ClusterResourceDefinitionTest.java
@@ -50,13 +50,14 @@ public class ClusterResourceDefinitionTest {
ResourceDefinition resource = new ClusterResourceDefinition();
Set<SubResourceDefinition> subResources = resource.getSubResourceDefinitions();
- assertEquals(6, subResources.size());
+ assertEquals(7, subResources.size());
assertTrue(includesType(subResources, Resource.Type.Service));
assertTrue(includesType(subResources, Resource.Type.Host));
assertTrue(includesType(subResources, Resource.Type.Configuration));
assertTrue(includesType(subResources, Resource.Type.Request));
assertTrue(includesType(subResources, Resource.Type.Workflow));
assertTrue(includesType(subResources, Resource.Type.ConfigGroup));
+ assertTrue(includesType(subResources, Resource.Type.AlertDefinition));
}
@Test
http://git-wip-us.apache.org/repos/asf/ambari/blob/39a92eb4/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
index 71bc1f8..0c6f8f0 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java
@@ -61,6 +61,7 @@ import org.apache.ambari.server.state.RepositoryInfo;
import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.Stack;
import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.stack.MetricDefinition;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
@@ -1382,4 +1383,25 @@ public class AmbariMetaInfoTest {
Assert.assertNotNull(passwordProperty);
Assert.assertEquals("javax.jdo.option.ConnectionPassword", passwordProperty.getName());
}
+
+ @Test
+ public void testAlertsJson() throws Exception {
+ ServiceInfo svc = metaInfo.getService(STACK_NAME_HDP, "2.0.5", "HDFS");
+ Assert.assertNotNull(svc);
+ Assert.assertNotNull(svc.getAlertsFile());
+
+ svc = metaInfo.getService(STACK_NAME_HDP, "2.0.6", "HDFS");
+ Assert.assertNotNull(svc);
+ Assert.assertNotNull(svc.getAlertsFile());
+
+ svc = metaInfo.getService(STACK_NAME_HDP, "1.3.4", "HDFS");
+ Assert.assertNotNull(svc);
+ Assert.assertNull(svc.getAlertsFile());
+
+ Set<AlertDefinition> set = metaInfo.getAlertDefinitions(STACK_NAME_HDP,
+ "2.0.5", "HDFS");
+ Assert.assertNotNull(set);
+ Assert.assertTrue(set.size() > 0);
+
+ }
}