You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by yu...@apache.org on 2014/10/16 22:11:28 UTC
[04/51] [partial] AMBARI-7718. Rebase branch-windows-dev against
trunk. (Jayush Luniya and Florian Barca via yusaku)
http://git-wip-us.apache.org/repos/asf/ambari/blob/9213dcca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
new file mode 100644
index 0000000..f6b6082
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertResourceProvider.java
@@ -0,0 +1,191 @@
+/**
+ * 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.Collections;
+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.Resource;
+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.AlertCurrentEntity;
+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 instances
+ */
+public class AlertResourceProvider extends ReadOnlyResourceProvider {
+
+ protected static final String ALERT_CLUSTER_NAME = "Alert/cluster_name";
+ protected static final String ALERT_ID = "Alert/id";
+ protected static final String ALERT_NAME = "Alert/name";
+ protected static final String ALERT_LATEST_TIMESTAMP = "Alert/latest_timestamp";
+ protected static final String ALERT_MAINTENANCE_STATE = "Alert/maintenance_state";
+ protected static final String ALERT_ORIGINAL_TIMESTAMP = "Alert/original_timestamp";
+ protected static final String ALERT_INSTANCE = "Alert/instance";
+ protected static final String ALERT_LABEL = "Alert/label";
+ protected static final String ALERT_STATE = "Alert/state";
+ protected static final String ALERT_TEXT = "Alert/text";
+ protected static final String ALERT_COMPONENT = "Alert/component_name";
+ protected static final String ALERT_HOST = "Alert/host_name";
+ protected static final String ALERT_SERVICE = "Alert/service_name";
+ protected static final String ALERT_SCOPE = "Alert/scope";
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(
+ Arrays.asList(ALERT_ID, ALERT_NAME));
+
+ private static AlertsDAO alertsDAO = null;
+
+ /**
+ * @param injector the injector
+ */
+ @Inject
+ public static void init(Injector injector) {
+ alertsDAO = injector.getInstance(AlertsDAO.class);
+ }
+
+ AlertResourceProvider(Set<String> propertyIds,
+ Map<Resource.Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+
+ @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_CLUSTER_NAME);
+
+ if (null == clusterName || clusterName.isEmpty()) {
+ throw new IllegalArgumentException("Invalid argument, cluster name is required");
+ }
+
+ String id = (String) propertyMap.get(ALERT_ID);
+ if (null != id) {
+ AlertCurrentEntity entity = alertsDAO.findCurrentById(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);
+ }
+
+ String serviceName = (String) propertyMap.get(ALERT_SERVICE);
+ String hostName = (String) propertyMap.get(ALERT_HOST);
+
+ List<AlertCurrentEntity> entities = null;
+
+ if (null != hostName) {
+ entities = alertsDAO.findCurrentByHost(cluster.getClusterId(),
+ hostName);
+ } else if (null != serviceName) {
+ entities = alertsDAO.findCurrentByService(cluster.getClusterId(),
+ serviceName);
+ } else {
+ entities = alertsDAO.findCurrentByCluster(cluster.getClusterId());
+ }
+
+ if (null == entities)
+ entities = Collections.emptyList();
+
+ for (AlertCurrentEntity entity : entities) {
+ results.add(toResource(true, clusterName, entity, requestPropertyIds));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ /**
+ * Converts an entity to a resource.
+ *
+ * @param isCollection {@code true} if the response is for a collection
+ * @param clusterName the cluster name
+ * @param entity the entity
+ * @param requestedIds the requested ids
+ * @return the resource
+ */
+ private Resource toResource(boolean isCollection, String clusterName,
+ AlertCurrentEntity entity, Set<String> requestedIds) {
+ Resource resource = new ResourceImpl(Resource.Type.Alert);
+
+ setResourceProperty(resource, ALERT_CLUSTER_NAME, clusterName, requestedIds);
+ setResourceProperty(resource, ALERT_ID, entity.getAlertId(), requestedIds);
+ setResourceProperty(resource, ALERT_LATEST_TIMESTAMP, entity.getLatestTimestamp(), requestedIds);
+ setResourceProperty(resource, ALERT_MAINTENANCE_STATE, entity.getMaintenanceState(), requestedIds);
+ setResourceProperty(resource, ALERT_ORIGINAL_TIMESTAMP, entity.getOriginalTimestamp(), requestedIds);
+ setResourceProperty(resource, ALERT_TEXT, entity.getLatestText(), requestedIds);
+
+ AlertHistoryEntity history = entity.getAlertHistory();
+ setResourceProperty(resource, ALERT_INSTANCE, history.getAlertInstance(), requestedIds);
+ setResourceProperty(resource, ALERT_LABEL, history.getAlertLabel(), requestedIds);
+ setResourceProperty(resource, ALERT_STATE, history.getAlertState(), requestedIds);
+ setResourceProperty(resource, ALERT_COMPONENT, history.getComponentName(), requestedIds);
+ setResourceProperty(resource, ALERT_HOST, history.getHostName(), requestedIds);
+ setResourceProperty(resource, ALERT_SERVICE, history.getServiceName(), requestedIds);
+
+ AlertDefinitionEntity definition = history.getAlertDefinition();
+ setResourceProperty(resource, ALERT_NAME, definition.getDefinitionName(), requestedIds);
+ setResourceProperty(resource, ALERT_SCOPE, definition.getScope(), requestedIds);
+
+ if (isCollection) {
+ // !!! want name to be populated as if it were a PK when requesting the collection
+ resource.setProperty(ALERT_NAME, definition.getDefinitionName());
+ }
+
+ return resource;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9213dcca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.java
new file mode 100644
index 0000000..2e8661a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertSummaryPropertyProvider.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.controller.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.PropertyProvider;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.AlertSummaryDTO;
+import org.apache.ambari.server.orm.dao.AlertsDAO;
+import org.apache.ambari.server.state.AlertState;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Injector;
+
+/**
+ * Property provider that adds alert summary information to endpoints.
+ */
+public class AlertSummaryPropertyProvider extends BaseProvider implements PropertyProvider {
+
+ private final static Logger LOG = LoggerFactory.getLogger(AlertSummaryPropertyProvider.class);
+
+ private static Clusters s_clusters = null;
+ private static AlertsDAO s_dao = null;
+
+ private Resource.Type m_resourceType = null;
+ private String m_clusterPropertyId = null;
+ private String m_typeIdPropertyId = null;
+
+ AlertSummaryPropertyProvider(Resource.Type type,
+ String clusterPropertyId, String typeIdPropertyId) {
+ super(Collections.singleton("alerts_summary"));
+ m_resourceType = type;
+ m_clusterPropertyId = clusterPropertyId;
+ m_typeIdPropertyId = typeIdPropertyId;
+ }
+
+ public static void init(Injector injector) {
+ s_clusters = injector.getInstance(Clusters.class);
+ s_dao = injector.getInstance(AlertsDAO.class);
+ }
+
+ @Override
+ public Set<Resource> populateResources(Set<Resource> resources,
+ Request request, Predicate predicate) throws SystemException {
+
+ Set<String> propertyIds = getRequestPropertyIds(request, predicate);
+
+ try {
+ for (Resource res : resources) {
+ populateResource(res, propertyIds);
+ }
+ } catch (AmbariException e) {
+ LOG.error("Could not load built-in alerts - Executor exception ({})",
+ e.getMessage());
+ }
+
+ return resources;
+ }
+
+ private void populateResource(Resource resource, Set<String> requestedIds) throws AmbariException {
+
+ AlertSummaryDTO summary = null;
+
+ String clusterName = (String) resource.getPropertyValue(m_clusterPropertyId);
+
+ if (null == clusterName)
+ return;
+
+ String typeId = null == m_typeIdPropertyId ? null : (String) resource.getPropertyValue(m_typeIdPropertyId);
+ Cluster cluster = s_clusters.getCluster(clusterName);
+
+ switch (m_resourceType.getInternalType()) {
+ case Cluster:
+ summary = s_dao.findCurrentCounts(cluster.getClusterId(), null, null);
+ break;
+ case Service:
+ summary = s_dao.findCurrentCounts(cluster.getClusterId(), typeId, null);
+ break;
+ case Host:
+ summary = s_dao.findCurrentCounts(cluster.getClusterId(), null, typeId);
+ break;
+ default:
+ break;
+ }
+
+ if (null != summary) {
+ Map<AlertState, Integer> map = new HashMap<AlertState, Integer>();
+ map.put(AlertState.OK, Integer.valueOf(summary.getOkCount()));
+ map.put(AlertState.WARNING, Integer.valueOf(summary.getWarningCount()));
+ map.put(AlertState.CRITICAL, Integer.valueOf(summary.getCriticalCount()));
+ map.put(AlertState.UNKNOWN, Integer.valueOf(summary.getUnknownCount()));
+
+ setResourceProperty(resource, "alerts_summary", map, requestedIds);
+ }
+
+ }
+
+ @Override
+ public Set<String> checkPropertyIds(Set<String> propertyIds) {
+ Set<String> rejects = new HashSet<String>();
+
+ for (String id : propertyIds) {
+ if (!id.startsWith("alerts_summary"))
+ rejects.add(id);
+ }
+
+ return rejects;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9213dcca/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
new file mode 100644
index 0000000..5173c1b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AlertTargetResourceProvider.java
@@ -0,0 +1,384 @@
+/**
+ * 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.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+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.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.dao.AlertDispatchDAO;
+import org.apache.ambari.server.orm.entities.AlertTargetEntity;
+import org.apache.ambari.server.state.alert.AlertTarget;
+import org.apache.commons.lang.StringUtils;
+
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+
+/**
+ * The {@link AlertTargetResourceProvider} class deals with managing the CRUD
+ * operations for {@link AlertTarget}, including property coercion to and from
+ * {@link AlertTargetEntity}.
+ */
+public class AlertTargetResourceProvider extends
+ AbstractResourceProvider {
+
+ protected static final String ALERT_TARGET = "AlertTarget";
+ protected static final String ALERT_TARGET_ID = "AlertTarget/id";
+ protected static final String ALERT_TARGET_NAME = "AlertTarget/name";
+ protected static final String ALERT_TARGET_DESCRIPTION = "AlertTarget/description";
+ protected static final String ALERT_TARGET_NOTIFICATION_TYPE = "AlertTarget/notification_type";
+ protected static final String ALERT_TARGET_PROPERTIES = "AlertTarget/properties";
+ protected static final String ALERT_TARGET_GROUPS = "AlertTarget/groups";
+
+ private static final Set<String> PK_PROPERTY_IDS = new HashSet<String>(
+ 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
+ private static AlertDispatchDAO s_dao;
+
+ /**
+ * Used for serializationa and deserialization of some fields.
+ */
+ private static final Gson s_gson = new Gson();
+
+ /**
+ * Initializes the injectable members of this class with the specified
+ * injector.
+ *
+ * @param injector
+ * the injector (not {@code null}).
+ */
+ @Inject
+ public static void init(Injector injector) {
+ s_dao = injector.getInstance(AlertDispatchDAO.class);
+ }
+
+ /**
+ * Constructor.
+ */
+ AlertTargetResourceProvider() {
+ super(PROPERTY_IDS, KEY_PROPERTY_IDS);
+ }
+
+ @Override
+ public RequestStatus createResources(final Request request)
+ throws SystemException,
+ UnsupportedPropertyException, ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ createResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ createAlertTargets(request.getProperties());
+ return null;
+ }
+ });
+
+ notifyCreate(Resource.Type.AlertTarget, request);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> results = new HashSet<Resource>();
+ Set<String> requestPropertyIds = getRequestPropertyIds(request, predicate);
+
+ if( null == predicate ){
+ List<AlertTargetEntity> entities = s_dao.findAllTargets();
+ for (AlertTargetEntity entity : entities) {
+ results.add(toResource(true, entity, requestPropertyIds));
+ }
+ } else {
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ String id = (String) propertyMap.get(ALERT_TARGET_ID);
+ if (null == id) {
+ continue;
+ }
+
+ AlertTargetEntity entity = s_dao.findTargetById(Long.parseLong(id));
+ if (null != entity) {
+ results.add(toResource(false, entity, requestPropertyIds));
+ }
+ }
+ }
+
+ return results;
+ }
+
+ @Override
+ public RequestStatus updateResources(final Request request,
+ Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ updateAlertTargets(request.getProperties());
+ return null;
+ }
+ });
+
+ notifyUpdate(Resource.Type.AlertTarget, request, predicate);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate)
+ throws SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ Set<Resource> resources = getResources(new RequestImpl(null, null, null,
+ null), predicate);
+
+ Set<Long> targetIds = new HashSet<Long>();
+
+ for (final Resource resource : resources) {
+ Long id = (Long) resource.getPropertyValue(ALERT_TARGET_ID);
+ targetIds.add(id);
+ }
+
+ for (Long targetId : targetIds) {
+ LOG.info("Deleting alert target {}", targetId);
+
+ final AlertTargetEntity entity = s_dao.findTargetById(targetId.longValue());
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ s_dao.remove(entity);
+ return null;
+ }
+ });
+ }
+
+ notifyDelete(Resource.Type.AlertTarget, predicate);
+ return getRequestStatus(null);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return PK_PROPERTY_IDS;
+ }
+
+ /**
+ * Create and persist {@link AlertTargetEntity} from the map of properties.
+ *
+ * @param requestMaps
+ * @throws AmbariException
+ */
+ private void createAlertTargets(Set<Map<String, Object>> requestMaps)
+ throws AmbariException {
+ List<AlertTargetEntity> entities = new ArrayList<AlertTargetEntity>();
+ for (Map<String, Object> requestMap : requestMaps) {
+ AlertTargetEntity entity = new AlertTargetEntity();
+
+ String name = (String) requestMap.get(ALERT_TARGET_NAME);
+ String description = (String) requestMap.get(ALERT_TARGET_DESCRIPTION);
+ String notificationType = (String) requestMap.get(ALERT_TARGET_NOTIFICATION_TYPE);
+
+ if (StringUtils.isEmpty(name)) {
+ throw new IllegalArgumentException(
+ "The name of the alert target is required.");
+ }
+
+ if (StringUtils.isEmpty(notificationType)) {
+ throw new IllegalArgumentException(
+ "The type of the alert target is required.");
+ }
+
+ String properties = extractProperties(requestMap);
+ if (StringUtils.isEmpty(properties)) {
+ throw new IllegalArgumentException(
+ "Alert targets must be created with their connection properties");
+ }
+
+ entity.setDescription(description);
+ entity.setNotificationType(notificationType);
+ entity.setProperties(properties);
+ entity.setTargetName(name);
+
+ entities.add(entity);
+ }
+
+ s_dao.createTargets(entities);
+ }
+
+ /**
+ * Updates existing {@link AlertTargetEntity}s with the specified properties.
+ *
+ * @param requestMaps
+ * a set of property maps, one map for each entity.
+ * @throws AmbariException
+ * if the entity could not be found.
+ */
+ private void updateAlertTargets(Set<Map<String, Object>> requestMaps)
+ throws AmbariException {
+
+ for (Map<String, Object> requestMap : requestMaps) {
+ String stringId = (String) requestMap.get(ALERT_TARGET_ID);
+
+ if (StringUtils.isEmpty(stringId)) {
+ throw new IllegalArgumentException(
+ "The ID of the alert target is required when updating an existing target");
+ }
+
+ long id = Long.parseLong(stringId);
+ AlertTargetEntity entity = s_dao.findTargetById(id);
+
+ if (null == entity) {
+ String message = MessageFormat.format(
+ "The alert target with ID {0} could not be found", id);
+ throw new AmbariException(message);
+ }
+
+ String name = (String) requestMap.get(ALERT_TARGET_NAME);
+ String description = (String) requestMap.get(ALERT_TARGET_DESCRIPTION);
+ String notificationType = (String) requestMap.get(ALERT_TARGET_NOTIFICATION_TYPE);
+
+ if (!StringUtils.isBlank(name)) {
+ entity.setTargetName(name);
+ }
+
+ if (null != description) {
+ entity.setDescription(description);
+ }
+
+ if (!StringUtils.isBlank(notificationType)) {
+ entity.setNotificationType(notificationType);
+ }
+
+ String properties = extractProperties(requestMap);
+ if (!StringUtils.isEmpty(properties)) {
+ entity.setProperties(properties);
+ }
+
+ s_dao.merge(entity);
+ }
+ }
+
+ /**
+ * Convert the given {@link AlertTargetEntity} to a {@link Resource}.
+ *
+ * @param isCollection
+ * {@code true} if the resource is part of a collection. Some
+ * properties are not returned when a collection of targets is
+ * requested.
+ * @param entity
+ * the entity to convert.
+ * @param requestedIds
+ * the properties that were requested or {@code null} for all.
+ * @return the resource representation of the entity (never {@code null}).
+ */
+ private Resource toResource(boolean isCollection, AlertTargetEntity entity,
+ Set<String> requestedIds) {
+
+ Resource resource = new ResourceImpl(Resource.Type.AlertTarget);
+ resource.setProperty(ALERT_TARGET_ID, entity.getTargetId());
+ resource.setProperty(ALERT_TARGET_NAME, entity.getTargetName());
+
+ resource.setProperty(ALERT_TARGET_DESCRIPTION, entity.getDescription());
+ resource.setProperty(ALERT_TARGET_NOTIFICATION_TYPE,
+ entity.getNotificationType());
+
+ if (!isCollection) {
+ String properties = entity.getProperties();
+ Map<String, String> map = s_gson.<Map<String, String>> fromJson(
+ properties,
+ Map.class);
+
+ resource.setProperty(ALERT_TARGET_PROPERTIES, map);
+ }
+
+ return resource;
+ }
+
+ /**
+ * Looks through the flat list of propery keys in the supplied map and builds
+ * a JSON string of key:value pairs for the {@link #ALERT_TARGET_PROPERTIES}
+ * key.
+ *
+ * @param requestMap
+ * the map of flattened properties (not {@code null}).
+ * @return the JSON representing the key/value pairs of all properties, or
+ * {@code null} if none.
+ */
+ private String extractProperties( Map<String, Object> requestMap ){
+ Map<String, Object> normalizedMap = new HashMap<String, Object>(
+ requestMap.size());
+
+ for (Entry<String, Object> entry : requestMap.entrySet()) {
+ String key = entry.getKey();
+ String propCat = PropertyHelper.getPropertyCategory(key);
+
+ if (propCat.equals(ALERT_TARGET_PROPERTIES)) {
+ String propKey = PropertyHelper.getPropertyName(key);
+ normalizedMap.put(propKey, entry.getValue());
+ }
+ }
+
+ return s_gson.toJson(normalizedMap);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9213dcca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProvider.java
new file mode 100644
index 0000000..f4839e9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariPrivilegeResourceProvider.java
@@ -0,0 +1,174 @@
+/**
+ * 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 privileges and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.orm.dao.ClusterDAO;
+import org.apache.ambari.server.orm.entities.ClusterEntity;
+import org.apache.ambari.server.orm.entities.GroupEntity;
+import org.apache.ambari.server.orm.entities.PrivilegeEntity;
+import org.apache.ambari.server.orm.entities.ResourceEntity;
+import org.apache.ambari.server.orm.entities.ResourceTypeEntity;
+import org.apache.ambari.server.orm.entities.UserEntity;
+import org.apache.ambari.server.orm.entities.ViewEntity;
+import org.apache.ambari.server.orm.entities.ViewInstanceEntity;
+import org.apache.ambari.server.view.ViewRegistry;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.ambari.server.controller.internal.ClusterPrivilegeResourceProvider.PRIVILEGE_CLUSTER_NAME_PROPERTY_ID;
+import static org.apache.ambari.server.controller.internal.ViewPrivilegeResourceProvider.PRIVILEGE_INSTANCE_NAME_PROPERTY_ID;
+import static org.apache.ambari.server.controller.internal.ViewPrivilegeResourceProvider.PRIVILEGE_VIEW_NAME_PROPERTY_ID;
+import static org.apache.ambari.server.controller.internal.ViewPrivilegeResourceProvider.PRIVILEGE_VIEW_VERSION_PROPERTY_ID;
+
+/**
+ * Resource provider for Ambari privileges.
+ */
+public class AmbariPrivilegeResourceProvider extends PrivilegeResourceProvider<Object> {
+
+ public static final String PRIVILEGE_TYPE_PROPERTY_ID = "PrivilegeInfo/type";
+
+ /**
+ * Data access object used to obtain privilege entities.
+ */
+ protected static ClusterDAO clusterDAO;
+
+ /**
+ * The property ids for an Ambari privilege resource.
+ */
+ private static Set<String> propertyIds = new HashSet<String>();
+ static {
+ propertyIds.add(PRIVILEGE_ID_PROPERTY_ID);
+ propertyIds.add(PERMISSION_NAME_PROPERTY_ID);
+ propertyIds.add(PRINCIPAL_NAME_PROPERTY_ID);
+ propertyIds.add(PRINCIPAL_TYPE_PROPERTY_ID);
+ propertyIds.add(PRIVILEGE_VIEW_NAME_PROPERTY_ID);
+ propertyIds.add(PRIVILEGE_VIEW_VERSION_PROPERTY_ID);
+ propertyIds.add(PRIVILEGE_INSTANCE_NAME_PROPERTY_ID);
+ propertyIds.add(PRIVILEGE_CLUSTER_NAME_PROPERTY_ID);
+ propertyIds.add(PRIVILEGE_TYPE_PROPERTY_ID);
+
+ }
+
+ /**
+ * The key property ids for a privilege resource.
+ */
+ private static Map<Resource.Type, String> keyPropertyIds = new HashMap<Resource.Type, String>();
+ static {
+ keyPropertyIds.put(Resource.Type.AmbariPrivilege, PRIVILEGE_ID_PROPERTY_ID);
+ }
+
+
+ // ----- Constructors ------------------------------------------------------
+
+ /**
+ * Construct an AmbariPrivilegeResourceProvider.
+ */
+ public AmbariPrivilegeResourceProvider() {
+ super(propertyIds, keyPropertyIds, Resource.Type.AmbariPrivilege);
+ }
+
+ // ----- AmbariPrivilegeResourceProvider ---------------------------------
+
+ /**
+ * Static initialization.
+ *
+ * @param clusterDao the cluster data access object
+ */
+ public static void init(ClusterDAO clusterDao) {
+ clusterDAO = clusterDao;
+ }
+
+ // ----- AbstractResourceProvider ------------------------------------------
+
+ @Override
+ public Map<Resource.Type, String> getKeyPropertyIds() {
+ return keyPropertyIds;
+ }
+
+
+ // ----- PrivilegeResourceProvider -----------------------------------------
+
+ @Override
+ public Map<Long, Object> getResourceEntities(Map<String, Object> properties) {
+ Map<Long, Object> resourceEntities = new HashMap<Long, Object>();
+
+ resourceEntities.put(ResourceEntity.AMBARI_RESOURCE_ID, null);
+ // add cluster entities
+ List<ClusterEntity> clusterEntities = clusterDAO.findAll();
+
+ if (clusterEntities != null) {
+ for (ClusterEntity clusterEntity : clusterEntities) {
+ resourceEntities.put(clusterEntity.getResource().getId(), clusterEntity);
+ }
+ }
+ //add view entities
+ ViewRegistry viewRegistry = ViewRegistry.getInstance();
+ for (ViewEntity viewEntity : viewRegistry.getDefinitions()) {
+ if (viewEntity.isDeployed()) {
+ for (ViewInstanceEntity viewInstanceEntity : viewEntity.getInstances()) {
+ resourceEntities.put(viewInstanceEntity.getResource().getId(), viewInstanceEntity);
+ }
+ }
+ }
+ return resourceEntities;
+ }
+
+ @Override
+ protected Resource toResource(PrivilegeEntity privilegeEntity,
+ Map<Long, UserEntity> userEntities,
+ Map<Long, GroupEntity> groupEntities,
+ Map<Long, Object> resourceEntities, Set<String> requestedIds) {
+ Resource resource = super.toResource(privilegeEntity, userEntities, groupEntities, resourceEntities, requestedIds);
+ if (resource != null) {
+ ResourceEntity resourceEntity = privilegeEntity.getResource();
+ ResourceTypeEntity type = resourceEntity.getResourceType();
+ String privilegeType;
+ switch (type.getId()) {
+ case ResourceTypeEntity.CLUSTER_RESOURCE_TYPE:
+ ClusterEntity clusterEntity = (ClusterEntity) resourceEntities.get(resourceEntity.getId());
+ privilegeType = ResourceTypeEntity.CLUSTER_RESOURCE_TYPE_NAME;
+ setResourceProperty(resource, PRIVILEGE_CLUSTER_NAME_PROPERTY_ID, clusterEntity.getClusterName(), requestedIds);
+ break;
+ case ResourceTypeEntity.AMBARI_RESOURCE_TYPE:
+ privilegeType = ResourceTypeEntity.AMBARI_RESOURCE_TYPE_NAME;
+ break;
+ default:
+ privilegeType = ResourceTypeEntity.VIEW_RESOURCE_TYPE_NAME;
+ ViewInstanceEntity viewInstanceEntity = (ViewInstanceEntity) resourceEntities.get(resourceEntity.getId());
+ ViewEntity viewEntity = viewInstanceEntity.getViewEntity();
+
+ setResourceProperty(resource, PRIVILEGE_VIEW_NAME_PROPERTY_ID, viewEntity.getCommonName(), requestedIds);
+ setResourceProperty(resource, PRIVILEGE_VIEW_VERSION_PROPERTY_ID, viewEntity.getVersion(), requestedIds);
+ setResourceProperty(resource, PRIVILEGE_INSTANCE_NAME_PROPERTY_ID, viewInstanceEntity.getName(), requestedIds);
+ break;
+ }
+ setResourceProperty(resource, PRIVILEGE_TYPE_PROPERTY_ID, privilegeType, requestedIds);
+ }
+ return resource;
+ }
+ @Override
+ public Long getResourceEntityId(Predicate predicate) {
+ return ResourceEntity.AMBARI_RESOURCE_ID;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9213dcca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
index 800ff3b..0cd8a9f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseBlueprintProcessor.java
@@ -19,12 +19,14 @@
package org.apache.ambari.server.controller.internal;
import com.google.gson.Gson;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.StackAccessException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.StackConfigurationRequest;
import org.apache.ambari.server.controller.StackConfigurationResponse;
+import org.apache.ambari.server.controller.StackLevelConfigurationRequest;
import org.apache.ambari.server.controller.StackServiceComponentRequest;
import org.apache.ambari.server.controller.StackServiceComponentResponse;
import org.apache.ambari.server.controller.StackServiceRequest;
@@ -38,7 +40,9 @@ import org.apache.ambari.server.orm.entities.HostGroupComponentEntity;
import org.apache.ambari.server.orm.entities.HostGroupConfigEntity;
import org.apache.ambari.server.orm.entities.HostGroupEntity;
import org.apache.ambari.server.state.AutoDeployInfo;
+import org.apache.ambari.server.state.ConfigHelper;
import org.apache.ambari.server.state.DependencyInfo;
+import org.apache.ambari.server.state.PropertyInfo;
import java.util.Collection;
import java.util.Collections;
@@ -64,6 +68,8 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
*/
protected static AmbariMetaInfo stackInfo;
+ protected static ConfigHelper configHelper;
+
protected BaseBlueprintProcessor(Set<String> propertyIds,
Map<Resource.Type, String> keyPropertyIds,
@@ -80,9 +86,9 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
*
* @return collection of host groups which contain the specified component
*/
- protected Collection<HostGroup> getHostGroupsForComponent(String component, Collection<HostGroup> hostGroups) {
- Collection<HostGroup> resultGroups = new HashSet<HostGroup>();
- for (HostGroup group : hostGroups ) {
+ protected Collection<HostGroupImpl> getHostGroupsForComponent(String component, Collection<HostGroupImpl> hostGroups) {
+ Collection<HostGroupImpl> resultGroups = new HashSet<HostGroupImpl>();
+ for (HostGroupImpl group : hostGroups ) {
if (group.getComponents().contains(component)) {
resultGroups.add(group);
}
@@ -98,11 +104,11 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
*
* @return map of host group name to host group
*/
- protected Map<String, HostGroup> parseBlueprintHostGroups(BlueprintEntity blueprint, Stack stack) {
- Map<String, HostGroup> mapHostGroups = new HashMap<String, HostGroup>();
+ protected Map<String, HostGroupImpl> parseBlueprintHostGroups(BlueprintEntity blueprint, Stack stack) {
+ Map<String, HostGroupImpl> mapHostGroups = new HashMap<String, HostGroupImpl>();
for (HostGroupEntity hostGroup : blueprint.getHostGroups()) {
- mapHostGroups.put(hostGroup.getName(), new HostGroup(hostGroup, stack));
+ mapHostGroups.put(hostGroup.getName(), new HostGroupImpl(hostGroup, stack, this));
}
return mapHostGroups;
}
@@ -119,7 +125,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
protected Stack parseStack(BlueprintEntity blueprint) throws SystemException {
Stack stack;
try {
- stack = new Stack(blueprint.getStackName(), blueprint.getStackVersion());
+ stack = new Stack(blueprint.getStackName(), blueprint.getStackVersion(), getManagementController());
} catch (StackAccessException e) {
throw new IllegalArgumentException("Invalid stack information provided for cluster. " +
"stack name: " + blueprint.getStackName() +
@@ -144,15 +150,15 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @throws IllegalArgumentException when validation fails
*/
protected BlueprintEntity validateTopology(BlueprintEntity blueprint) throws AmbariException {
- Stack stack = new Stack(blueprint.getStackName(), blueprint.getStackVersion());
- Map<String, HostGroup> hostGroupMap = parseBlueprintHostGroups(blueprint, stack);
- Collection<HostGroup> hostGroups = hostGroupMap.values();
+ Stack stack = new Stack(blueprint.getStackName(), blueprint.getStackVersion(), getManagementController());
+ Map<String, HostGroupImpl> hostGroupMap = parseBlueprintHostGroups(blueprint, stack);
+ Collection<HostGroupImpl> hostGroups = hostGroupMap.values();
Map<String, Map<String, String>> clusterConfig = processBlueprintConfigurations(blueprint, null);
Map<String, Map<String, Collection<DependencyInfo>>> missingDependencies =
new HashMap<String, Map<String, Collection<DependencyInfo>>>();
Collection<String> services = getTopologyServices(hostGroups);
- for (HostGroup group : hostGroups) {
+ for (HostGroupImpl group : hostGroups) {
Map<String, Collection<DependencyInfo>> missingGroupDependencies =
group.validateTopology(hostGroups, services, clusterConfig);
if (! missingGroupDependencies.isEmpty()) {
@@ -206,6 +212,33 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
}
/**
+ * Process cluster scoped configuration attributes contained in blueprint.
+ *
+ * @param blueprint blueprint entity
+ *
+ * @return cluster scoped property attributes contained within in blueprint
+ */
+ protected Map<String, Map<String, Map<String, String>>> processBlueprintAttributes(BlueprintEntity blueprint) {
+
+ Map<String, Map<String, Map<String, String>>> mapAttributes =
+ new HashMap<String, Map<String, Map<String, String>>>();
+ Collection<BlueprintConfigEntity> configs = blueprint.getConfigurations();
+
+ if (configs != null) {
+ Gson gson = new Gson();
+ for (BlueprintConfigEntity config : configs) {
+ Map<String, Map<String, String>> typeAttrs =
+ gson.<Map<String, Map<String, String>>>fromJson(config.getConfigAttributes(), Map.class);
+ if (typeAttrs != null && !typeAttrs.isEmpty()) {
+ mapAttributes.put(config.getType(), typeAttrs);
+ }
+ }
+ }
+
+ return mapAttributes;
+ }
+
+ /**
* Override existing properties or add new.
*
* @param existingProperties current property values
@@ -280,9 +313,9 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
*
* @return collections of all services provided by topology
*/
- protected Collection<String> getTopologyServices(Collection<HostGroup> hostGroups) {
+ protected Collection<String> getTopologyServices(Collection<HostGroupImpl> hostGroups) {
Collection<String> services = new HashSet<String>();
- for (HostGroup group : hostGroups) {
+ for (HostGroupImpl group : hostGroups) {
services.addAll(group.getServices());
}
return services;
@@ -328,7 +361,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @return collection of missing component information
*/
private Collection<String> verifyComponentCardinalityCount(BlueprintEntity blueprint,
- Collection<HostGroup> hostGroups,
+ Collection<HostGroupImpl> hostGroups,
String component,
Cardinality cardinality,
AutoDeployInfo autoDeploy,
@@ -343,11 +376,11 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
if (! validated && autoDeploy != null && autoDeploy.isEnabled() && cardinality.supportsAutoDeploy()) {
String coLocateName = autoDeploy.getCoLocate();
if (coLocateName != null && ! coLocateName.isEmpty()) {
- Collection<HostGroup> coLocateHostGroups = getHostGroupsForComponent(
+ Collection<HostGroupImpl> coLocateHostGroups = getHostGroupsForComponent(
coLocateName.split("/")[1], hostGroups);
if (! coLocateHostGroups.isEmpty()) {
validated = true;
- HostGroup group = coLocateHostGroups.iterator().next();
+ HostGroupImpl group = coLocateHostGroups.iterator().next();
if (group.addComponent(component)) {
addComponentToBlueprint(blueprint, group.getEntity().getName(), component);
}
@@ -374,7 +407,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @return collection of missing component information
*/
private Collection<String> verifyComponentInAllHostGroups(BlueprintEntity blueprint,
- Collection<HostGroup> hostGroups,
+ Collection<HostGroupImpl> hostGroups,
String component,
AutoDeployInfo autoDeploy) {
@@ -382,7 +415,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
int actualCount = getHostGroupsForComponent(component, hostGroups).size();
if (actualCount != hostGroups.size()) {
if (autoDeploy != null && autoDeploy.isEnabled()) {
- for (HostGroup group : hostGroups) {
+ for (HostGroupImpl group : hostGroups) {
if (group.addComponent(component)) {
addComponentToBlueprint(blueprint, group.getEntity().getName(), component);
}
@@ -424,7 +457,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
/**
* Encapsulates stack information.
*/
- protected class Stack {
+ protected static class Stack {
/**
* Stack name
*/
@@ -480,8 +513,44 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
/**
* Map of service to config type properties
*/
- private Map<String, Map<String, Map<String, String>>> serviceConfigurations =
- new HashMap<String, Map<String, Map<String, String>>>();
+ private Map<String, Map<String, Map<String, ConfigProperty>>> serviceConfigurations =
+ new HashMap<String, Map<String, Map<String, ConfigProperty>>>();
+
+
+ /**
+ * Ambari Management Controller, used to obtain Stack definitions
+ */
+ private final AmbariManagementController ambariManagementController;
+
+ /**
+ * Contains a configuration property's value and attributes.
+ */
+ private class ConfigProperty {
+
+ private ConfigProperty(String value, Map<String, String> attributes) {
+ this.value = value;
+ this.attributes = attributes;
+ }
+
+ private String value;
+ private Map<String, String> attributes;
+
+ public String getValue() {
+ return value;
+ }
+
+ public void setValue(String value) {
+ this.value = value;
+ }
+
+ public Map<String, String> getAttributes() {
+ return attributes;
+ }
+
+ public void setAttributes(Map<String, String> attributes) {
+ this.attributes = attributes;
+ }
+ }
/**
* Constructor.
@@ -492,11 +561,12 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @throws AmbariException an exception occurred getting stack information
* for the specified name and version
*/
- public Stack(String name, String version) throws AmbariException {
+ public Stack(String name, String version, AmbariManagementController ambariManagementController) throws AmbariException {
this.name = name;
this.version = version;
+ this.ambariManagementController = ambariManagementController;
- Set<StackServiceResponse> stackServices = getManagementController().getStackServices(
+ Set<StackServiceResponse> stackServices = ambariManagementController.getStackServices(
Collections.singleton(new StackServiceRequest(name, version, null)));
for (StackServiceResponse stackService : stackServices) {
@@ -525,6 +595,11 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
return version;
}
+
+ Map<DependencyInfo, String> getDependencyConditionalServiceMap() {
+ return dependencyConditionalServiceMap;
+ }
+
/**
* Get services contained in the stack.
*
@@ -565,7 +640,47 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @return map of property names to values for the specified service and configuration type
*/
public Map<String, String> getConfigurationProperties(String service, String type) {
- return serviceConfigurations.get(service).get(type);
+ Map<String, String> configMap = new HashMap<String, String>();
+ Map<String, ConfigProperty> configProperties = serviceConfigurations.get(service).get(type);
+ if (configProperties != null) {
+ for (Map.Entry<String, ConfigProperty> configProperty : configProperties.entrySet()) {
+ configMap.put(configProperty.getKey(), configProperty.getValue().getValue());
+ }
+ }
+ return configMap;
+ }
+
+ /**
+ * Get config attributes for the specified service and configuration type.
+ *
+ * @param service service name
+ * @param type configuration type
+ *
+ * @return map of attribute names to map of property names to attribute values
+ * for the specified service and configuration type
+ */
+ public Map<String, Map<String, String>> getConfigurationAttributes(String service, String type) {
+ Map<String, Map<String, String>> attributesMap = new HashMap<String, Map<String, String>>();
+ Map<String, ConfigProperty> configProperties = serviceConfigurations.get(service).get(type);
+ if (configProperties != null) {
+ for (Map.Entry<String, ConfigProperty> configProperty : configProperties.entrySet()) {
+ String propertyName = configProperty.getKey();
+ Map<String, String> propertyAttributes = configProperty.getValue().getAttributes();
+ if (propertyAttributes != null) {
+ for (Map.Entry<String, String> propertyAttribute : propertyAttributes.entrySet()) {
+ String attributeName = propertyAttribute.getKey();
+ String attributeValue = propertyAttribute.getValue();
+ Map<String, String> attributes = attributesMap.get(attributeName);
+ if (attributes == null) {
+ attributes = new HashMap<String, String>();
+ attributesMap.put(attributeName, attributes);
+ }
+ attributes.put(propertyName, attributeValue);
+ }
+ }
+ }
+ }
+ return attributesMap;
}
/**
@@ -603,8 +718,8 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @return name of service which corresponds to the specified configuration type
*/
public String getServiceForConfigType(String config) {
- for (Map.Entry<String, Map<String, Map<String, String>>> entry : serviceConfigurations.entrySet()) {
- Map<String, Map<String, String>> typeMap = entry.getValue();
+ for (Map.Entry<String, Map<String, Map<String, ConfigProperty>>> entry : serviceConfigurations.entrySet()) {
+ Map<String, Map<String, ConfigProperty>> typeMap = entry.getValue();
if (typeMap.containsKey(config)) {
return entry.getKey();
}
@@ -666,7 +781,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
private void parseComponents(String service) throws AmbariException{
Collection<String> componentSet = new HashSet<String>();
- Set<StackServiceComponentResponse> components = getManagementController().getStackComponents(
+ Set<StackServiceComponentResponse> components = ambariManagementController.getStackComponents(
Collections.singleton(new StackServiceComponentRequest(name, version, service, null)));
// stack service components
@@ -702,12 +817,15 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* @throws AmbariException an exception occurred getting configurations from the stack definition
*/
private void parseConfigurations(String service) throws AmbariException {
- Map<String, Map<String, String>> mapServiceConfig = new HashMap<String, Map<String, String>>();
+ Map<String, Map<String, ConfigProperty>> mapServiceConfig = new HashMap<String, Map<String, ConfigProperty>>();
serviceConfigurations.put(service, mapServiceConfig);
- Set<StackConfigurationResponse> serviceConfigs = getManagementController().getStackConfigurations(
+ Set<StackConfigurationResponse> serviceConfigs = ambariManagementController.getStackConfigurations(
Collections.singleton(new StackConfigurationRequest(name, version, service, null)));
+ Set<StackConfigurationResponse> stackLevelConfigs = ambariManagementController.getStackLevelConfigurations(
+ Collections.singleton(new StackLevelConfigurationRequest(name, version, null)));
+ serviceConfigs.addAll(stackLevelConfigs);
for (StackConfigurationResponse config : serviceConfigs) {
String type = config.getType();
@@ -715,12 +833,13 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
if (type.endsWith(".xml")) {
type = type.substring(0, type.length() - 4);
}
- Map<String, String> mapTypeConfig = mapServiceConfig.get(type);
+ Map<String, ConfigProperty> mapTypeConfig = mapServiceConfig.get(type);
if (mapTypeConfig == null) {
- mapTypeConfig = new HashMap<String, String>();
+ mapTypeConfig = new HashMap<String, ConfigProperty>();
mapServiceConfig.put(type, mapTypeConfig);
}
- mapTypeConfig.put(config.getPropertyName(), config.getPropertyValue());
+ mapTypeConfig.put(config.getPropertyName(),
+ new ConfigProperty(config.getPropertyValue(), config.getPropertyAttributes()));
}
}
@@ -728,13 +847,19 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
* Register conditional dependencies.
*/
//todo: This information should be specified in the stack definition.
- private void registerConditionalDependencies() {
+ void registerConditionalDependencies() {
Collection<DependencyInfo> nagiosDependencies = getDependenciesForComponent("NAGIOS_SERVER");
for (DependencyInfo dependency : nagiosDependencies) {
if (dependency.getComponentName().equals("HCAT")) {
- dependencyConditionalServiceMap.put(dependency, "HCATALOG");
+ dependencyConditionalServiceMap.put(dependency, "HIVE");
} else if (dependency.getComponentName().equals("OOZIE_CLIENT")) {
dependencyConditionalServiceMap.put(dependency, "OOZIE");
+ } else if (dependency.getComponentName().equals("YARN_CLIENT")) {
+ dependencyConditionalServiceMap.put(dependency, "YARN");
+ } else if (dependency.getComponentName().equals("TEZ_CLIENT")) {
+ dependencyConditionalServiceMap.put(dependency, "TEZ");
+ } else if (dependency.getComponentName().equals("MAPREDUCE2_CLIENT")) {
+ dependencyConditionalServiceMap.put(dependency, "MAPREDUCE2");
}
}
dbDependencyInfo.put("MYSQL_SERVER", "global/hive_database");
@@ -744,7 +869,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
/**
* Host group representation.
*/
- protected class HostGroup {
+ protected static class HostGroupImpl implements HostGroup {
/**
* Host group entity
*/
@@ -778,18 +903,39 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
private Stack stack;
/**
+ * The Blueprint processor associated with this HostGroupImpl instance
+ */
+ private final BaseBlueprintProcessor blueprintProcessor;
+
+ /**
* Constructor.
*
* @param hostGroup host group
* @param stack stack
*/
- public HostGroup(HostGroupEntity hostGroup, Stack stack) {
+ public HostGroupImpl(HostGroupEntity hostGroup, Stack stack, BaseBlueprintProcessor blueprintProcessor) {
this.hostGroup = hostGroup;
this.stack = stack;
+ this.blueprintProcessor = blueprintProcessor;
parseComponents();
parseConfigurations();
}
+ @Override
+ public String getName() {
+ return hostGroup.getName();
+ }
+
+ @Override
+ public Collection<String> getComponents() {
+ return this.components;
+ }
+
+ @Override
+ public Collection<String> getHostInfo() {
+ return this.hosts;
+ }
+
/**
* Associate a host with the host group.
*
@@ -800,15 +946,6 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
}
/**
- * Get associated host information.
- *
- * @return collection of hosts associated with the host group
- */
- public Collection<String> getHostInfo() {
- return this.hosts;
- }
-
- /**
* Get the services which are deployed to this host group.
*
* @return collection of services which have components in this host group
@@ -818,16 +955,6 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
}
/**
- * Get the components associated with the host group.
- *
- * @return collection of component names for the host group
- */
- public Collection<String> getComponents() {
- return this.components;
- }
-
-
- /**
* Add a component to the host group.
*
* @param component component to add
@@ -867,7 +994,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
*
* @return map of configuration type to a map of properties
*/
- public Map<String, Map<String, String>> getConfigurations() {
+ public Map<String, Map<String, String>> getConfigurationProperties() {
return configurations;
}
@@ -889,7 +1016,7 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
*
* @return map of component to missing dependencies
*/
- public Map<String, Collection<DependencyInfo>> validateTopology(Collection<HostGroup> hostGroups,
+ public Map<String, Collection<DependencyInfo>> validateTopology(Collection<HostGroupImpl> hostGroups,
Collection<String> services,
Map<String, Map<String, String>> clusterConfig) {
@@ -911,14 +1038,14 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
boolean resolved = false;
if (dependencyScope.equals("cluster")) {
- Collection<String> missingDependencyInfo = verifyComponentCardinalityCount(entity, hostGroups,
+ Collection<String> missingDependencyInfo = blueprintProcessor.verifyComponentCardinalityCount(entity, hostGroups,
componentName, new Cardinality("1+"), autoDeployInfo, stack, clusterConfig);
resolved = missingDependencyInfo.isEmpty();
} else if (dependencyScope.equals("host")) {
if (components.contains(component) || (autoDeployInfo != null && autoDeployInfo.isEnabled())) {
resolved = true;
if (addComponent(componentName)) {
- addComponentToBlueprint(hostGroup.getBlueprintEntity(), getEntity().getName(), componentName);
+ blueprintProcessor.addComponentToBlueprint(hostGroup.getBlueprintEntity(), getEntity().getName(), componentName);
}
}
}
@@ -957,8 +1084,12 @@ public abstract class BaseBlueprintProcessor extends AbstractControllerResourceP
typeProperties = new HashMap<String, String>();
configurations.put(type, typeProperties);
}
- configurations.put(type, jsonSerializer.<Map<String, String>>fromJson(
- configEntity.getConfigData(), Map.class));
+ Map<String, String> propertyMap = jsonSerializer.<Map<String, String>>fromJson(
+ configEntity.getConfigData(), Map.class);
+
+ if (propertyMap != null) {
+ typeProperties.putAll(propertyMap);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/9213dcca/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
index f31ed7a..b4d582a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BaseProvider.java
@@ -18,6 +18,16 @@
package org.apache.ambari.server.controller.internal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
import org.apache.ambari.server.controller.spi.Predicate;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
@@ -26,10 +36,6 @@ import org.apache.ambari.server.controller.utilities.PropertyHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
/**
* Base provider implementation for both property and resource providers.
*/
@@ -61,6 +67,19 @@ public abstract class BaseProvider {
protected final static Logger LOG =
LoggerFactory.getLogger(BaseProvider.class);
+ /**
+ * The regex pattern that will match on all $1, $2.method(0), and
+ * $3.method(\"/\",\"///\") and properly substitute. For example, it can turn
+ * <p/>
+ * {@code
+ * metrics/yarn/Queue/$1.replaceAll(\"([.])\",\"/\")/AppsCompleted/$2.substring(0)/foo/$3/bar/$4
+ * }
+ * <p/>
+ * into
+ * <p/>
+ * {@code metrics/yarn/Queue/-/AppsCompleted/-/foo/-/bar/-}
+ */
+ private static final Pattern METRIC_ARGUMENT_METHOD_REPLACEMENT = Pattern.compile("\\$\\d+(\\.\\w+(\\(\\\\\"\\S+\\\\\"\\)|\\(\\d+\\)))*");
// ----- Constructors ------------------------------------------------------
@@ -71,13 +90,17 @@ public abstract class BaseProvider {
*/
public BaseProvider(Set<String> propertyIds) {
this.propertyIds = new HashSet<String>(propertyIds);
- this.categoryIds = PropertyHelper.getCategories(propertyIds);
- this.combinedIds = new HashSet<String>(propertyIds);
- this.combinedIds.addAll(this.categoryIds);
- this.patterns = new HashMap<String, Pattern>();
- for (String id : this.combinedIds) {
+ categoryIds = PropertyHelper.getCategories(propertyIds);
+ combinedIds = new HashSet<String>(propertyIds);
+ combinedIds.addAll(categoryIds);
+ patterns = new HashMap<String, Pattern>();
+
+ // convert the argumented metric as it's defined in the JSON file to regex
+ for (String id : combinedIds) {
if (containsArguments(id)) {
- String pattern = id.replaceAll("\\$\\d+(\\.\\S+\\(\\S+\\))*", "(\\\\S+)");
+ String pattern = METRIC_ARGUMENT_METHOD_REPLACEMENT.matcher(id).replaceAll(
+ "(\\\\S*)");
+
patterns.put(id, Pattern.compile(pattern));
}
}
@@ -93,15 +116,17 @@ public abstract class BaseProvider {
*/
protected Set<String> checkConfigPropertyIds(Set<String> base, String configCategory) {
- if (0 == base.size())
+ if (0 == base.size()) {
return base;
+ }
Set<String> unsupported = new HashSet<String>();
for (String propertyId : base)
{
- if (!propertyId.startsWith(configCategory + "/desired_config"))
+ if (!propertyId.startsWith(configCategory + "/desired_config")) {
unsupported.add(propertyId);
+ }
}
return unsupported;
@@ -110,7 +135,7 @@ public abstract class BaseProvider {
public Set<String> checkPropertyIds(Set<String> propertyIds) {
if (!this.propertyIds.containsAll(propertyIds)) {
Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
- unsupportedPropertyIds.removeAll(this.combinedIds);
+ unsupportedPropertyIds.removeAll(combinedIds);
// If the property id is not in the set of known property ids we may still allow it if
// its parent category is a known property. This allows for Map type properties where
@@ -150,17 +175,17 @@ public abstract class BaseProvider {
propertyIds.addAll(PredicateHelper.getPropertyIds(predicate));
}
- if (!this.combinedIds.containsAll(propertyIds)) {
+ if (!combinedIds.containsAll(propertyIds)) {
Set<String> keepers = new HashSet<String>();
Set<String> unsupportedPropertyIds = new HashSet<String>(propertyIds);
- unsupportedPropertyIds.removeAll(this.combinedIds);
+ unsupportedPropertyIds.removeAll(combinedIds);
for (String unsupportedPropertyId : unsupportedPropertyIds) {
if (checkCategory(unsupportedPropertyId) || checkRegExp(unsupportedPropertyId)) {
keepers.add(unsupportedPropertyId);
}
}
- propertyIds.retainAll(this.combinedIds);
+ propertyIds.retainAll(combinedIds);
propertyIds.addAll(keepers);
}
return propertyIds;
@@ -173,7 +198,7 @@ public abstract class BaseProvider {
protected boolean checkCategory(String unsupportedPropertyId) {
String category = PropertyHelper.getPropertyCategory(unsupportedPropertyId);
while (category != null) {
- if(this.propertyIds.contains(category)) {
+ if(propertyIds.contains(category)) {
return true;
}
category = PropertyHelper.getPropertyCategory(category);
@@ -191,20 +216,28 @@ public abstract class BaseProvider {
return false;
}
- protected String getRegExpKey(String id) {
- String regExpKey = null;
+ /**
+ * Gets the key/value mapping between a metric string in the JSON files and
+ * the Java regular expression pattern that matches it.
+ *
+ * @param id
+ * @return the entry, or {@code null} if none match the ID.
+ */
+ protected Map.Entry<String, Pattern> getRegexEntry(String id) {
+ Map.Entry<String, Pattern> regexEntry = null;
+
for (Map.Entry<String, Pattern> entry : patterns.entrySet()) {
Pattern pattern = entry.getValue();
Matcher matcher = pattern.matcher(id);
if (matcher.matches()) {
String key = entry.getKey();
- if (regExpKey == null || key.startsWith(regExpKey)) {
- regExpKey = entry.getKey();
+ if (regexEntry == null || key.startsWith(regexEntry.getKey())) {
+ regexEntry = entry;
}
}
}
- return regExpKey;
+ return regexEntry;
}
/**