Repository: ambari Updated Branches: refs/heads/trunk 19eeff551 -> 03784ecad
AMBARI-7734 - Alerts: Create REST API Endpoint for Alert History (jonathanhurley) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/03784eca Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/03784eca Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/03784eca Branch: refs/heads/trunk Commit: 03784ecad819a6b6ee422b4ba6158e9d860f3655 Parents: 19eeff5 Author: Jonathan Hurley <[email protected]> Authored: Fri Oct 10 13:56:15 2014 -0400 Committer: Jonathan Hurley <[email protected]> Committed: Sun Oct 12 20:27:04 2014 -0400 ---------------------------------------------------------------------- .../server/api/query/JpaPredicateVisitor.java | 258 +++++++++++++++++++ .../AlertHistoryResourceDefinition.java | 50 ++++ .../resources/ResourceInstanceFactoryImpl.java | 6 +- .../api/services/AlertHistoryService.java | 99 +++++++ .../server/api/services/ClusterService.java | 22 +- .../server/controller/AlertHistoryRequest.java | 34 +++ .../ambari/server/controller/AmbariServer.java | 2 + .../AbstractControllerResourceProvider.java | 6 - .../AlertDefinitionResourceProvider.java | 41 ++- .../internal/AlertGroupResourceProvider.java | 36 ++- .../internal/AlertHistoryResourceProvider.java | 251 ++++++++++++++++++ .../internal/AlertTargetResourceProvider.java | 37 ++- .../internal/DefaultProviderModule.java | 12 +- .../ambari/server/controller/spi/Resource.java | 2 + .../apache/ambari/server/orm/dao/AlertsDAO.java | 67 +++++ .../orm/entities/AlertDefinitionEntity_.java | 50 ++++ .../orm/entities/AlertHistoryEntity_.java | 94 +++++++ .../src/main/resources/key_properties.json | 11 - .../src/main/resources/properties.json | 29 --- .../AlertDefinitionResourceProviderTest.java | 5 +- .../AlertGroupResourceProviderTest.java | 4 +- .../AlertHistoryResourceProviderTest.java | 228 ++++++++++++++++ .../AlertTargetResourceProviderTest.java | 4 +- .../ambari/server/orm/dao/AlertsDAOTest.java | 168 ++++++++++++ 24 files changed, 1433 insertions(+), 83 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/api/query/JpaPredicateVisitor.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/query/JpaPredicateVisitor.java b/ambari-server/src/main/java/org/apache/ambari/server/api/query/JpaPredicateVisitor.java new file mode 100644 index 0000000..660bae7 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/query/JpaPredicateVisitor.java @@ -0,0 +1,258 @@ +/** + * 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.query; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.Path; +import javax.persistence.criteria.Root; +import javax.persistence.metamodel.SingularAttribute; + +import org.apache.ambari.server.controller.predicate.AlwaysPredicate; +import org.apache.ambari.server.controller.predicate.ArrayPredicate; +import org.apache.ambari.server.controller.predicate.CategoryPredicate; +import org.apache.ambari.server.controller.predicate.ComparisonPredicate; +import org.apache.ambari.server.controller.predicate.PredicateVisitor; +import org.apache.ambari.server.controller.predicate.UnaryPredicate; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.utilities.PredicateHelper; + +/** + * The {@link JpaPredicateVisitor} is used to convert an Ambari + * {@link Predicate} into a JPA {@link javax.persistence.criteria.Predicate}. + */ +public abstract class JpaPredicateVisitor<T> implements PredicateVisitor { + /** + * JPA entity manager + */ + private EntityManager m_entityManager; + + /** + * Builds the {@link CriteriaQuery} from the {@link Predicate}. + */ + private CriteriaBuilder m_builder; + + /** + * The root that the {@code from} clause requests from. + */ + private Root<T> m_root; + + /** + * The query to submit to JPA. + */ + private CriteriaQuery<T> m_query; + + /** + * The last calculated predicate. + */ + private javax.persistence.criteria.Predicate m_lastPredicate = null; + + /** + * A queue of lists of {@link javax.persistence.criteria.Predicate}. Every + * time an {@code OR} or {@code AND} is encountered, a new chain (list) is + * created and the prior list is enqeued. When the logical statement is + * closed, the chain is completed and added to the prior chain's list. + */ + private ArrayDeque<List<javax.persistence.criteria.Predicate>> m_queue = + new ArrayDeque<List<javax.persistence.criteria.Predicate>>(); + + /** + * Constructor. + * + * @param entityManager + * the EM used to get a {@link CriteriaBuilder}. + * @param entityClass + * the entity class being queried from. + */ + public JpaPredicateVisitor(EntityManager entityManager, Class<T> entityClass) { + m_entityManager = entityManager; + m_builder = m_entityManager.getCriteriaBuilder(); + m_query = m_builder.createQuery(entityClass); + m_root = m_query.from(entityClass); + } + + /** + * Gets the entity class that is the root type in the JPA {@code from} clause. + * + * @return the entity class (not {@code null}). + */ + public abstract Class<T> getEntityClass(); + + /** + * Gets the {@link SingularAttribute}s mapped to the specified Ambari-style + * property. + * + * @param propertyId + * the Ambari-style property (not {@code null}). + * @return the {@link SingularAttribute}, or {@code null} if no mapping + * exists. + */ + public abstract List<? extends SingularAttribute<?, ?>> getPredicateMapping( + String propertyId); + + /** + * Gets the final JPA {@link javax.persistence.criteria.Predicate} after the + * visitor is done traversing the Ambari {@link Predicate}. + * + * @return the predicate, or {@code null} if none. + */ + public javax.persistence.criteria.Predicate getJpaPredicate() { + return m_lastPredicate; + } + + /** + * Gets the query to use along with {@link #getJpaPredicate()}. + * + * @return the query (not {@code null}). + */ + public CriteriaQuery<T> getCriteriaQuery() { + return m_query; + } + + /** + * {@inheritDoc} + */ + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + public void acceptComparisonPredicate(ComparisonPredicate predicate) { + String propertyId = predicate.getPropertyId(); + + List<? extends SingularAttribute<?, ?>> singularAttributes = getPredicateMapping(propertyId); + + if (null == singularAttributes || singularAttributes.size() == 0) { + return; + } + + SingularAttribute<?, ?> lastSingularAttribute = null; + Path<Comparable> path = null; + + for (SingularAttribute<?, ?> singularAttribute : singularAttributes) { + lastSingularAttribute = singularAttribute; + + if (null == path) { + path = m_root.get(singularAttribute.getName()); + } else { + path = path.get(singularAttribute.getName()); + } + } + + if (null == path) { + return; + } + + String operator = predicate.getOperator(); + Comparable<?> value = predicate.getValue(); + + // convert string to enum for proper JPA comparisons + Class<?> clazz = lastSingularAttribute.getJavaType(); + if (clazz.isEnum()) { + Class<? extends Enum> enumClass = (Class<? extends Enum>) clazz; + value = Enum.valueOf(enumClass, value.toString()); + } + + javax.persistence.criteria.Predicate jpaPredicate = null; + if ("=".equals(operator)) { + jpaPredicate = m_builder.equal(path, value); + } else if ("<".equals(operator)) { + jpaPredicate = m_builder.lessThan(path, value); + } else if ("<=".equals(operator)) { + jpaPredicate = m_builder.lessThanOrEqualTo(path, value); + } else if (">".equals(operator)) { + jpaPredicate = m_builder.greaterThan(path, value); + } else if (">=".equals(operator)) { + jpaPredicate = m_builder.greaterThanOrEqualTo(path, value); + } + + if (null == jpaPredicate) { + return; + } + + if (null == m_queue.peekLast()) { + m_lastPredicate = jpaPredicate; + } else { + m_queue.peekLast().add(jpaPredicate); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void acceptArrayPredicate(ArrayPredicate predicate) { + // no predicates, no work + Predicate[] predicates = predicate.getPredicates(); + if (predicates.length == 0) { + return; + } + + // create a new list for all of the predicates in this chain + List<javax.persistence.criteria.Predicate> predicateList = new ArrayList<javax.persistence.criteria.Predicate>(); + m_queue.add(predicateList); + + // visit every child predicate so it can be added to the list + String operator = predicate.getOperator(); + for (int i = 0; i < predicates.length; i++) { + PredicateHelper.visit(predicates[i], this); + } + + // the list is done; deque and apply logical AND or OR + predicateList = m_queue.pollLast(); + + javax.persistence.criteria.Predicate jpaPredicate = null; + javax.persistence.criteria.Predicate[] array = new javax.persistence.criteria.Predicate[predicateList.size()]; + array = predicateList.toArray(array); + + if ("AND".equals(operator)) { + jpaPredicate = m_builder.and(array); + } else { + jpaPredicate = m_builder.or(array); + } + + if (null == m_queue.peekLast()) { + m_lastPredicate = jpaPredicate; + } else { + m_queue.peekLast().add(jpaPredicate); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void acceptUnaryPredicate(UnaryPredicate predicate) { + } + + /** + * {@inheritDoc} + */ + @Override + public void acceptAlwaysPredicate(AlwaysPredicate predicate) { + } + + /** + * {@inheritDoc} + */ + @Override + public void acceptCategoryPredicate(CategoryPredicate predicate) { + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertHistoryResourceDefinition.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertHistoryResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertHistoryResourceDefinition.java new file mode 100644 index 0000000..729a140 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/AlertHistoryResourceDefinition.java @@ -0,0 +1,50 @@ +/** + * 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 {@link Resource.Type#AlertHistory} types. + */ +public class AlertHistoryResourceDefinition extends BaseResourceDefinition { + + /** + * Constructor. + * + */ + public AlertHistoryResourceDefinition() { + super(Resource.Type.AlertHistory); + } + + /** + * {@inheritDoc} + */ + @Override + public String getPluralName() { + return "alert_history"; + } + + /** + * {@inheritDoc} + */ + @Override + public String getSingularName() { + return "alert_history"; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 d024528..c7a3277 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 @@ -249,7 +249,7 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory { case Permission: resourceDefinition = new PermissionResourceDefinition(); break; - + case Alert: resourceDefinition = new AlertResourceDefinition(); break; @@ -258,6 +258,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory { resourceDefinition = new AlertDefResourceDefinition(); break; + case AlertHistory: + resourceDefinition = new AlertHistoryResourceDefinition(); + break; + case AlertGroup: resourceDefinition = new AlertGroupResourceDefinition(); break; http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertHistoryService.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertHistoryService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertHistoryService.java new file mode 100644 index 0000000..f1855f0 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AlertHistoryService.java @@ -0,0 +1,99 @@ +/** + * 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.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 history. + */ +public class AlertHistoryService extends BaseService { + + private String clusterName = null; + private String serviceName = null; + private String hostName = null; + + /** + * Constructor. + * + * @param clusterName + * the cluster name (not {@code null}). + * @param serviceName + * the service name, or {@code null} to return history across all + * services. + * @param hostName + * the host name, or {@code null} to return history across all hosts. + */ + AlertHistoryService(String clusterName, String serviceName, String hostName) { + this.clusterName = clusterName; + this.serviceName = serviceName; + this.hostName = hostName; + } + + @GET + @Produces("text/plain") + public Response getHistories(String body, + @Context HttpHeaders headers, + @Context UriInfo ui) { + return handleRequest(headers, body, ui, Request.Type.GET, + createResourceInstance(clusterName, null)); + } + + @GET + @Path("{alertHistoryId}") + @Produces("text/plain") + public Response getHistory(String body, + @Context HttpHeaders headers, + @Context UriInfo ui, @PathParam("alertHistoryId") Long id) { + return handleRequest(headers, body, ui, Request.Type.GET, + createResourceInstance(clusterName, id)); + } + + /** + * Create an alert history resource instance + * + * @param clusterName + * @return + */ + private ResourceInstance createResourceInstance(String clusterName, + Long historyId) { + Map<Resource.Type, String> mapIds = new HashMap<Resource.Type, String>(); + mapIds.put(Resource.Type.Cluster, clusterName); + mapIds.put(Resource.Type.Service, serviceName); + mapIds.put(Resource.Type.Host, hostName); + + if (null != historyId) { + mapIds.put(Resource.Type.AlertHistory, historyId.toString()); + } + + return createResource(Resource.Type.AlertHistory, mapIds); + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 a56bcbf..e039b6a 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 @@ -357,7 +357,7 @@ public class ClusterService extends BaseService { hasPermission(Request.Type.valueOf(request.getMethod()), clusterName); return new ClusterPrivilegeService(clusterName); } - + /** * Gets the alert definition service * @@ -372,8 +372,26 @@ public class ClusterService extends BaseService { hasPermission(Request.Type.valueOf(request.getMethod()), clusterName); return new AlertService(clusterName, null, null); - } + } + /** + * Gets the alert history service + * + * @param request + * the request + * @param clusterName + * the cluster name + * + * @return the alert history service + */ + @Path("{clusterName}/alert_history") + public AlertHistoryService getAlertHistoryService( + @Context javax.ws.rs.core.Request request, + @PathParam("clusterName") String clusterName) { + + hasPermission(Request.Type.valueOf(request.getMethod()), clusterName); + return new AlertHistoryService(clusterName, null, null); + } // ----- helper methods ---------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertHistoryRequest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertHistoryRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertHistoryRequest.java new file mode 100644 index 0000000..9dc6cc4 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AlertHistoryRequest.java @@ -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.server.controller; + +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.orm.entities.AlertHistoryEntity; + +/** + * The {@link AlertHistoryRequest} encapsulates the data necessary to make a + * backend request for {@link AlertHistoryEntity}. + */ +public class AlertHistoryRequest { + + /** + * An Ambari predicate. + */ + public Predicate Predicate; + +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 f843aa8..d428b80 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 @@ -47,6 +47,7 @@ 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.AlertGroupResourceProvider; +import org.apache.ambari.server.controller.internal.AlertHistoryResourceProvider; import org.apache.ambari.server.controller.internal.AlertResourceProvider; import org.apache.ambari.server.controller.internal.AlertSummaryPropertyProvider; import org.apache.ambari.server.controller.internal.AlertTargetResourceProvider; @@ -577,6 +578,7 @@ public class AmbariServer { ClusterResourceProvider.init(injector.getInstance(BlueprintDAO.class), ambariMetaInfo, injector.getInstance(ConfigHelper.class)); AlertResourceProvider.init(injector); AlertDefinitionResourceProvider.init(injector); + AlertHistoryResourceProvider.init(injector); AlertGroupResourceProvider.init(injector); AlertSummaryPropertyProvider.init(injector); AlertTargetResourceProvider.init(injector); http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 5810633..cb6c271 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 @@ -151,12 +151,6 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc return new ValidationResourceProvider(propertyIds, keyPropertyIds, managementController); case Alert: return new AlertResourceProvider(propertyIds, keyPropertyIds, managementController); - case AlertDefinition: - return new AlertDefinitionResourceProvider(propertyIds, keyPropertyIds, managementController); - case AlertGroup: - return new AlertGroupResourceProvider(propertyIds, keyPropertyIds, managementController); - case AlertTarget: - return new AlertTargetResourceProvider(propertyIds, keyPropertyIds, managementController); case ClientConfig: return new ClientConfigResourceProvider(propertyIds, keyPropertyIds, managementController); default: http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 index 1de49a7..5d0a180 100644 --- 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 @@ -20,6 +20,7 @@ package org.apache.ambari.server.controller.internal; import java.util.ArrayList; import java.util.Arrays; import java.util.EnumSet; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -105,6 +106,35 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP private static ActionQueue actionQueue; /** + * The property ids for an alert defintion resource. + */ + private static final Set<String> PROPERTY_IDS = new HashSet<String>(); + + /** + * The key property ids for an alert definition resource. + */ + private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<Resource.Type, String>(); + + static { + // properties + PROPERTY_IDS.add(ALERT_DEF_CLUSTER_NAME); + PROPERTY_IDS.add(ALERT_DEF_SERVICE_NAME); + PROPERTY_IDS.add(ALERT_DEF_COMPONENT_NAME); + PROPERTY_IDS.add(ALERT_DEF_ID); + PROPERTY_IDS.add(ALERT_DEF_NAME); + PROPERTY_IDS.add(ALERT_DEF_LABEL); + PROPERTY_IDS.add(ALERT_DEF_INTERVAL); + PROPERTY_IDS.add(ALERT_DEF_ENABLED); + PROPERTY_IDS.add(ALERT_DEF_SCOPE); + PROPERTY_IDS.add(ALERT_DEF_SOURCE); + PROPERTY_IDS.add(ALERT_DEF_ACTION_RUN_NOW); + + // keys + KEY_PROPERTY_IDS.put(Resource.Type.AlertDefinition, ALERT_DEF_ID); + KEY_PROPERTY_IDS.put(Resource.Type.Cluster, ALERT_DEF_CLUSTER_NAME); + } + + /** * @param instance */ @Inject @@ -115,10 +145,13 @@ public class AlertDefinitionResourceProvider extends AbstractControllerResourceP actionQueue = injector.getInstance(ActionQueue.class); } - AlertDefinitionResourceProvider(Set<String> propertyIds, - Map<Resource.Type, String> keyPropertyIds, - AmbariManagementController managementController) { - super(propertyIds, keyPropertyIds, managementController); + /** + * Constructor. + * + * @param controller + */ + AlertDefinitionResourceProvider(AmbariManagementController controller) { + super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java index 8c55aa7..e3c93e0 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProvider.java @@ -21,6 +21,7 @@ import java.text.MessageFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -35,7 +36,6 @@ 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.Resource.Type; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; @@ -72,6 +72,30 @@ public class AlertGroupResourceProvider extends Arrays.asList(ALERT_GROUP_ID, ALERT_GROUP_CLUSTER_NAME)); /** + * The property ids for an alert group resource. + */ + private static final Set<String> PROPERTY_IDS = new HashSet<String>(); + + /** + * The key property ids for an alert group resource. + */ + private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<Resource.Type, String>(); + + static { + // properties + PROPERTY_IDS.add(ALERT_GROUP_ID); + PROPERTY_IDS.add(ALERT_GROUP_CLUSTER_NAME); + PROPERTY_IDS.add(ALERT_GROUP_NAME); + PROPERTY_IDS.add(ALERT_GROUP_DEFAULT); + PROPERTY_IDS.add(ALERT_GROUP_DEFINITIONS); + PROPERTY_IDS.add(ALERT_GROUP_TARGETS); + + // keys + KEY_PROPERTY_IDS.put(Resource.Type.AlertGroup, ALERT_GROUP_ID); + KEY_PROPERTY_IDS.put(Resource.Type.Cluster, ALERT_GROUP_CLUSTER_NAME); + } + + /** * Group/Target DAO */ private static AlertDispatchDAO s_dao; @@ -97,14 +121,10 @@ public class AlertGroupResourceProvider extends /** * Constructor. * - * @param propertyIds - * @param keyPropertyIds - * @param managementController + * @param controller */ - AlertGroupResourceProvider(Set<String> propertyIds, - Map<Type, String> keyPropertyIds, - AmbariManagementController managementController) { - super(propertyIds, keyPropertyIds, managementController); + AlertGroupResourceProvider(AmbariManagementController controller) { + super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProvider.java new file mode 100644 index 0000000..05ae105 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProvider.java @@ -0,0 +1,251 @@ +/** + * 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.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.ambari.server.AmbariException; +import org.apache.ambari.server.controller.AlertHistoryRequest; +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.AlertsDAO; +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; +import org.apache.ambari.server.orm.entities.AlertHistoryEntity; +import org.apache.ambari.server.state.Cluster; + +import com.google.inject.Inject; +import com.google.inject.Injector; + +/** + * ResourceProvider for Alert History + */ +public class AlertHistoryResourceProvider extends + AbstractControllerResourceProvider { + + public static final String ALERT_HISTORY = "AlertHistory"; + public static final String ALERT_HISTORY_DEFINITION_ID = "AlertHistory/definition_id"; + public static final String ALERT_HISTORY_DEFINITION_NAME = "AlertHistory/definition_name"; + public static final String ALERT_HISTORY_ID = "AlertHistory/id"; + public static final String ALERT_HISTORY_CLUSTER_NAME = "AlertHistory/cluster_name"; + public static final String ALERT_HISTORY_SERVICE_NAME = "AlertHistory/service_name"; + public static final String ALERT_HISTORY_COMPONENT_NAME = "AlertHistory/component_name"; + public static final String ALERT_HISTORY_HOSTNAME = "AlertHistory/host_name"; + public static final String ALERT_HISTORY_LABEL = "AlertHistory/label"; + public static final String ALERT_HISTORY_STATE = "AlertHistory/state"; + public static final String ALERT_HISTORY_TEXT = "AlertHistory/text"; + public static final String ALERT_HISTORY_TIMESTAMP = "AlertHistory/timestamp"; + public static final String ALERT_HISTORY_INSTANCE = "AlertHistory/instance"; + + private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>( + Arrays.asList(ALERT_HISTORY_ID)); + + /** + * Used for querying alert history. + */ + private static AlertsDAO s_dao = null; + + /** + * The property ids for an alert history resource. + */ + private static final Set<String> PROPERTY_IDS = new HashSet<String>(); + + /** + * The key property ids for an alert history resource. + */ + private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = + new HashMap<Resource.Type, String>(); + + static { + // properties + PROPERTY_IDS.add(ALERT_HISTORY_DEFINITION_ID); + PROPERTY_IDS.add(ALERT_HISTORY_DEFINITION_NAME); + PROPERTY_IDS.add(ALERT_HISTORY_ID); + PROPERTY_IDS.add(ALERT_HISTORY_CLUSTER_NAME); + PROPERTY_IDS.add(ALERT_HISTORY_SERVICE_NAME); + PROPERTY_IDS.add(ALERT_HISTORY_COMPONENT_NAME); + PROPERTY_IDS.add(ALERT_HISTORY_HOSTNAME); + PROPERTY_IDS.add(ALERT_HISTORY_LABEL); + PROPERTY_IDS.add(ALERT_HISTORY_STATE); + PROPERTY_IDS.add(ALERT_HISTORY_TEXT); + PROPERTY_IDS.add(ALERT_HISTORY_TIMESTAMP); + PROPERTY_IDS.add(ALERT_HISTORY_INSTANCE); + + // keys + KEY_PROPERTY_IDS.put(Resource.Type.AlertHistory, ALERT_HISTORY_ID); + KEY_PROPERTY_IDS.put(Resource.Type.Cluster, ALERT_HISTORY_CLUSTER_NAME); + } + + /** + * Static intializer for Guice. + * + * @param instance + */ + @Inject + public static void init(Injector injector) { + s_dao = injector.getInstance(AlertsDAO.class); + } + + /** + * Constructor. + * + * @param controller + */ + AlertHistoryResourceProvider(AmbariManagementController controller) { + super(PROPERTY_IDS, KEY_PROPERTY_IDS, controller); + } + + /** + * {@inheritDoc} + */ + @Override + protected Set<String> getPKPropertyIds() { + return PK_PROPERTY_IDS; + } + + /** + * {@inheritDoc} + */ + @Override + public RequestStatus createResources(Request request) throws SystemException, + UnsupportedPropertyException, ResourceAlreadyExistsException, + NoSuchParentResourceException { + throw new UnsupportedOperationException(); + } + + /** + * {@inheritDoc} + */ + @Override + public RequestStatus updateResources(Request request, Predicate predicate) + throws SystemException, UnsupportedPropertyException, + NoSuchResourceException, NoSuchParentResourceException { + throw new UnsupportedOperationException(); + } + + /** + * {@inheritDoc} + */ + @Override + public RequestStatus deleteResources(Predicate predicate) + throws SystemException, UnsupportedPropertyException, + NoSuchResourceException, NoSuchParentResourceException { + throw new UnsupportedOperationException(); + } + + /** + * {@inheritDoc} + */ + @Override + public Set<Resource> getResources(Request request, Predicate predicate) + throws SystemException, UnsupportedPropertyException, + NoSuchResourceException, NoSuchParentResourceException { + + Cluster cluster = null; + Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate); + Set<Resource> results = new LinkedHashSet<Resource>(); + + Set<Map<String, Object>> propertyMaps = getPropertyMaps(predicate); + for (Map<String, Object> propertyMap : propertyMaps) { + String clusterName = (String) propertyMap.get(ALERT_HISTORY_CLUSTER_NAME); + + if (null == clusterName || clusterName.isEmpty()) { + throw new IllegalArgumentException( + "Invalid argument, cluster name is required"); + } + + if (null == cluster) { + try { + cluster = getManagementController().getClusters().getCluster( + clusterName); + } catch (AmbariException e) { + throw new NoSuchResourceException( + "Parent Cluster resource doesn't exist", e); + } + } + + // if asking for a single ID, get that historical entry and continue + // the for-loop + String id = (String) propertyMap.get(ALERT_HISTORY_ID); + if (null != id) { + AlertHistoryEntity entity = s_dao.findById(Long.parseLong(id)); + if (null != entity) { + results.add(toResource(clusterName, entity, requestPropertyIds)); + continue; + } + } + + AlertHistoryRequest historyRequest = new AlertHistoryRequest(); + historyRequest.Predicate = predicate; + + List<AlertHistoryEntity> entities = s_dao.findAll(historyRequest); + for (AlertHistoryEntity entity : entities) { + results.add(toResource(cluster.getClusterName(), entity, + requestPropertyIds)); + } + } + + return results; + } + + /** + * Converts the {@link AlertHistoryEntity} to a {@link Resource}. + * + * @param clusterName + * the name of the cluster (not {@code null}). + * @param entity + * the entity to convert (not {@code null}). + * @param requestedIds + * the properties requested (not {@code null}). + * @return + */ + private Resource toResource(String clusterName, AlertHistoryEntity entity, + Set<String> requestedIds) { + AlertDefinitionEntity definition = entity.getAlertDefinition(); + + Resource resource = new ResourceImpl(Resource.Type.AlertHistory); + resource.setProperty(ALERT_HISTORY_ID, entity.getAlertId()); + + setResourceProperty(resource, ALERT_HISTORY_CLUSTER_NAME, clusterName, requestedIds); + setResourceProperty(resource, ALERT_HISTORY_DEFINITION_ID, definition.getDefinitionId(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_DEFINITION_NAME, definition.getDefinitionName(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_SERVICE_NAME, entity.getServiceName(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_COMPONENT_NAME, entity.getComponentName(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_HOSTNAME, entity.getHostName(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_LABEL, entity.getAlertLabel(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_STATE, entity.getAlertState(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_TEXT, entity.getAlertText(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_TIMESTAMP, entity.getAlertTimestamp(), requestedIds); + setResourceProperty(resource, ALERT_HISTORY_INSTANCE, entity.getAlertInstance(), requestedIds); + + return resource; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java index b0cc52b..5173c1b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java @@ -28,14 +28,12 @@ import java.util.Map.Entry; 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.Resource.Type; import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException; import org.apache.ambari.server.controller.spi.SystemException; import org.apache.ambari.server.controller.spi.UnsupportedPropertyException; @@ -55,7 +53,7 @@ import com.google.inject.Injector; * {@link AlertTargetEntity}. */ public class AlertTargetResourceProvider extends - AbstractControllerResourceProvider { + AbstractResourceProvider { protected static final String ALERT_TARGET = "AlertTarget"; protected static final String ALERT_TARGET_ID = "AlertTarget/id"; @@ -69,6 +67,29 @@ public class AlertTargetResourceProvider extends Arrays.asList(ALERT_TARGET_ID, ALERT_TARGET_NAME)); /** + * The property ids for an alert target resource. + */ + private static final Set<String> PROPERTY_IDS = new HashSet<String>(); + + /** + * The key property ids for an alert target resource. + */ + private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<Resource.Type, String>(); + + static { + // properties + PROPERTY_IDS.add(ALERT_TARGET_ID); + PROPERTY_IDS.add(ALERT_TARGET_NAME); + PROPERTY_IDS.add(ALERT_TARGET_DESCRIPTION); + PROPERTY_IDS.add(ALERT_TARGET_NOTIFICATION_TYPE); + PROPERTY_IDS.add(ALERT_TARGET_PROPERTIES); + PROPERTY_IDS.add(ALERT_TARGET_GROUPS); + + // keys + KEY_PROPERTY_IDS.put(Resource.Type.AlertTarget, ALERT_TARGET_ID); + } + + /** * Target DAO */ @Inject @@ -93,15 +114,9 @@ public class AlertTargetResourceProvider extends /** * Constructor. - * - * @param propertyIds - * @param keyPropertyIds - * @param managementController */ - AlertTargetResourceProvider(Set<String> propertyIds, - Map<Type, String> keyPropertyIds, - AmbariManagementController managementController) { - super(propertyIds, keyPropertyIds, managementController); + AlertTargetResourceProvider() { + super(PROPERTY_IDS, KEY_PROPERTY_IDS); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java index 23719d7..40bcb62 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java @@ -21,13 +21,14 @@ package org.apache.ambari.server.controller.internal; import java.util.Map; import java.util.Set; -import com.google.inject.Inject; import org.apache.ambari.server.controller.AmbariManagementController; import org.apache.ambari.server.controller.AmbariServer; import org.apache.ambari.server.controller.spi.Resource; import org.apache.ambari.server.controller.spi.ResourceProvider; import org.apache.ambari.server.controller.utilities.PropertyHelper; +import com.google.inject.Inject; + /** * The default provider module implementation. */ @@ -83,6 +84,15 @@ public class DefaultProviderModule extends AbstractProviderModule { return new LdapSyncEventResourceProvider(managementController); case UserPrivilege: return new UserPrivilegeResourceProvider(); + case AlertDefinition: + return new AlertDefinitionResourceProvider(managementController); + case AlertHistory: + return new AlertHistoryResourceProvider(managementController); + case AlertTarget: + return new AlertTargetResourceProvider(); + case AlertGroup: + return new AlertGroupResourceProvider(managementController); + default: return AbstractControllerResourceProvider.getResourceProvider(type, propertyIds, keyPropertyIds, managementController); http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 55d34c3..4fb8319 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 @@ -116,6 +116,7 @@ public interface Resource { Permission, Alert, AlertDefinition, + AlertHistory, AlertGroup, AlertTarget, AmbariPrivilege, @@ -202,6 +203,7 @@ public interface Resource { public static final Type Permission = InternalType.Permission.getType(); public static final Type Alert = InternalType.Alert.getType(); public static final Type AlertDefinition = InternalType.AlertDefinition.getType(); + public static final Type AlertHistory = InternalType.AlertHistory.getType(); public static final Type AlertGroup = InternalType.AlertGroup.getType(); public static final Type AlertTarget = InternalType.AlertTarget.getType(); public static final Type AmbariPrivilege = InternalType.AmbariPrivilege.getType(); http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 index f2161f3..8414765 100644 --- 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 @@ -24,10 +24,17 @@ import java.util.List; import javax.persistence.EntityManager; import javax.persistence.TypedQuery; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.metamodel.SingularAttribute; +import org.apache.ambari.server.api.query.JpaPredicateVisitor; +import org.apache.ambari.server.controller.AlertHistoryRequest; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.utilities.PredicateHelper; import org.apache.ambari.server.orm.RequiresSession; import org.apache.ambari.server.orm.entities.AlertCurrentEntity; import org.apache.ambari.server.orm.entities.AlertHistoryEntity; +import org.apache.ambari.server.orm.entities.AlertHistoryEntity_; import org.apache.ambari.server.state.AlertState; import org.apache.ambari.server.state.alert.Scope; import org.eclipse.persistence.config.HintValues; @@ -185,6 +192,33 @@ public class AlertsDAO { } /** + * Finds all {@link AlertHistoryEntity} that match the provided + * {@link AlertHistoryRequest}. This method will make JPA do the heavy lifting + * of providing a slice of the result set. + * + * @param request + * @return + */ + @Transactional + public List<AlertHistoryEntity> findAll(AlertHistoryRequest request) { + EntityManager entityManager = entityManagerProvider.get(); + + // convert the Ambari predicate into a JPA predicate + HistoryPredicateVisitor visitor = new HistoryPredicateVisitor(); + PredicateHelper.visit(request.Predicate, visitor); + + CriteriaQuery<AlertHistoryEntity> query = visitor.getCriteriaQuery(); + javax.persistence.criteria.Predicate jpaPredicate = visitor.getJpaPredicate(); + + if (null != jpaPredicate) { + query.where(jpaPredicate); + } + + TypedQuery<AlertHistoryEntity> typedQuery = entityManager.createQuery(query); + return daoUtils.selectList(typedQuery); + } + + /** * Gets the current alerts. * * @return the current alerts or an empty list if none exist (never @@ -537,4 +571,37 @@ public class AlertsDAO { query.setHint(QueryHints.REFRESH, HintValues.TRUE); return query; } + + /** + * The {@link HistoryPredicateVisitor} is used to convert an Ambari + * {@link Predicate} into a JPA {@link javax.persistence.criteria.Predicate}. + */ + private final class HistoryPredicateVisitor extends + JpaPredicateVisitor<AlertHistoryEntity> { + + /** + * Constructor. + * + */ + public HistoryPredicateVisitor() { + super(entityManagerProvider.get(), AlertHistoryEntity.class); + } + + /** + * {@inheritDoc} + */ + @Override + public Class<AlertHistoryEntity> getEntityClass() { + return AlertHistoryEntity.class; + } + + /** + * {@inheritDoc} + */ + @Override + public List<? extends SingularAttribute<?, ?>> getPredicateMapping( + String propertyId) { + return AlertHistoryEntity_.getPredicateMapping().get(propertyId); + } + } } http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 new file mode 100644 index 0000000..d2d4cf3 --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity_.java @@ -0,0 +1,50 @@ +/* + * 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.entities; + +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.metamodel.SetAttribute; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +import org.apache.ambari.server.state.alert.Scope; +import org.apache.ambari.server.state.alert.SourceType; + + +/** + * The {@link AlertDefinitionEntity_} is a strongly typed metamodel for creating + * {@link CriteriaQuery} for {@link AlertDefinitionEntity}. + */ +@StaticMetamodel(AlertDefinitionEntity.class) +public class AlertDefinitionEntity_ { + public static volatile SingularAttribute<AlertDefinitionEntity, Long> definitionId; + public static volatile SingularAttribute<AlertDefinitionEntity, String> source; + public static volatile SingularAttribute<AlertDefinitionEntity, Long> clusterId; + public static volatile SingularAttribute<AlertDefinitionEntity, ClusterEntity> clusterEntity; + public static volatile SingularAttribute<AlertDefinitionEntity, String> componentName; + public static volatile SingularAttribute<AlertDefinitionEntity, String> definitionName; + public static volatile SingularAttribute<AlertDefinitionEntity, String> label; + public static volatile SingularAttribute<AlertDefinitionEntity, Scope> scope; + public static volatile SingularAttribute<AlertDefinitionEntity, Integer> enabled; + public static volatile SingularAttribute<AlertDefinitionEntity, String> hash; + public static volatile SingularAttribute<AlertDefinitionEntity, Integer> scheduleInterval; + public static volatile SingularAttribute<AlertDefinitionEntity, String> serviceName; + public static volatile SingularAttribute<AlertDefinitionEntity, SourceType> sourceType; + public static volatile SetAttribute<AlertDefinitionEntity, AlertGroupEntity> alertGroups; +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 new file mode 100644 index 0000000..7b696fc --- /dev/null +++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertHistoryEntity_.java @@ -0,0 +1,94 @@ +/* + * 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.entities; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.metamodel.SingularAttribute; +import javax.persistence.metamodel.StaticMetamodel; + +import org.apache.ambari.server.controller.internal.AlertHistoryResourceProvider; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.state.AlertState; + + +/** + * The {@link AlertHistoryEntity_} is a strongly typed metamodel for creating + * {@link CriteriaQuery} for {@link AlertHistoryEntity}. + */ +@StaticMetamodel(AlertHistoryEntity.class) +public class AlertHistoryEntity_ { + public static volatile SingularAttribute<AlertHistoryEntity, Long> alertId; + public static volatile SingularAttribute<AlertHistoryEntity, String> alertInstance; + public static volatile SingularAttribute<AlertHistoryEntity, String> alertLabel; + public static volatile SingularAttribute<AlertHistoryEntity, AlertState> alertState; + public static volatile SingularAttribute<AlertHistoryEntity, String> alertText; + public static volatile SingularAttribute<AlertHistoryEntity, Long> alertTimestamp; + public static volatile SingularAttribute<AlertHistoryEntity, Long> clusterId; + public static volatile SingularAttribute<AlertHistoryEntity, String> componentName; + public static volatile SingularAttribute<AlertHistoryEntity, String> hostName; + public static volatile SingularAttribute<AlertHistoryEntity, String> serviceName; + public static volatile SingularAttribute<AlertHistoryEntity, AlertDefinitionEntity> alertDefinition; + + /** + * Gets a mapping of between a resource provider property, like + * {@link AlertHistoryResourceProvider#ALERT_HISTORY_SERVICE_NAME} to a + * metamodel {@link SingularAttribute}. + * <p/> + * This is used when converting an Ambari {@link Predicate} into a JPA + * {@link javax.persistence.criteria.Predicate} and we need a type-safe + * conversion between "category/property" and JPA field names. + * <p/> + * Multiple {@link SingularAttribute} instances can be chained together in + * order to provide an {@code entity.subEntity.field} reference. + * + * @return + */ + @SuppressWarnings("unchecked") + public static Map<String, List<? extends SingularAttribute<?, ?>>> getPredicateMapping() { + Map<String, List<? extends SingularAttribute<?, ?>>> mapping = new HashMap<String, List<? extends SingularAttribute<?, ?>>>(); + + mapping.put(AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME, + Collections.singletonList(serviceName)); + + mapping.put( + AlertHistoryResourceProvider.ALERT_HISTORY_COMPONENT_NAME, + Collections.singletonList(componentName)); + + mapping.put(AlertHistoryResourceProvider.ALERT_HISTORY_STATE, + Collections.singletonList(alertState)); + + mapping.put(AlertHistoryResourceProvider.ALERT_HISTORY_TIMESTAMP, + Collections.singletonList(alertTimestamp)); + + mapping.put(AlertHistoryResourceProvider.ALERT_HISTORY_HOSTNAME, + Collections.singletonList(hostName)); + + // AlertHistory.alertDefinition.definitionName = foo + mapping.put(AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_NAME, + Arrays.asList(alertDefinition, AlertDefinitionEntity_.definitionName)); + + return mapping; + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 085dc11..c1a6636 100644 --- a/ambari-server/src/main/resources/key_properties.json +++ b/ambari-server/src/main/resources/key_properties.json @@ -151,17 +151,6 @@ "Host": "Alert/host_name", "Alert": "Alert/id" }, - "AlertDefinition": { - "Cluster": "AlertDefinition/cluster_name", - "AlertDefinition": "AlertDefinition/id" - }, - "AlertTarget": { - "AlertTarget": "AlertTarget/id" - }, - "AlertGroup": { - "Cluster": "AlertGroup/cluster_name", - "AlertGroup": "AlertGroup/id" - }, "ClientConfig": { "Cluster": "ServiceComponentInfo/cluster_name", "Service": "ServiceComponentInfo/service_name", http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 8a0a58a..e9b967f 100644 --- a/ambari-server/src/main/resources/properties.json +++ b/ambari-server/src/main/resources/properties.json @@ -437,35 +437,6 @@ "Alert/service_name", "Alert/scope" ], - "AlertDefinition": [ - "AlertDefinition/cluster_name", - "AlertDefinition/service_name", - "AlertDefinition/component_name", - "AlertDefinition/id", - "AlertDefinition/name", - "AlertDefinition/label", - "AlertDefinition/interval", - "AlertDefinition/enabled", - "AlertDefinition/scope", - "AlertDefinition/source", - "AlertDefinition/run_now" - ], - "AlertGroup": [ - "AlertGroup/id", - "AlertGroup/name", - "AlertGroup/cluster_name", - "AlertGroup/default", - "AlertGroup/definitions", - "AlertGroup/targets" - ], - "AlertTarget": [ - "AlertTarget/id", - "AlertTarget/name", - "AlertTarget/description", - "AlertTarget/notification_type", - "AlertTarget/properties", - "AlertTarget/groups" - ], "ClientConfig":[ "ServiceComponentInfo/service_name", "ServiceComponentInfo/component_name", http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/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 index 78655dd..a28fe5f 100644 --- 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 @@ -451,10 +451,7 @@ public class AlertDefinitionResourceProviderTest { * @return */ private AlertDefinitionResourceProvider createProvider(AmbariManagementController amc) { - return new AlertDefinitionResourceProvider( - PropertyHelper.getPropertyIds(Resource.Type.AlertDefinition), - PropertyHelper.getKeyPropertyIds(Resource.Type.AlertDefinition), - amc); + return new AlertDefinitionResourceProvider(amc); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java index 771bf8a..9aad9a1 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertGroupResourceProviderTest.java @@ -528,9 +528,7 @@ public class AlertGroupResourceProviderTest { private AlertGroupResourceProvider createProvider( AmbariManagementController amc) { - return new AlertGroupResourceProvider( - PropertyHelper.getPropertyIds(Resource.Type.AlertGroup), - PropertyHelper.getKeyPropertyIds(Resource.Type.AlertGroup), amc); + return new AlertGroupResourceProvider(amc); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProviderTest.java new file mode 100644 index 0000000..2cf76dd --- /dev/null +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertHistoryResourceProviderTest.java @@ -0,0 +1,228 @@ +/** + * 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.easymock.EasyMock.anyObject; +import static org.easymock.EasyMock.createMock; +import static org.easymock.EasyMock.createStrictMock; +import static org.easymock.EasyMock.expect; +import static org.easymock.EasyMock.replay; +import static org.easymock.EasyMock.verify; +import static org.junit.Assert.assertEquals; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import org.apache.ambari.server.controller.AlertHistoryRequest; +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.metadata.ActionMetadata; +import org.apache.ambari.server.orm.InMemoryDefaultTestModule; +import org.apache.ambari.server.orm.dao.AlertsDAO; +import org.apache.ambari.server.orm.entities.AlertDefinitionEntity; +import org.apache.ambari.server.orm.entities.AlertHistoryEntity; +import org.apache.ambari.server.state.AlertState; +import org.apache.ambari.server.state.Cluster; +import org.apache.ambari.server.state.Clusters; +import org.easymock.EasyMock; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.google.inject.Binder; +import com.google.inject.Guice; +import com.google.inject.Injector; +import com.google.inject.Module; +import com.google.inject.util.Modules; + +/** + * {@link AlertHistoryResourceProvider} tests. + */ +public class AlertHistoryResourceProviderTest { + + private AlertsDAO m_dao = null; + private Injector m_injector; + + @Before + public void before() { + m_dao = createStrictMock(AlertsDAO.class); + + m_injector = Guice.createInjector(Modules.override( + new InMemoryDefaultTestModule()).with(new MockModule())); + + AlertHistoryResourceProvider.init(m_injector); + } + + /** + * @throws Exception + */ + @Test + public void testGetResourcesNoPredicate() throws Exception { + AlertHistoryResourceProvider provider = createProvider(null); + + Request request = PropertyHelper.getReadRequest( + "AlertHistory/cluster_name", "AlertHistory/id"); + + Set<Resource> results = provider.getResources(request, null); + assertEquals(0, results.size()); + } + + /** + * @throws Exception + */ + @Test + public void testGetResourcesClusterPredicate() throws Exception { + Request request = PropertyHelper.getReadRequest( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME, + AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_ID, + AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_NAME, + AlertHistoryResourceProvider.ALERT_HISTORY_COMPONENT_NAME, + AlertHistoryResourceProvider.ALERT_HISTORY_HOSTNAME, + AlertHistoryResourceProvider.ALERT_HISTORY_STATE); + + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); + expect(cluster.getClusterName()).andReturn("c1").atLeastOnce(); + + Predicate predicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME).equals("c1").toPredicate(); + + expect(m_dao.findAll(EasyMock.anyObject(AlertHistoryRequest.class))).andReturn( + getMockEntities()); + + replay(amc, clusters, cluster, m_dao); + + AlertHistoryResourceProvider provider = createProvider(amc); + Set<Resource> results = provider.getResources(request, predicate); + + assertEquals(1, results.size()); + + Resource r = results.iterator().next(); + + Assert.assertEquals( + "namenode_definition", + r.getPropertyValue(AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_NAME)); + + Assert.assertEquals(AlertState.WARNING, + r.getPropertyValue(AlertHistoryResourceProvider.ALERT_HISTORY_STATE)); + + verify(amc, clusters, cluster, m_dao); + } + + /** + * @throws Exception + */ + @Test + public void testGetSingleResource() throws Exception { + Request request = PropertyHelper.getReadRequest( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME, + AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_ID, + AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_NAME, + AlertHistoryResourceProvider.ALERT_HISTORY_COMPONENT_NAME, + AlertHistoryResourceProvider.ALERT_HISTORY_HOSTNAME, + AlertHistoryResourceProvider.ALERT_HISTORY_STATE); + + AmbariManagementController amc = createMock(AmbariManagementController.class); + Clusters clusters = createMock(Clusters.class); + Cluster cluster = createMock(Cluster.class); + expect(amc.getClusters()).andReturn(clusters).atLeastOnce(); + expect(clusters.getCluster((String) anyObject())).andReturn(cluster).atLeastOnce(); + expect(cluster.getClusterId()).andReturn(Long.valueOf(1)).anyTimes(); + + Predicate predicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME).equals("c1").and().property( + AlertHistoryResourceProvider.ALERT_HISTORY_ID).equals("1").toPredicate(); + + expect(m_dao.findById(1L)).andReturn(getMockEntities().get(0)); + + replay(amc, clusters, cluster, m_dao); + + AlertHistoryResourceProvider provider = createProvider(amc); + Set<Resource> results = provider.getResources(request, predicate); + + assertEquals(1, results.size()); + + Resource r = results.iterator().next(); + + Assert.assertEquals( + "namenode_definition", + r.getPropertyValue(AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_NAME)); + + Assert.assertEquals(AlertState.WARNING, + r.getPropertyValue(AlertHistoryResourceProvider.ALERT_HISTORY_STATE)); + } + + /** + * @param amc + * @return + */ + private AlertHistoryResourceProvider createProvider( + AmbariManagementController amc) { + return new AlertHistoryResourceProvider(amc); + } + + /** + * @return + */ + private List<AlertHistoryEntity> getMockEntities() throws Exception { + AlertDefinitionEntity definition = new AlertDefinitionEntity(); + definition.setClusterId(1L); + definition.setComponentName("NAMENODE"); + definition.setDefinitionName("namenode_definition"); + definition.setEnabled(true); + definition.setServiceName("HDFS"); + + AlertHistoryEntity entity = new AlertHistoryEntity(); + entity.setAlertId(1L); + entity.setAlertDefinition(definition); + entity.setClusterId(Long.valueOf(1L)); + entity.setComponentName(null); + entity.setAlertText("Mock Label"); + entity.setServiceName("HDFS"); + entity.setAlertState(AlertState.WARNING); + entity.setAlertTimestamp(System.currentTimeMillis()); + return Arrays.asList(entity); + } + + /** + * + */ + private class MockModule implements Module { + /** + * + */ + @Override + public void configure(Binder binder) { + binder.bind(AlertsDAO.class).toInstance(m_dao); + binder.bind(Clusters.class).toInstance( + EasyMock.createNiceMock(Clusters.class)); + binder.bind(Cluster.class).toInstance( + EasyMock.createNiceMock(Cluster.class)); + binder.bind(ActionMetadata.class); + } + } +} http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java index b96a4f3..282dfcc 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProviderTest.java @@ -317,9 +317,7 @@ public class AlertTargetResourceProviderTest { */ private AlertTargetResourceProvider createProvider( AmbariManagementController amc) { - return new AlertTargetResourceProvider( - PropertyHelper.getPropertyIds(Resource.Type.AlertTarget), - PropertyHelper.getKeyPropertyIds(Resource.Type.AlertTarget), amc); + return new AlertTargetResourceProvider(); } /** http://git-wip-us.apache.org/repos/asf/ambari/blob/03784eca/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java index a2023d8..c3da07f 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertsDAOTest.java @@ -37,6 +37,10 @@ import java.util.UUID; import junit.framework.Assert; +import org.apache.ambari.server.controller.AlertHistoryRequest; +import org.apache.ambari.server.controller.internal.AlertHistoryResourceProvider; +import org.apache.ambari.server.controller.spi.Predicate; +import org.apache.ambari.server.controller.utilities.PredicateBuilder; import org.apache.ambari.server.events.listeners.AlertMaintenanceModeListener; import org.apache.ambari.server.events.publishers.AmbariEventPublisher; import org.apache.ambari.server.orm.GuiceJpaInitializer; @@ -763,7 +767,171 @@ public class AlertsDAOTest { assertEquals(MaintenanceState.OFF, current.getMaintenanceState()); } } + } + + /** + * Tests that the Ambari {@link Predicate} can be converted and submitted to + * JPA correctly to return a restricted result set. + * + * @throws Exception + */ + @Test + public void testAlertHistoryPredicate() throws Exception { + Cluster cluster = initializeNewCluster(); + + // remove any definitions and start over + List<AlertDefinitionEntity> definitions = m_definitionDao.findAll(); + for (AlertDefinitionEntity definition : definitions) { + m_definitionDao.remove(definition); + } + + // create some definitions + AlertDefinitionEntity namenode = new AlertDefinitionEntity(); + namenode.setDefinitionName("NAMENODE"); + namenode.setServiceName("HDFS"); + namenode.setComponentName("NAMENODE"); + namenode.setClusterId(cluster.getClusterId()); + namenode.setHash(UUID.randomUUID().toString()); + namenode.setScheduleInterval(Integer.valueOf(60)); + namenode.setScope(Scope.ANY); + namenode.setSource("{\"type\" : \"SCRIPT\"}"); + namenode.setSourceType(SourceType.SCRIPT); + m_definitionDao.create(namenode); + + AlertDefinitionEntity datanode = new AlertDefinitionEntity(); + datanode.setDefinitionName("DATANODE"); + datanode.setServiceName("HDFS"); + datanode.setComponentName("DATANODE"); + datanode.setClusterId(cluster.getClusterId()); + datanode.setHash(UUID.randomUUID().toString()); + datanode.setScheduleInterval(Integer.valueOf(60)); + datanode.setScope(Scope.HOST); + datanode.setSource("{\"type\" : \"SCRIPT\"}"); + datanode.setSourceType(SourceType.SCRIPT); + m_definitionDao.create(datanode); + + AlertDefinitionEntity aggregate = new AlertDefinitionEntity(); + aggregate.setDefinitionName("YARN_AGGREGATE"); + aggregate.setServiceName("YARN"); + aggregate.setComponentName(null); + aggregate.setClusterId(cluster.getClusterId()); + aggregate.setHash(UUID.randomUUID().toString()); + aggregate.setScheduleInterval(Integer.valueOf(60)); + aggregate.setScope(Scope.SERVICE); + aggregate.setSource("{\"type\" : \"SCRIPT\"}"); + aggregate.setSourceType(SourceType.SCRIPT); + m_definitionDao.create(aggregate); + + // create some history + AlertHistoryEntity nnHistory = new AlertHistoryEntity(); + nnHistory.setAlertState(AlertState.OK); + nnHistory.setServiceName(namenode.getServiceName()); + nnHistory.setComponentName(namenode.getComponentName()); + nnHistory.setClusterId(cluster.getClusterId()); + nnHistory.setAlertDefinition(namenode); + nnHistory.setAlertLabel(namenode.getDefinitionName()); + nnHistory.setAlertText(namenode.getDefinitionName()); + nnHistory.setAlertTimestamp(calendar.getTimeInMillis()); + nnHistory.setHostName(HOSTNAME); + m_dao.create(nnHistory); + + AlertHistoryEntity dnHistory = new AlertHistoryEntity(); + dnHistory.setAlertState(AlertState.WARNING); + dnHistory.setServiceName(datanode.getServiceName()); + dnHistory.setComponentName(datanode.getComponentName()); + dnHistory.setClusterId(cluster.getClusterId()); + dnHistory.setAlertDefinition(datanode); + dnHistory.setAlertLabel(datanode.getDefinitionName()); + dnHistory.setAlertText(datanode.getDefinitionName()); + dnHistory.setAlertTimestamp(calendar.getTimeInMillis()); + dnHistory.setHostName(HOSTNAME); + m_dao.create(dnHistory); + + AlertHistoryEntity aggregateHistory = new AlertHistoryEntity(); + aggregateHistory.setAlertState(AlertState.CRITICAL); + aggregateHistory.setServiceName(aggregate.getServiceName()); + aggregateHistory.setComponentName(aggregate.getComponentName()); + aggregateHistory.setClusterId(cluster.getClusterId()); + aggregateHistory.setAlertDefinition(aggregate); + aggregateHistory.setAlertLabel(aggregate.getDefinitionName()); + aggregateHistory.setAlertText(aggregate.getDefinitionName()); + aggregateHistory.setAlertTimestamp(calendar.getTimeInMillis()); + m_dao.create(aggregateHistory); + + List<AlertHistoryEntity> histories = m_dao.findAll(); + assertEquals(3, histories.size()); + + Predicate clusterPredicate = null; + Predicate hdfsPredicate = null; + Predicate yarnPredicate = null; + Predicate clusterAndHdfsPredicate = null; + Predicate clusterAndHdfsAndCriticalPredicate = null; + Predicate hdfsAndCriticalOrWarningPredicate = null; + Predicate alertNamePredicate = null; + + clusterPredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME).equals("c1").toPredicate(); + + AlertHistoryRequest request = new AlertHistoryRequest(); + + request.Predicate = clusterPredicate; + histories = m_dao.findAll(request); + assertEquals(3, histories.size()); + + hdfsPredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME).equals("HDFS").toPredicate(); + + yarnPredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME).equals("YARN").toPredicate(); + + clusterAndHdfsPredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME).equals("c1").and().property( + AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME).equals("HDFS").toPredicate(); + + clusterAndHdfsPredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME).equals("c1").and().property( + AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME).equals("HDFS").toPredicate(); + + clusterAndHdfsAndCriticalPredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_CLUSTER_NAME).equals("c1").and().property( + AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME).equals("HDFS").and().property( + AlertHistoryResourceProvider.ALERT_HISTORY_STATE).equals( + AlertState.CRITICAL.name()).toPredicate(); + + hdfsAndCriticalOrWarningPredicate = new PredicateBuilder().begin().property( + AlertHistoryResourceProvider.ALERT_HISTORY_SERVICE_NAME).equals("HDFS").and().property( + AlertHistoryResourceProvider.ALERT_HISTORY_STATE).equals( + AlertState.CRITICAL.name()).end().or().property( + AlertHistoryResourceProvider.ALERT_HISTORY_STATE).equals( + AlertState.WARNING.name()).toPredicate(); + + alertNamePredicate = new PredicateBuilder().property( + AlertHistoryResourceProvider.ALERT_HISTORY_DEFINITION_NAME).equals( + "NAMENODE").toPredicate(); + + request.Predicate = hdfsPredicate; + histories = m_dao.findAll(request); + assertEquals(2, histories.size()); + + request.Predicate = yarnPredicate; + histories = m_dao.findAll(request); + assertEquals(1, histories.size()); + + request.Predicate = clusterAndHdfsPredicate; + histories = m_dao.findAll(request); + assertEquals(2, histories.size()); + + request.Predicate = clusterAndHdfsAndCriticalPredicate; + histories = m_dao.findAll(request); + assertEquals(0, histories.size()); + + request.Predicate = hdfsAndCriticalOrWarningPredicate; + histories = m_dao.findAll(request); + assertEquals(1, histories.size()); + request.Predicate = alertNamePredicate; + histories = m_dao.findAll(request); + assertEquals(1, histories.size()); } private Cluster initializeNewCluster() throws Exception {
