You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by jl...@apache.org on 2016/06/27 23:36:56 UTC
[30/34] ambari git commit: AMBARI-17355 & AMBARI-17354: POC: FE & BE
changes for first class support for Yarn hosted services
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/QuickLinkArtifactResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/QuickLinkArtifactResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/QuickLinkArtifactResourceProvider.java
index 034aeb7..3e4b6aa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/QuickLinkArtifactResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/QuickLinkArtifactResourceProvider.java
@@ -19,6 +19,7 @@
package org.apache.ambari.server.controller.internal;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
@@ -138,8 +139,9 @@ public class QuickLinkArtifactResourceProvider extends AbstractControllerResourc
String stackService = (String) properties.get(STACK_SERVICE_NAME_PROPERTY_ID);
StackInfo stackInfo;
+ AmbariMetaInfo ambariMetaInfo = getManagementController().getAmbariMetaInfo();
try {
- stackInfo = getManagementController().getAmbariMetaInfo().getStack(stackName, stackVersion);
+ stackInfo = ambariMetaInfo.getStack(stackName, stackVersion);
} catch (AmbariException e) {
throw new NoSuchParentResourceException(String.format(
"Parent stack resource doesn't exist: stackName='%s', stackVersion='%s'", stackName, stackVersion));
@@ -150,13 +152,19 @@ public class QuickLinkArtifactResourceProvider extends AbstractControllerResourc
if (stackService == null) {
serviceInfoList.addAll(stackInfo.getServices());
} else {
- ServiceInfo service = stackInfo.getService(stackService);
- if (service == null) {
+ try {
+ ServiceInfo service = ambariMetaInfo.getService(stackName, stackVersion, stackService);
+ if (service == null) {
+ throw new NoSuchParentResourceException(String.format(
+ "Parent stack/service resource doesn't exist: stackName='%s', stackVersion='%s', serviceName='%s'",
+ stackName, stackVersion, stackService));
+ }
+ serviceInfoList.add(service);
+ } catch (AmbariException e) {
throw new NoSuchParentResourceException(String.format(
- "Parent stack/service resource doesn't exist: stackName='%s', stackVersion='%s', serviceName='%s'",
- stackName, stackVersion, stackService));
+ "Parent stack/service resource doesn't exist: stackName='%s', stackVersion='%s', serviceName='%s'",
+ stackName, stackVersion, stackService));
}
- serviceInfoList.add(service);
}
for (ServiceInfo serviceInfo : serviceInfoList) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RemoteClusterResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RemoteClusterResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RemoteClusterResourceProvider.java
index 413dbff..49892cb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RemoteClusterResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RemoteClusterResourceProvider.java
@@ -63,6 +63,7 @@ public class RemoteClusterResourceProvider extends AbstractAuthorizedResourcePro
* Remote Cluster property id constants.
*/
public static final String CLUSTER_NAME_PROPERTY_ID = "ClusterInfo/name";
+ public static final String CLUSTER_ID_PROPERTY_ID = "ClusterInfo/cluster_id";
public static final String CLUSTER_URL_PROPERTY_ID = "ClusterInfo/url";
public static final String USERNAME_PROPERTY_ID = "ClusterInfo/username";
public static final String PASSWORD_PROPERTY_ID = "ClusterInfo/password";
@@ -87,6 +88,7 @@ public class RemoteClusterResourceProvider extends AbstractAuthorizedResourcePro
private static Set<String> propertyIds = new HashSet<String>();
static {
propertyIds.add(CLUSTER_NAME_PROPERTY_ID);
+ propertyIds.add(CLUSTER_ID_PROPERTY_ID);
propertyIds.add(CLUSTER_URL_PROPERTY_ID);
propertyIds.add(USERNAME_PROPERTY_ID);
propertyIds.add(PASSWORD_PROPERTY_ID);
@@ -167,6 +169,7 @@ public class RemoteClusterResourceProvider extends AbstractAuthorizedResourcePro
protected Resource toResource(Set<String> requestedIds, RemoteAmbariClusterEntity cluster) {
Resource resource = new ResourceImpl(Resource.Type.RemoteCluster);
setResourceProperty(resource, CLUSTER_NAME_PROPERTY_ID, cluster.getName(), requestedIds);
+ setResourceProperty(resource, CLUSTER_ID_PROPERTY_ID, cluster.getId(), requestedIds);
setResourceProperty(resource, CLUSTER_URL_PROPERTY_ID, cluster.getUrl(), requestedIds);
setResourceProperty(resource, USERNAME_PROPERTY_ID, cluster.getUsername(), requestedIds);
ArrayList<String> services = new ArrayList<String>();
@@ -237,8 +240,14 @@ public class RemoteClusterResourceProvider extends AbstractAuthorizedResourcePro
public Void invoke() throws AmbariException {
String name = (String)properties.get(CLUSTER_NAME_PROPERTY_ID);
- if(StringUtils.isEmpty(name)){
- throw new IllegalArgumentException("Cluster Name cannot ne null or Empty");
+ if (StringUtils.isEmpty(name)) {
+ throw new IllegalArgumentException("Cluster Name cannot be null or Empty");
+ }
+
+ String id = (String)properties.get(CLUSTER_ID_PROPERTY_ID);
+
+ if (StringUtils.isEmpty(id)) {
+ throw new IllegalArgumentException("Cluster Id cannot be null or Empty");
}
saveOrUpdateRemoteAmbariClusterEntity(properties,true);
@@ -261,16 +270,24 @@ public class RemoteClusterResourceProvider extends AbstractAuthorizedResourcePro
String username = (String)properties.get(USERNAME_PROPERTY_ID);
String password = (String)properties.get(PASSWORD_PROPERTY_ID);
- if(StringUtils.isEmpty(url) && StringUtils.isEmpty(username)){
+ if (StringUtils.isEmpty(url) && StringUtils.isEmpty(username)) {
throw new IllegalArgumentException("Url or username cannot be null");
}
- RemoteAmbariClusterEntity entity = remoteAmbariClusterDAO.findByName(name);
+ RemoteAmbariClusterEntity entity ;
+
+ if (update) {
+ Long id = Long.valueOf((String) properties.get(CLUSTER_ID_PROPERTY_ID));
+ entity = remoteAmbariClusterDAO.findById(id);
+ if (entity == null) {
+ throw new IllegalArgumentException(String.format("Cannot find cluster with Id : \"%s\"", id));
+ }
+ } else {
- if(update && entity == null){
- throw new IllegalArgumentException(String.format("Cannot find cluster with name : \"%s\"",name));
- }else if(!update && entity != null){
- throw new DuplicateResourceException(String.format("Cluster with name : \"%s\" already exists",name));
+ entity = remoteAmbariClusterDAO.findByName(name);
+ if (entity != null) {
+ throw new DuplicateResourceException(String.format("Cluster with name : \"%s\" already exists", name));
+ }
}
// Check Password not null for create
@@ -288,7 +305,7 @@ public class RemoteClusterResourceProvider extends AbstractAuthorizedResourcePro
entity.setName(name);
entity.setUrl(url);
try {
- if(password != null) {
+ if (password != null) {
entity.setUsername(username);
entity.setPassword(password);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupResourceProvider.java
new file mode 100644
index 0000000..ff67c5b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupResourceProvider.java
@@ -0,0 +1,759 @@
+/**
+ * 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 com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import jline.internal.Log;
+import org.apache.ambari.server.*;
+import org.apache.ambari.server.api.services.*;
+import org.apache.ambari.server.controller.*;
+import org.apache.ambari.server.controller.servicegroup.cache.ServiceGroupCacheKey;
+import org.apache.ambari.server.controller.servicegroup.cache.ServiceGroupCacheProvider;
+import org.apache.ambari.server.controller.spi.*;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.controller.servicegroup.cache.ServiceGroupCache;
+import org.apache.ambari.server.controller.servicegroup.cache.ServiceGroupCacheValue;
+import org.apache.ambari.server.controller.servicegroup.cache.ServiceGroupCacheProvider;
+import org.apache.ambari.server.security.authorization.AuthorizationException;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.security.authorization.ResourceType;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.apache.ambari.server.serveraction.kerberos.KerberosAdminAuthenticationException;
+import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
+import org.apache.ambari.server.serveraction.kerberos.KerberosMissingAdminCredentialsException;
+import org.apache.ambari.server.state.*;
+import org.apache.ambari.server.utils.MapUtils;
+import org.apache.ambari.server.utils.StageUtils;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.NotImplementedException;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.Validate;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.*;
+import java.net.URLEncoder;
+import java.io.OutputStream;
+
+/**
+ * Resource provider for service resources.
+ */
+public class ServiceGroupResourceProvider extends AbstractControllerResourceProvider {
+
+
+ // ----- Property ID constants ---------------------------------------------
+
+ // Services
+ public static final String SERVICE_GROUP_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "cluster_name");
+ public static final String SERVICE_GROUP_SERVICE_GROUP_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "service_group_name");
+ public static final String SERVICE_GROUP_SERVICE_GROUP_DISPLAY_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "service_group_display_name");
+ public static final String SERVICE_GROUP_SERVICE_GROUP_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "service_group_type");
+ public static final String SERVICE_GROUP_ASSEMBLY_FILE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "assembly_file");
+ public static final String SERVICE_GROUP_DESIRED_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "desired_state");
+ public static final String SERVICE_GROUP_CURRENT_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "current_state");
+ public static final String SERVICE_GROUP_APPLICATION_ID_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "application_id");
+ public static final String SERVICE_GROUP_LIFETIME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "lifetime");
+ public static final String SERVICE_GROUP_QUICKLINKS_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "quicklinks");
+ public static final String SERVICE_GROUP_CONTAINERS_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "containers");
+ public static final String SERVICE_GROUP_NUMBER_CONTAINERS_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "number_of_containers");
+ public static final String SERVICE_GROUP_EXPECTED_CONTAINERS_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceGroupInfo", "expected_number_of_containers");
+
+
+ private static Set<String> pkPropertyIds =
+ new HashSet<String>(Arrays.asList(new String[]{
+ SERVICE_GROUP_CLUSTER_NAME_PROPERTY_ID,
+ SERVICE_GROUP_SERVICE_GROUP_NAME_PROPERTY_ID}));
+
+ private static Map<String, String> componentNameMappings = MapUtils.fillMap("/var/lib/ambari-server/resources/componentsMap.dat");
+
+ private static Gson gson = StageUtils.getGson();
+
+ /**
+ * kerberos helper
+ */
+ @Inject
+ private KerberosHelper kerberosHelper;
+
+ private ServiceGroupCacheProvider cacheProvider;
+ private ServiceGroupCache cache;
+
+ // ----- Constructors ----------------------------------------------------
+
+ /**
+ * Create a new resource provider for the given management controller.
+ *
+ * @param propertyIds the property ids
+ * @param keyPropertyIds the key property ids
+ * @param managementController the management controller
+ */
+ @AssistedInject
+ public ServiceGroupResourceProvider(@Assisted Set<String> propertyIds,
+ @Assisted Map<Resource.Type, String> keyPropertyIds,
+ @Assisted AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+
+ setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.SERVICE_ADD_DELETE_SERVICES));
+ setRequiredUpdateAuthorizations(RoleAuthorization.AUTHORIZATIONS_UPDATE_SERVICE);
+ setRequiredGetAuthorizations(RoleAuthorization.AUTHORIZATIONS_VIEW_SERVICE);
+ setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.SERVICE_ADD_DELETE_SERVICES));
+
+ this.cacheProvider = managementController.getServiceGroupCacheProvider();
+ this.cache = cacheProvider.getServiceGroupCache();
+ }
+
+ // ----- ResourceProvider ------------------------------------------------
+
+ @Override
+ protected RequestStatus createResourcesAuthorized(Request request)
+ throws SystemException,
+ UnsupportedPropertyException,
+ ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ final Set<ServiceGroupRequest> requests = new HashSet<>();
+ for (Map<String, Object> propertyMap : request.getProperties()) {
+ requests.add(getRequest(propertyMap));
+ }
+ createResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException, AuthorizationException {
+ createServiceGroups(requests);
+ return null;
+ }
+ });
+ notifyCreate(Resource.Type.ServiceGroup, request);
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ protected Set<Resource> getResourcesAuthorized(Request request, Predicate predicate) throws
+ SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ServiceGroupRequest> requests = new HashSet<>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ Set<ServiceGroupResponse> responses = getResources(new Command<Set<ServiceGroupResponse>>() {
+ @Override
+ public Set<ServiceGroupResponse> invoke() throws AmbariException {
+ return getServiceGroups(requests);
+ }
+ });
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ServiceGroupResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.ServiceGroup);
+ setResourceProperty(resource, SERVICE_GROUP_CLUSTER_NAME_PROPERTY_ID,
+ response.getClusterName(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_SERVICE_GROUP_NAME_PROPERTY_ID,
+ response.getServiceGroupName(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_SERVICE_GROUP_DISPLAY_NAME_PROPERTY_ID,
+ response.getServiceGroupDisplayName(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_SERVICE_GROUP_TYPE_PROPERTY_ID,
+ response.getServiceGroupType(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_ASSEMBLY_FILE_PROPERTY_ID,
+ response.getAssemblyFile(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DESIRED_STATE_PROPERTY_ID,
+ response.getDesiredState(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_CURRENT_STATE_PROPERTY_ID,
+ response.getDesiredState(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_APPLICATION_ID_PROPERTY_ID,
+ response.getApplicationId(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_LIFETIME_PROPERTY_ID,
+ response.getLifetime(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_QUICKLINKS_PROPERTY_ID,
+ response.getQuickLinks(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_CONTAINERS_PROPERTY_ID,
+ response.getContainers(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_NUMBER_CONTAINERS_PROPERTY_ID,
+ response.getNumContainers(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_EXPECTED_CONTAINERS_PROPERTY_ID,
+ response.getExpectedContainers(), requestedIds);
+ resources.add(resource);
+ }
+ return resources;
+ }
+
+ @Override
+ protected RequestStatus updateResourcesAuthorized(final Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ RequestStageContainer requestStages = doUpdateResources(null, request, predicate);
+
+ RequestStatusResponse response = null;
+ if (requestStages != null) {
+ try {
+ requestStages.persist();
+ } catch (AmbariException e) {
+ throw new SystemException(e.getMessage(), e);
+ }
+ response = requestStages.getRequestStatusResponse();
+ }
+ notifyUpdate(Resource.Type.ServiceGroup, request, predicate);
+
+ return getRequestStatus(response);
+ }
+
+ @Override
+ protected RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ServiceGroupRequest> requests = new HashSet<>();
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
+ @Override
+ public RequestStatusResponse invoke() throws AmbariException, AuthorizationException {
+ return deleteServiceGroups(requests);
+ }
+ });
+
+ notifyDelete(Resource.Type.ServiceGroup, predicate);
+ return getRequestStatus(response);
+ }
+
+ @Override
+ public Set<String> checkPropertyIds(Set<String> propertyIds) {
+ propertyIds = super.checkPropertyIds(propertyIds);
+
+ if (propertyIds.isEmpty()) {
+ return propertyIds;
+ }
+ Set<String> unsupportedProperties = new HashSet<String>();
+ return unsupportedProperties;
+ }
+
+
+ // ----- AbstractResourceProvider ----------------------------------------
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+ // ----- utility methods -------------------------------------------------
+
+ private RequestStageContainer doUpdateResources(final RequestStageContainer stages, final Request request, Predicate predicate)
+ throws UnsupportedPropertyException, SystemException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ServiceGroupRequest> requests = new HashSet<>();
+ RequestStageContainer requestStages = null;
+
+ Iterator<Map<String,Object>> iterator = request.getProperties().iterator();
+ if (iterator.hasNext()) {
+ for (Map<String, Object> propertyMap : getPropertyMaps(iterator.next(), predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ requestStages = modifyResources(new Command<RequestStageContainer>() {
+ @Override
+ public RequestStageContainer invoke() throws AmbariException, AuthorizationException {
+ return updateServiceGroup(stages, requests, request.getRequestInfoProperties());
+ }
+ });
+ }
+ return requestStages;
+ }
+
+ // Update services based on the given requests.
+ protected synchronized RequestStageContainer updateServiceGroup(RequestStageContainer requestStages,
+ Set<ServiceGroupRequest> requests, Map<String, String> requestProperties) throws AmbariException, AuthorizationException {
+
+ AmbariManagementController controller = getManagementController();
+ if (requests.isEmpty()) {
+ LOG.warn("Received an empty requests set");
+ return null;
+ }
+
+ Map<String, Set<String>> serviceGroupNames = new HashMap<>();
+ Map<State, List<ServiceGroup>> changedServiceGroups = new EnumMap<>(State.class);
+ Set<State> seenNewStates = new HashSet<>();
+ Clusters clusters = controller.getClusters();
+ Set<String> clusterNames = new HashSet<>();
+
+ for (ServiceGroupRequest request : requests) {
+ if (request.getClusterName() == null
+ || request.getClusterName().isEmpty()
+ || request.getServiceGroupName() == null
+ || request.getServiceGroupName().isEmpty()) {
+ throw new IllegalArgumentException("Invalid arguments, cluster name"
+ + " and service group name should be provided to update service groups");
+ }
+
+ LOG.info("Received a updateServiceGroup request"
+ + ", clusterName=" + request.getClusterName()
+ + ", serviceGroupName=" + request.getServiceGroupName()
+ + ", request=" + request.toString());
+
+ clusterNames.add(request.getClusterName());
+
+ if (clusterNames.size() > 1) {
+ throw new IllegalArgumentException("Updates to multiple clusters is not"
+ + " supported");
+ }
+
+ if (!serviceGroupNames.containsKey(request.getClusterName())) {
+ serviceGroupNames.put(request.getClusterName(), new HashSet<String>());
+ }
+ if (serviceGroupNames.get(request.getClusterName())
+ .contains(request.getServiceGroupName())) {
+ // TODO throw single exception
+ throw new IllegalArgumentException("Invalid request contains duplicate"
+ + " service group names");
+ }
+ serviceGroupNames.get(request.getClusterName()).add(request.getServiceGroupName());
+
+ Cluster cluster = clusters.getCluster(request.getClusterName());
+ ServiceGroup sg = cluster.getServiceGroup(request.getServiceGroupName());
+ State oldState = sg.getCurrentState();
+ State newState = null;
+ if (request.getDesiredState() != null) {
+ newState = State.valueOf(request.getDesiredState());
+ if (!newState.isValidDesiredState()) {
+ throw new IllegalArgumentException("Invalid arguments, invalid"
+ + " desired state, desiredState=" + newState);
+ }
+ }
+
+ boolean persist = false;
+ if(request.getServiceGroupDisplayName() != null && !request.getServiceGroupDisplayName().equals(sg.getServiceGroupDisplayName())) {
+ sg.setServiceGroupDisplayName(request.getServiceGroupDisplayName());
+ persist = true;
+ }
+
+ if(request.getAssemblyFile() != null && !request.getAssemblyFile().equals(sg.getAssemblyFile())) {
+ sg.setAssemblyFile(request.getAssemblyFile());
+ persist = true;
+ }
+
+ if(persist) {
+ sg.persist();
+ LOG.info("Updated properties for service group " + sg.getName());
+ }
+
+ if (newState == null) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Nothing to do for new updateServiceGroup request"
+ + ", clusterName=" + request.getClusterName()
+ + ", serviceName=" + request.getServiceGroupName()
+ + ", newDesiredState=null");
+ }
+ continue;
+ }
+
+ seenNewStates.add(newState);
+ if (newState != oldState) {
+ // The if user is trying to start or stop the service, ensure authorization
+ if (((newState == State.INSTALLED) || (newState == State.STARTED)) &&
+ !AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, cluster.getResourceId(), RoleAuthorization.SERVICE_START_STOP)) {
+ throw new AuthorizationException("The authenticated user is not authorized to start or stop services");
+ }
+
+ if (!State.isValidDesiredStateTransition(oldState, newState)) {
+ throw new AmbariException("Invalid transition for"
+ + " service group"
+ + ", clusterName=" + cluster.getClusterName()
+ + ", clusterId=" + cluster.getClusterId()
+ + ", serviceGroupName=" + sg.getName()
+ + ", currentDesiredState=" + oldState
+ + ", newDesiredState=" + newState);
+ }
+ // TODO: Remove block for stopping service groups
+ if (newState == State.INSTALLED && oldState == State.STARTED ) {
+ throw new AmbariException("Stopping service groups not supported for"
+ + " service group"
+ + ", clusterName=" + cluster.getClusterName()
+ + ", clusterId=" + cluster.getClusterId()
+ + ", serviceGroupName=" + sg.getName()
+ + ", currentDesiredState=" + oldState
+ + ", newDesiredState=" + newState);
+ }
+ if (!changedServiceGroups.containsKey(newState)) {
+ changedServiceGroups.put(newState, new ArrayList<ServiceGroup>());
+ }
+ changedServiceGroups.get(newState).add(sg);
+ }
+ }
+ if (seenNewStates.size() > 1) {
+ // TODO should we handle this scenario
+ throw new IllegalArgumentException("Cannot handle different desired state"
+ + " changes for a set of services at the same time");
+ }
+ Cluster cluster = clusters.getCluster(clusterNames.iterator().next());
+
+ return controller.addServiceGroupStages(requestStages, cluster, requestProperties,
+ null, changedServiceGroups);
+ }
+
+ /**
+ * Get a service group request object from a map of property values.
+ *
+ * @param properties the predicate
+ *
+ * @return the service request object
+ */
+ private ServiceGroupRequest getRequest(Map<String, Object> properties) {
+ ServiceGroupRequest svcRequest = new ServiceGroupRequest(
+ (String) properties.get(SERVICE_GROUP_CLUSTER_NAME_PROPERTY_ID),
+ (String) properties.get(SERVICE_GROUP_SERVICE_GROUP_NAME_PROPERTY_ID),
+ (String) properties.get(SERVICE_GROUP_SERVICE_GROUP_DISPLAY_NAME_PROPERTY_ID),
+ (String) properties.get(SERVICE_GROUP_SERVICE_GROUP_TYPE_PROPERTY_ID),
+ (String) properties.get(SERVICE_GROUP_ASSEMBLY_FILE_PROPERTY_ID),
+ (String) properties.get(SERVICE_GROUP_DESIRED_STATE_PROPERTY_ID),
+ (String) properties.get(SERVICE_GROUP_CURRENT_STATE_PROPERTY_ID));
+ return svcRequest;
+ }
+
+ // Create services from the given request.
+ public synchronized void createServiceGroups(Set<ServiceGroupRequest> requests)
+ throws AmbariException, AuthorizationException {
+
+ if (requests.isEmpty()) {
+ LOG.warn("Received an empty requests set");
+ return;
+ }
+ AmbariManagementController controller = getManagementController();
+ Clusters clusters = controller.getClusters();
+ for(ServiceGroupRequest request: requests) {
+ if(StringUtils.isBlank(request.getServiceGroupDisplayName())) {
+ request.setServiceGroupDisplayName(request.getServiceGroupName());
+ }
+ }
+
+ // do all validation checks
+ validateCreateRequests(requests, clusters);
+
+ ServiceGroupFactory serviceGroupFactory = controller.getServiceGroupFactory();
+ ServiceFactory serviceFactory = getManagementController().getServiceFactory();
+ ServiceComponentFactory serviceComponentFactory = getManagementController().getServiceComponentFactory();
+ for (ServiceGroupRequest request : requests) {
+ Cluster cluster = clusters.getCluster(request.getClusterName());
+
+ State desiredState = State.INIT;
+ State currentState = State.INIT;
+ if (!request.getServiceGroupType().equalsIgnoreCase("AMBARI")) {
+ ServiceGroupCacheKey cacheKey = new ServiceGroupCacheKey(request.getServiceGroupName());
+ ServiceGroupCacheValue cacheValue = null;
+ try {
+ cacheValue = cache.getServiceGroupCacheValue(cacheKey);
+ } catch (Exception e) {
+ LOG.error("Hit exception when retrieving service group from cache. Exception: " + e.getMessage());
+ }
+ if (cacheValue != null) {
+ // YarnApp already deployed (Ambari takeover)
+ desiredState = State.STARTED;
+ currentState = State.STARTED;
+ }
+ }
+ // Already checked that service group does not exist
+ ServiceGroup sg = serviceGroupFactory.createNew(cluster, request.getServiceGroupName(),
+ request.getServiceGroupDisplayName(), request.getServiceGroupType(), request.getAssemblyFile(), desiredState, currentState);
+ sg.persist();
+
+ try {
+ if (!request.getServiceGroupType().equalsIgnoreCase("AMBARI")) {
+ Map<String, Map<String, Integer>> serviceComponentsMap = parseAssemblyFile(request.getAssemblyFile(), cluster);
+ if (serviceComponentsMap != null) {
+ for (Map.Entry<String, Map<String, Integer>> serviceEntry : serviceComponentsMap.entrySet()) {
+ String stackServiceName = serviceEntry.getKey();
+ String serviceName = stackServiceName + "_" + request.getServiceGroupName();
+ LOG.info("Creating service " + serviceName + " in service group " + request.getServiceGroupName());
+ State state = State.INIT;
+ // Already checked that service does not exist
+ Service s = serviceFactory.createNew(
+ cluster, serviceName, stackServiceName, request.getServiceGroupName());
+ s.setDesiredState(state);
+ s.setDesiredStackVersion(cluster.getDesiredStackVersion());
+ cluster.addService(s);
+ s.persist();
+ LOG.info("Created service " + serviceName + " in service group " + request.getServiceGroupName());
+
+ for (Map.Entry<String, Integer> componentEntry : serviceEntry.getValue().entrySet()) {
+ String componentName = componentEntry.getKey();
+ Integer desiredCount = componentEntry.getValue();
+ LOG.info("Creating service component " + componentName +
+ " in service " + serviceName +
+ " with desired count " + desiredCount);
+ ServiceComponent sc = serviceComponentFactory.createNew(s, componentName);
+ sc.setDesiredState(s.getDesiredState());
+ sc.setDesiredCount(desiredCount);
+ s.addServiceComponent(sc);
+ sc.persist();
+ LOG.info("Created service component " + componentName +
+ " in service " + serviceName +
+ " with desired count " + desiredCount);
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOG.error("Failed to create service components for service group " + sg.getName());
+ LOG.error("Ignoring Exception : " + e.getMessage());
+ }
+ }
+ }
+
+ // Get services from the given set of requests.
+ protected Set<ServiceGroupResponse> getServiceGroups(Set<ServiceGroupRequest> requests)
+ throws AmbariException {
+ Set<ServiceGroupResponse> response = new HashSet<ServiceGroupResponse>();
+ for (ServiceGroupRequest request : requests) {
+ try {
+ response.addAll(getServiceGroups(request));
+ } catch (ServiceGroupNotFoundException e) {
+ if (requests.size() == 1) {
+ // only throw exception if 1 request.
+ // there will be > 1 request in case of OR predicate
+ throw e;
+ }
+ }
+ }
+ return response;
+ }
+
+ // Get services from the given request.
+ private Set<ServiceGroupResponse> getServiceGroups(ServiceGroupRequest request)
+ throws AmbariException {
+ if (request.getClusterName() == null
+ || request.getClusterName().isEmpty()) {
+ throw new AmbariException("Invalid arguments, cluster name"
+ + " cannot be null");
+ }
+ AmbariManagementController controller = getManagementController();
+ Clusters clusters = controller.getClusters();
+ String clusterName = request.getClusterName();
+
+ final Cluster cluster;
+ try {
+ cluster = clusters.getCluster(clusterName);
+ } catch (ObjectNotFoundException e) {
+ throw new ParentObjectNotFoundException("Parent Cluster resource doesn't exist", e);
+ }
+
+ Set<ServiceGroupResponse> response = new HashSet<>();
+ if (request.getServiceGroupName() != null) {
+ ServiceGroup sg = cluster.getServiceGroup(request.getServiceGroupName());
+ ServiceGroupResponse serviceGroupResponse = sg.convertToResponse();
+ if(sg != null && !sg.getServiceGroupType().equalsIgnoreCase("AMBARI")) {
+ ServiceGroupCacheKey cacheKey = new ServiceGroupCacheKey(sg.getName());
+ ServiceGroupCacheValue cacheValue = null;
+ try {
+ cacheValue = cache.getServiceGroupCacheValue(cacheKey);
+ } catch (Exception e) {
+ LOG.error("Hit exception when retrieving service group from cache. Exception: " + e.getMessage());
+ }
+ if(cacheValue != null) {
+ serviceGroupResponse.setApplicationId(cacheValue.getApplicationId());
+ serviceGroupResponse.setLifetime(cacheValue.getLifetime());
+ serviceGroupResponse.setQuickLinks(cacheValue.getQuicklinks());
+ serviceGroupResponse.setContainers(cacheValue.getContainers());
+ serviceGroupResponse.setNumContainers(cacheValue.getNumContainers());
+ serviceGroupResponse.setExpectedContainers(cacheValue.getExpectedContainers());
+ }
+ }
+ response.add(serviceGroupResponse);
+ return response;
+ }
+
+ for (ServiceGroup sg : cluster.getServiceGroups().values()) {
+ ServiceGroupResponse serviceGroupResponse = sg.convertToResponse();
+ if(!sg.getServiceGroupType().equalsIgnoreCase("AMBARI")) {
+ ServiceGroupCacheKey cacheKey = new ServiceGroupCacheKey(sg.getName());
+ ServiceGroupCacheValue cacheValue = null;
+ try {
+ cacheValue = cache.getServiceGroupCacheValue(cacheKey);
+ } catch (Exception e) {
+ LOG.error("Hit exception when retrieving service group from cache. Exception: " + e.getMessage());
+ }
+ if(cacheValue != null) {
+ serviceGroupResponse.setApplicationId(cacheValue.getApplicationId());
+ serviceGroupResponse.setLifetime(cacheValue.getLifetime());
+ serviceGroupResponse.setQuickLinks(cacheValue.getQuicklinks());
+ serviceGroupResponse.setContainers(cacheValue.getContainers());
+ serviceGroupResponse.setNumContainers(cacheValue.getNumContainers());
+ serviceGroupResponse.setExpectedContainers(cacheValue.getExpectedContainers());
+ }
+ }
+ response.add(serviceGroupResponse);
+ }
+ return response;
+ }
+
+
+ // Delete services based on the given set of requests
+ protected RequestStatusResponse deleteServiceGroups(Set<ServiceGroupRequest> request)
+ throws AmbariException, AuthorizationException {
+
+ Clusters clusters = getManagementController().getClusters();
+
+ Set<ServiceGroup> removable = new HashSet<>();
+
+ for (ServiceGroupRequest serviceGroupRequest : request) {
+ if (StringUtils.isEmpty(serviceGroupRequest.getClusterName())
+ || StringUtils.isEmpty(serviceGroupRequest.getServiceGroupName())) {
+ // FIXME throw correct error
+ throw new AmbariException("invalid arguments");
+ } else {
+
+ if(!AuthorizationHelper.isAuthorized(
+ ResourceType.CLUSTER, getClusterResourceId(serviceGroupRequest.getClusterName()),
+ RoleAuthorization.SERVICE_ADD_DELETE_SERVICES)) {
+ throw new AuthorizationException("The user is not authorized to delete service groups");
+ }
+
+ ServiceGroup serviceGroup = clusters.getCluster(
+ serviceGroupRequest.getClusterName()).getServiceGroup(
+ serviceGroupRequest.getServiceGroupName());
+
+ // TODO: Add check to validate there are no services in the service group
+ removable.add(serviceGroup);
+ }
+ }
+
+ for (ServiceGroup serviceGroup : removable) {
+ serviceGroup.getCluster().deleteServiceGroup(serviceGroup.getName());
+ }
+
+ return null;
+ }
+
+
+ private void validateCreateRequests(Set<ServiceGroupRequest> requests, Clusters clusters)
+ throws AuthorizationException, AmbariException {
+
+ AmbariMetaInfo ambariMetaInfo = getManagementController().getAmbariMetaInfo();
+ Map<String, Set<String>> serviceGroupNames = new HashMap<>();
+ Set<String> duplicates = new HashSet<>();
+ for (ServiceGroupRequest request : requests) {
+ final String clusterName = request.getClusterName();
+ final String serviceGroupName = request.getServiceGroupName();
+
+ Validate.notEmpty(clusterName, "Cluster name should be provided when creating a service group");
+ Validate.notEmpty(serviceGroupName, "Service group name should be provided when creating a service group");
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Received a createServiceGroup request"
+ + ", clusterName=" + ", serviceGroupName=" + serviceGroupName + ", request=" + request);
+ }
+
+ if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER,
+ getClusterResourceId(clusterName), RoleAuthorization.SERVICE_ADD_DELETE_SERVICES)) {
+ throw new AuthorizationException("The user is not authorized to create service groups");
+ }
+
+ if (!serviceGroupNames.containsKey(clusterName)) {
+ serviceGroupNames.put(clusterName, new HashSet<String>());
+ }
+
+ if (serviceGroupNames.get(clusterName).contains(serviceGroupName)) {
+ // throw error later for dup
+ duplicates.add(serviceGroupName);
+ continue;
+ }
+ serviceGroupNames.get(clusterName).add(serviceGroupName);
+
+ Cluster cluster;
+ try {
+ cluster = clusters.getCluster(clusterName);
+ } catch (ClusterNotFoundException e) {
+ throw new ParentObjectNotFoundException("Attempted to add a service group to a cluster which doesn't exist", e);
+ }
+ try {
+ ServiceGroup sg = cluster.getServiceGroup(serviceGroupName);
+ if (sg != null) {
+ // throw error later for dup
+ duplicates.add(serviceGroupName);
+ continue;
+ }
+ } catch (ServiceGroupNotFoundException e) {
+ // Expected
+ }
+ }
+ // ensure only a single cluster update
+ if (serviceGroupNames.size() != 1) {
+ throw new IllegalArgumentException("Invalid arguments, updates allowed"
+ + "on only one cluster at a time");
+ }
+
+ // Validate dups
+ if (!duplicates.isEmpty()) {
+ String clusterName = requests.iterator().next().getClusterName();
+ String msg = "Attempted to create a service group which already exists: "
+ + ", clusterName=" + clusterName + " serviceGroupName=" + StringUtils.join(duplicates, ",");
+
+ throw new DuplicateResourceException(msg);
+ }
+ }
+
+ private Map<String, Map<String, Integer>> parseAssemblyFile(String assemblyFile, Cluster cluster) throws AmbariException {
+ StackId stackId = cluster.getDesiredStackVersion();
+ AmbariMetaInfo ambariMetaInfo = getManagementController().getAmbariMetaInfo();
+ if(StringUtils.isBlank(assemblyFile)) {
+ return null;
+ }
+ Map<String, Map<String, Integer>> serviceComponentsMap = new HashMap<>();
+ Map<String, Object> assemblyMap = gson.fromJson(assemblyFile,
+ new TypeToken<Map<String, Object>>() {
+ }.getType());
+ if(assemblyMap != null && assemblyMap.containsKey("components")) {
+ for (Map<String, Object> componentMap : (ArrayList<Map<String, Object>>) assemblyMap.get("components")) {
+ if(componentMap.containsKey("name")) {
+ String stackComponentName = null;
+ String stackServiceName = null;
+ Integer desiredCount = 0;
+ String assemblyComponentName = (String)componentMap.get("name");
+ for(Map.Entry<String, String> componentEntry : componentNameMappings.entrySet()) {
+ if(componentEntry.getValue().equalsIgnoreCase(assemblyComponentName)) {
+ stackComponentName = componentEntry.getKey();
+ break;
+ }
+ }
+ if(stackComponentName != null) {
+ stackServiceName =
+ ambariMetaInfo.getComponentToService(stackId.getStackName(),
+ stackId.getStackVersion(), stackComponentName);
+ if(componentMap.containsKey("number_of_containers")) {
+ desiredCount = ((Double)componentMap.get("number_of_containers")).intValue();
+ }
+ }
+ if(stackComponentName != null && stackServiceName != null) {
+ if(!serviceComponentsMap.containsKey(stackServiceName)) {
+ serviceComponentsMap.put(stackServiceName, new HashMap<String, Integer>());
+ }
+ Map<String, Integer> componentsMap = serviceComponentsMap.get(stackServiceName);
+ componentsMap.put(stackComponentName, desiredCount);
+ }
+ }
+ }
+ }
+ return serviceComponentsMap;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
index 56196c1..893cdb2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
@@ -89,6 +89,8 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
// Services
public static final String SERVICE_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "cluster_name");
public static final String SERVICE_SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "service_name");
+ public static final String SERVICE_STACK_SERVICE_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "stack_service_name");
+ public static final String SERVICE_SERVICE_GROUP_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "service_group_name");
public static final String SERVICE_SERVICE_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "state");
public static final String SERVICE_MAINTENANCE_STATE_PROPERTY_ID = PropertyHelper.getPropertyId("ServiceInfo", "maintenance_state");
@@ -109,7 +111,6 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
SERVICE_CLUSTER_NAME_PROPERTY_ID,
SERVICE_SERVICE_NAME_PROPERTY_ID}));
-
private MaintenanceStateHelper maintenanceStateHelper;
/**
@@ -192,6 +193,10 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
response.getClusterName(), requestedIds);
setResourceProperty(resource, SERVICE_SERVICE_NAME_PROPERTY_ID,
response.getServiceName(), requestedIds);
+ setResourceProperty(resource, SERVICE_STACK_SERVICE_NAME_PROPERTY_ID,
+ response.getStackServiceName(), requestedIds);
+ setResourceProperty(resource, SERVICE_SERVICE_GROUP_NAME_PROPERTY_ID,
+ response.getServiceGroupName(), requestedIds);
setResourceProperty(resource, SERVICE_SERVICE_STATE_PROPERTY_ID,
calculateServiceState(response.getClusterName(), response.getServiceName()),
requestedIds);
@@ -199,7 +204,7 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
response.getMaintenanceState(), requestedIds);
Map<String, Object> serviceSpecificProperties = getServiceSpecificProperties(
- response.getClusterName(), response.getServiceName(), requestedIds);
+ response.getClusterName(), response.getServiceName(), response.getStackServiceName(), requestedIds);
for (Map.Entry<String, Object> entry : serviceSpecificProperties.entrySet()) {
setResourceProperty(resource, entry.getKey(), entry.getValue(), requestedIds);
@@ -322,6 +327,8 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
ServiceRequest svcRequest = new ServiceRequest(
(String) properties.get(SERVICE_CLUSTER_NAME_PROPERTY_ID),
(String) properties.get(SERVICE_SERVICE_NAME_PROPERTY_ID),
+ (String) properties.get(SERVICE_STACK_SERVICE_NAME_PROPERTY_ID),
+ (String) properties.get(SERVICE_SERVICE_GROUP_NAME_PROPERTY_ID),
(String) properties.get(SERVICE_SERVICE_STATE_PROPERTY_ID));
Object o = properties.get(SERVICE_MAINTENANCE_STATE_PROPERTY_ID);
@@ -341,6 +348,14 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
return;
}
Clusters clusters = getManagementController().getClusters();
+ for(ServiceRequest request: requests) {
+ if(StringUtils.isBlank(request.getStackServiceName())) {
+ request.setStackServiceName(request.getServiceName());
+ }
+ if(StringUtils.isBlank(request.getServiceGroupName())) {
+ request.setServiceGroupName("CORE");
+ }
+ }
// do all validation checks
validateCreateRequests(requests, clusters);
@@ -351,7 +366,8 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
State state = State.INIT;
// Already checked that service does not exist
- Service s = serviceFactory.createNew(cluster, request.getServiceName());
+ Service s = serviceFactory.createNew(
+ cluster, request.getServiceName(), request.getStackServiceName(), request.getServiceGroupName());
s.setDesiredState(state);
s.setDesiredStackVersion(cluster.getDesiredStackVersion());
@@ -848,9 +864,10 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
* @param serviceName service name
* @param requestedIds relevant request property ids
*/
- private Map<String, Object> getServiceSpecificProperties(String clusterName, String serviceName, Set<String> requestedIds) {
+ private Map<String, Object> getServiceSpecificProperties(String clusterName, String serviceName,
+ String stackServiceName, Set<String> requestedIds) {
Map<String, Object> serviceSpecificProperties = new HashMap<String, Object>();
- if (serviceName.equals("KERBEROS")) {
+ if (stackServiceName.equals("KERBEROS")) {
// Only include details on whether the KDC administrator credentials are set and correct if
// implicitly (Service/attributes) or explicitly (Service/attributes/kdc_...) queried
if (requestedIds.contains(SERVICE_ATTRIBUTES_PROPERTY_ID) ||
@@ -895,15 +912,22 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
for (ServiceRequest request : requests) {
final String clusterName = request.getClusterName();
final String serviceName = request.getServiceName();
+ final String stackServiceName = request.getStackServiceName();
+ final String serviceGroupName = request.getServiceGroupName();
+
Validate.notEmpty(clusterName, "Cluster name should be provided when creating a service");
Validate.notEmpty(serviceName, "Service name should be provided when creating a service");
+ Validate.notEmpty(stackServiceName, "Stack service name should be provided when creating a service");
+ Validate.notEmpty(serviceGroupName, "Service group name should be provided when creating a service");
if (LOG.isDebugEnabled()) {
LOG.debug("Received a createService request"
- + ", clusterName=" + clusterName + ", serviceName=" + serviceName + ", request=" + request);
+ + ", clusterName=" + clusterName + ", serviceName=" + serviceName + ", stackServiceName=" + stackServiceName
+ + ", serviceGroupName=" + serviceGroupName + ", request=" + request);
}
- if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER, getClusterResourceId(clusterName), RoleAuthorization.SERVICE_ADD_DELETE_SERVICES)) {
+ if(!AuthorizationHelper.isAuthorized(ResourceType.CLUSTER,
+ getClusterResourceId(clusterName), RoleAuthorization.SERVICE_ADD_DELETE_SERVICES)) {
throw new AuthorizationException("The user is not authorized to create services");
}
@@ -946,7 +970,7 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
StackId stackId = cluster.getDesiredStackVersion();
if (!ambariMetaInfo.isValidService(stackId.getStackName(),
- stackId.getStackVersion(), request.getServiceName())) {
+ stackId.getStackVersion(), request.getStackServiceName())) {
throw new IllegalArgumentException("Unsupported or invalid service in stack, clusterName=" + clusterName
+ ", serviceName=" + serviceName + ", stackInfo=" + stackId.getStackId());
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
index b8ed215..bdb1087 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ViewInstanceResourceProvider.java
@@ -352,7 +352,7 @@ public class ViewInstanceResourceProvider extends AbstractAuthorizedResourceProv
}
if (properties.containsKey(CLUSTER_HANDLE_PROPERTY_ID)) {
- viewInstanceEntity.setClusterHandle((String) properties.get(CLUSTER_HANDLE_PROPERTY_ID));
+ viewInstanceEntity.setClusterHandle(Long.valueOf((String) properties.get(CLUSTER_HANDLE_PROPERTY_ID)));
}
if (properties.containsKey(CLUSTER_TYPE_PROPERTY_ID)) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCache.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCache.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCache.java
new file mode 100644
index 0000000..84bb32a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCache.java
@@ -0,0 +1,124 @@
+/**
+ * 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.servicegroup.cache;
+
+import net.sf.ehcache.CacheException;
+import net.sf.ehcache.Ehcache;
+import net.sf.ehcache.Element;
+import net.sf.ehcache.constructs.blocking.LockTimeoutException;
+import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory;
+import net.sf.ehcache.constructs.blocking.UpdatingSelfPopulatingCache;
+import net.sf.ehcache.statistics.StatisticsGateway;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.net.SocketTimeoutException;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.Map;
+
+public class ServiceGroupCache extends UpdatingSelfPopulatingCache {
+
+ private final static Logger LOG = LoggerFactory.getLogger(ServiceGroupCache.class);
+ private static AtomicInteger printCacheStatsCounter = new AtomicInteger(0);
+
+ /**
+ * Creates a SelfPopulatingCache.
+ *
+ * @param cache @Cache
+ * @param factory @CacheEntryFactory
+ */
+ public ServiceGroupCache(Ehcache cache, UpdatingCacheEntryFactory factory) throws CacheException {
+ super(cache, factory);
+ }
+
+
+
+ public ServiceGroupCacheValue getServiceGroupCacheValue(ServiceGroupCacheKey key)
+ throws IllegalArgumentException, IOException {
+
+ LOG.debug("Fetching service group cache value with key: " + key);
+ // Make sure key is valid
+ validateKey(key);
+
+ Element element = null;
+ try {
+ element = get(key);
+ } catch (LockTimeoutException le) {
+ // Ehcache masks the Socket Timeout to look as a LockTimeout
+ Throwable t = le.getCause();
+ if (t instanceof CacheException) {
+ t = t.getCause();
+ if (t instanceof SocketTimeoutException) {
+ throw new SocketTimeoutException(t.getMessage());
+ }
+ }
+ }
+
+ ServiceGroupCacheValue cacheValue = null;
+ if (element != null && element.getObjectValue() != null) {
+ cacheValue = (ServiceGroupCacheValue) element.getObjectValue();
+ LOG.debug("Returning service group value from cache: " + cacheValue);
+ }
+ return cacheValue;
+ }
+
+ public Map<String, Object> getResponseFromCache(ServiceGroupCacheKey key) throws IllegalArgumentException, IOException {
+ LOG.debug("Fetching service group with key: " + key);
+
+ // Make sure key is valid
+ validateKey(key);
+
+ Element element = null;
+ try {
+ element = get(key);
+ } catch (LockTimeoutException le) {
+ // Ehcache masks the Socket Timeout to look as a LockTimeout
+ Throwable t = le.getCause();
+ if (t instanceof CacheException) {
+ t = t.getCause();
+ if (t instanceof SocketTimeoutException) {
+ throw new SocketTimeoutException(t.getMessage());
+ }
+ }
+ }
+
+ Map<String, Object> response = null;
+ if (element != null && element.getObjectValue() != null) {
+ ServiceGroupCacheValue value = (ServiceGroupCacheValue) element.getObjectValue();
+ LOG.debug("Returning service group value from cache: " + value);
+ response = value.getResponse();
+ }
+ return response;
+ }
+
+
+ private void validateKey(ServiceGroupCacheKey key) throws IllegalArgumentException {
+ StringBuilder msg = new StringBuilder("Invalid service group key requested.");
+ boolean throwException = false;
+
+ if (key.getServiceGroupName() == null) {
+ msg.append(" No service group name provided.");
+ throwException = true;
+ }
+
+ if (throwException) {
+ throw new IllegalArgumentException(msg.toString());
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheEntryFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheEntryFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheEntryFactory.java
new file mode 100644
index 0000000..718243c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheEntryFactory.java
@@ -0,0 +1,102 @@
+/**
+ * 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.servicegroup.cache;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import net.sf.ehcache.constructs.blocking.UpdatingCacheEntryFactory;
+import org.apache.ambari.server.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+
+import java.util.Map;
+import org.apache.commons.io.IOUtils;
+
+@Singleton
+public class ServiceGroupCacheEntryFactory implements UpdatingCacheEntryFactory {
+ private final static Logger LOG = LoggerFactory.getLogger(ServiceGroupCacheEntryFactory.class);
+ private final String dashEndpoint;
+ private final Gson gson;
+
+ @Inject
+ public ServiceGroupCacheEntryFactory(Configuration configuration) {
+ gson = new Gson();
+ dashEndpoint = configuration.getDashApiEndpoint();
+ }
+
+ @Override
+ public Object createEntry(Object key) throws Exception {
+ LOG.debug("Creating cache entry since none exists, key = " + key);
+ ServiceGroupCacheKey serviceGroupCacheKey = (ServiceGroupCacheKey) key;
+
+ Map<String, Object> response = null;
+ String urlString = dashEndpoint + "/" + serviceGroupCacheKey.getServiceGroupName().toLowerCase();
+ try {
+ URL url = new URL(urlString);
+ HttpURLConnection httpRequest = (HttpURLConnection) url.openConnection();
+ InputStream inputStream = httpRequest.getInputStream();
+ String jsonResponse = IOUtils.toString(inputStream, "UTF-8");
+ response = gson.fromJson(jsonResponse, new TypeToken<Map<String, Object>>() {
+ }.getType());
+ } catch (Exception e) {
+ LOG.error("Failed to get response from DASH endpoint " + dashEndpoint + "Exception : " + e.getMessage());
+ response = null;
+ }
+ ServiceGroupCacheValue value = null;
+ if (response != null) {
+ value = new ServiceGroupCacheValue(System.currentTimeMillis(), response);
+ LOG.debug("Created cache entry: " + value);
+ }
+ return value;
+ }
+
+ @Override
+ public void updateEntryValue(Object key, Object value) throws Exception {
+ ServiceGroupCacheKey serviceGroupCacheKey = (ServiceGroupCacheKey) key;
+ ServiceGroupCacheValue existingValue = (ServiceGroupCacheValue) value;
+ long fetchTime = existingValue.getFetchTime();
+ if(System.currentTimeMillis() - fetchTime > 60000) {
+ LOG.debug("Updating service group cache entry for key = " + key);
+ Map<String, Object> response = null;
+ String urlString = dashEndpoint + "/" + serviceGroupCacheKey.getServiceGroupName().toLowerCase();
+ try {
+ URL url = new URL(urlString);
+ HttpURLConnection httpRequest = (HttpURLConnection) url.openConnection();
+ InputStream inputStream = httpRequest.getInputStream();
+ String jsonResponse = IOUtils.toString(inputStream, "UTF-8");
+ response = gson.fromJson(jsonResponse, new TypeToken<Map<String, Object>>() {
+ }.getType());
+ } catch (Exception e) {
+ LOG.error("Failed to get response from Dash endpoint " + dashEndpoint + "Exception : " + e.getMessage());
+ response = null;
+ }
+ if (response != null) {
+ existingValue.setFetchTime(System.currentTimeMillis());
+ existingValue.setResponse(response);
+ LOG.debug("Updated cache entry for key = " + key + ", newValue = " + value);
+ }
+ } else {
+ LOG.debug("Skipping updating service group cache entry for key = " + key);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheKey.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheKey.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheKey.java
new file mode 100644
index 0000000..b45e870
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheKey.java
@@ -0,0 +1,55 @@
+/**
+ * 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.servicegroup.cache;
+
+public class ServiceGroupCacheKey {
+ private String serviceGroupName;
+
+ public ServiceGroupCacheKey(String serviceGroupName) {
+ this.serviceGroupName = serviceGroupName;
+ }
+
+ public String getServiceGroupName() {
+ return serviceGroupName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ServiceGroupCacheKey that = (ServiceGroupCacheKey) o;
+
+ if (!serviceGroupName.equals(that.serviceGroupName))
+ return false;
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = serviceGroupName.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "ServiceGroupCacheKey { " +
+ "serviceGroupName=" + serviceGroupName +
+ " }";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheProvider.java
new file mode 100644
index 0000000..2571216
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheProvider.java
@@ -0,0 +1,114 @@
+/**
+ * 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.servicegroup.cache;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.CacheManager;
+import net.sf.ehcache.config.CacheConfiguration;
+import net.sf.ehcache.config.PersistenceConfiguration;
+import net.sf.ehcache.config.SizeOfPolicyConfiguration;
+import net.sf.ehcache.config.SizeOfPolicyConfiguration.MaxDepthExceededBehavior;
+import net.sf.ehcache.store.MemoryStoreEvictionPolicy;
+import org.apache.ambari.server.configuration.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static net.sf.ehcache.config.PersistenceConfiguration.Strategy;
+
+@Singleton
+public class ServiceGroupCacheProvider {
+ private ServiceGroupCache serviceGroupCache;
+ private volatile boolean isCacheInitialized = false;
+ public static final String SERVICE_GROUP_CACHE_MANAGER_NAME = "ServiceGroupCacheManager";
+ public static final String SERVICE_GROUP_CACHE_INSTANCE_NAME = "ServiceGroupCache";
+
+ Configuration configuration;
+ ServiceGroupCacheEntryFactory cacheEntryFactory;
+ private final static Logger LOG = LoggerFactory.getLogger(ServiceGroupCacheProvider.class);
+
+ @Inject
+ public ServiceGroupCacheProvider(Configuration configuration,
+ ServiceGroupCacheEntryFactory cacheEntryFactory) {
+ this.configuration = configuration;
+ this.cacheEntryFactory = cacheEntryFactory;
+ }
+
+ private synchronized void initializeCache() {
+ // Check in case of contention to avoid ObjectExistsException
+ if (isCacheInitialized) {
+ return;
+ }
+
+ System.setProperty("net.sf.ehcache.skipUpdateCheck", "true");
+
+ net.sf.ehcache.config.Configuration managerConfig =
+ new net.sf.ehcache.config.Configuration();
+ managerConfig.setName(SERVICE_GROUP_CACHE_MANAGER_NAME);
+
+ // Set max heap available to the cache manager
+ managerConfig.setMaxBytesLocalHeap("10%");
+
+ //Create a singleton CacheManager using defaults
+ CacheManager manager = CacheManager.create(managerConfig);
+
+ // TODO: Add service group cache timeout configs
+ LOG.info("Creating service group cache with timeouts => ttl = " +
+ configuration.getMetricCacheTTLSeconds() + ", idle = " +
+ configuration.getMetricCacheIdleSeconds());
+
+ // Create a Cache specifying its configuration.
+ CacheConfiguration cacheConfiguration = createCacheConfiguration();
+ Cache cache = new Cache(cacheConfiguration);
+
+ // Decorate with UpdatingSelfPopulatingCache
+ serviceGroupCache = new ServiceGroupCache(cache, cacheEntryFactory);
+
+ LOG.info("Registering service group cache with provider: name = " +
+ cache.getName() + ", guid: " + cache.getGuid());
+ manager.addCache(serviceGroupCache);
+ isCacheInitialized = true;
+ }
+
+ // Having this as a separate public method for testing/mocking purposes
+ public CacheConfiguration createCacheConfiguration() {
+
+ CacheConfiguration cacheConfiguration = new CacheConfiguration()
+ .name(SERVICE_GROUP_CACHE_INSTANCE_NAME)
+ .timeToLiveSeconds(configuration.getMetricCacheTTLSeconds()) // 1 hour
+ .timeToIdleSeconds(configuration.getMetricCacheIdleSeconds()) // 5 minutes
+ .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LRU)
+ .sizeOfPolicy(new SizeOfPolicyConfiguration() // Set sizeOf policy to continue on max depth reached - avoid OOM
+ .maxDepth(10000)
+ .maxDepthExceededBehavior(MaxDepthExceededBehavior.CONTINUE))
+ .eternal(false)
+ .persistence(new PersistenceConfiguration()
+ .strategy(Strategy.NONE.name()));
+
+ return cacheConfiguration;
+ }
+
+ public ServiceGroupCache getServiceGroupCache() {
+ if (!isCacheInitialized) {
+ initializeCache();
+ }
+ return serviceGroupCache;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheValue.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheValue.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheValue.java
new file mode 100644
index 0000000..690c47a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/servicegroup/cache/ServiceGroupCacheValue.java
@@ -0,0 +1,135 @@
+/**
+ * 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.servicegroup.cache;
+
+
+import java.util.Map;
+import java.util.ArrayList;
+
+/**
+ * Wrapper object for service group cache value.
+ */
+public class ServiceGroupCacheValue {
+ private long fetchTime;
+ private Map<String, Object> response = null;
+ private String applicationId = null;
+ private String state;
+ private String lifetime = null;
+ private Map<String, String> quicklinks = null;
+ private Integer numContainers;
+ private Integer expectedContainers;
+ public ArrayList<Map<String, Object>> containers = null;
+
+
+ public ServiceGroupCacheValue(long fetchTime, Map<String, Object> response) {
+ this.fetchTime = fetchTime;
+ this.response = response;
+ parseResponse();
+ }
+
+ public Map<String, Object> getResponse() {
+ return response;
+ }
+
+ public void setResponse(Map<String, Object> response) {
+ this.response = response;
+ parseResponse();
+ }
+
+ public Long getFetchTime() {
+ return fetchTime;
+ }
+
+ public void setFetchTime(Long fetchTime) {
+ this.fetchTime = fetchTime;
+ }
+
+ public String getApplicationId() {
+ return applicationId;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public Map<String, String> getQuicklinks() {
+ return quicklinks;
+ }
+
+ public Integer getNumContainers() {
+ return numContainers;
+ }
+
+ public Integer getExpectedContainers() {
+ return expectedContainers;
+ }
+
+ public String getLifetime() {
+ return lifetime;
+ }
+
+ public ArrayList<Map<String, Object>> getContainers() {
+ return containers;
+ }
+
+ public void parseResponse() {
+ if(response != null) {
+ if(response.containsKey("id")) {
+ applicationId = (String) response.get("id");
+ }
+
+ if(response.containsKey("quicklinks")) {
+ quicklinks = (Map<String, String>) response.get("quicklinks");
+ }
+
+ if(response.containsKey("state")) {
+ state = (String) response.get("state");
+ }
+
+ if(response.containsKey("lifetime")) {
+ lifetime = (String) response.get("lifetime");
+ }
+
+ if(response.containsKey("number_of_containers")) {
+ numContainers = ((Double) response.get("number_of_containers")).intValue();
+ }
+
+ if(response.containsKey("expected_number_of_containers")) {
+ expectedContainers = ((Double) response.get("expected_number_of_containers")).intValue();
+ }
+
+ if(response.containsKey("containers")) {
+ containers = (ArrayList<Map<String, Object>>) response.get("containers");
+
+ }
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "ServiceGroupCacheValue { " +
+ "fetchTime=" + fetchTime +
+ ", applicationId=" + applicationId +
+ ", state=" + state +
+ ", quicklinks=" + quicklinks +
+ ", lifetime=" + lifetime +
+ ", numContainers=" + numContainers +
+ ", expectedContainers=" + expectedContainers +
+ " }";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/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 99e4ccd..7e6fb09 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
@@ -76,6 +76,7 @@ public interface Resource {
enum InternalType {
Cluster,
Service,
+ ServiceGroup,
Setting,
Host,
Component,
@@ -194,6 +195,7 @@ public interface Resource {
*/
public static final Type Cluster = InternalType.Cluster.getType();
public static final Type Service = InternalType.Service.getType();
+ public static final Type ServiceGroup = InternalType.ServiceGroup.getType();
public static final Type Setting = InternalType.Setting.getType();
public static final Type Host = InternalType.Host.getType();
public static final Type Component = InternalType.Component.getType();
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
index d35fc1a..436258f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/utilities/DatabaseChecker.java
@@ -88,8 +88,8 @@ public class DatabaseChecker {
if (serviceDesiredStateEntity == null) {
checkPassed = false;
LOG.error(String.format("ServiceDesiredStateEntity is null for " +
- "ServiceComponentDesiredStateEntity, clusterName=%s, serviceName=%s ",
- clusterEntity.getClusterName(), clusterServiceEntity.getServiceName()));
+ "ServiceComponentDesiredStateEntity, clusterName=%s, serviceName=%s, stackServiceName=%s ",
+ clusterEntity.getClusterName(), clusterServiceEntity.getServiceName(), clusterServiceEntity.getStackServiceName()));
}
Collection<ServiceComponentDesiredStateEntity> scDesiredStateEntities =
clusterServiceEntity.getServiceComponentDesiredStateEntities();
@@ -97,8 +97,8 @@ public class DatabaseChecker {
scDesiredStateEntities.isEmpty()) {
checkPassed = false;
LOG.error(String.format("serviceComponentDesiredStateEntities is null or empty for " +
- "ServiceComponentDesiredStateEntity, clusterName=%s, serviceName=%s ",
- clusterEntity.getClusterName(), clusterServiceEntity.getServiceName()));
+ "ServiceComponentDesiredStateEntity, clusterName=%s, serviceName=%s, stackServiceName=%s ",
+ clusterEntity.getClusterName(), clusterServiceEntity.getServiceName(), clusterServiceEntity.getStackServiceName()));
} else {
for (ServiceComponentDesiredStateEntity scDesiredStateEnity : scDesiredStateEntities) {
@@ -227,22 +227,24 @@ public class DatabaseChecker {
for (ClusterServiceEntity clusterServiceEntity : clusterServiceEntities) {
if (!State.INIT.equals(clusterServiceEntity.getServiceDesiredStateEntity().getDesiredState())) {
String serviceName = clusterServiceEntity.getServiceName();
- ServiceInfo serviceInfo = ambariMetaInfo.getService(stack.getName(), stack.getVersion(), serviceName);
+ String stackServiceName = clusterServiceEntity.getStackServiceName();
+ String serviceGroupName = clusterServiceEntity.getServiceGroupName();
+ ServiceInfo serviceInfo = ambariMetaInfo.getService(stack.getName(), stack.getVersion(), stackServiceName);
for (String configTypeName : serviceInfo.getConfigTypeAttributes().keySet()) {
if (selectedCountForType.get(configTypeName) == null) {
checkPassed = false;
- LOG.error("ClusterConfigMapping does not contain mapping for service=" + serviceName + " type_name="
- + configTypeName);
+ LOG.error("ClusterConfigMapping does not contain mapping for serviceName=" + serviceName
+ + " stackServiceName=" + stackServiceName + " serviceGroupName=" + serviceGroupName + " type_name=" + configTypeName);
} else {
// Check that for each config type exactly one is selected
if (selectedCountForType.get(configTypeName) == 0) {
checkPassed = false;
- LOG.error("ClusterConfigMapping selected count is 0 for service=" + serviceName + " type_name="
- + configTypeName);
+ LOG.error("ClusterConfigMapping selected count is 0 for serviceName=" + serviceName
+ + " stackServiceName=" + stackServiceName + " serviceGroupName=" + serviceGroupName + " type_name=" + configTypeName);
} else if (selectedCountForType.get(configTypeName) > 1) {
checkPassed = false;
- LOG.error("ClusterConfigMapping selected count is more than 1 for service=" + serviceName
- + " type_name=" + configTypeName);
+ LOG.error("ClusterConfigMapping selected count is more than 1 for serviceName=" + serviceName
+ + " stackServiceName=" + stackServiceName + " serviceGroupName=" + serviceGroupName + " type_name="+ configTypeName);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index 1079806..d91da98 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -38,6 +38,16 @@ public abstract class AmbariEvent {
SERVICE_REMOVED_SUCCESS,
/**
+ * A service group was successfully installed.
+ */
+ SERVICE_GROUP_INSTALL_SUCCESS,
+
+ /**
+ * A service group was successfully removed.
+ */
+ SERVICE_GROUP_REMOVED_SUCCESS,
+
+ /**
* A service component was successfully installed.
*/
SERVICE_COMPONENT_INSTALL_SUCCESS,
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentInstalledEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentInstalledEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentInstalledEvent.java
index 3ad1492..7e60980 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentInstalledEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentInstalledEvent.java
@@ -37,11 +37,11 @@ public class ServiceComponentInstalledEvent extends ServiceEvent {
* @param hostName
*/
public ServiceComponentInstalledEvent(long clusterId, String stackName,
- String stackVersion, String serviceName, String componentName,
+ String stackVersion, String serviceName, String stackServiceName, String serviceGroupName, String componentName,
String hostName, boolean recoveryEnabled) {
super(AmbariEventType.SERVICE_COMPONENT_INSTALL_SUCCESS, clusterId,
stackName,
- stackVersion, serviceName);
+ stackVersion, serviceName, stackServiceName, serviceGroupName);
m_componentName = componentName;
m_hostName = hostName;
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
index 6f3fa95..822d325 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceComponentUninstalledEvent.java
@@ -33,15 +33,16 @@ public class ServiceComponentUninstalledEvent extends ServiceEvent {
* @param stackName
* @param stackVersion
* @param serviceName
+ * @param serviceGroupName
* @param componentName
* @param hostName
*/
public ServiceComponentUninstalledEvent(long clusterId, String stackName,
- String stackVersion, String serviceName, String componentName,
+ String stackVersion, String serviceName, String stackServiceName, String serviceGroupName, String componentName,
String hostName, boolean recoveryEnabled) {
super(AmbariEventType.SERVICE_COMPONENT_UNINSTALLED_SUCCESS, clusterId,
stackName,
- stackVersion, serviceName);
+ stackVersion, serviceName, stackServiceName, serviceGroupName);
m_componentName = componentName;
m_hostName = hostName;
http://git-wip-us.apache.org/repos/asf/ambari/blob/b88db3cc/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
index 3bc5c17..837e299 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/ServiceEvent.java
@@ -29,6 +29,16 @@ public abstract class ServiceEvent extends ClusterEvent {
protected final String m_serviceName;
/**
+ * The name of the real service.
+ */
+ protected final String m_stackServiceName;
+
+ /**
+ * The name of the service group.
+ */
+ protected final String m_serviceGroupName;
+
+ /**
* The name of the services' stack.
*/
protected final String m_stackName;
@@ -44,12 +54,14 @@ public abstract class ServiceEvent extends ClusterEvent {
* @param eventType
* @param clusterId
*/
- public ServiceEvent(AmbariEventType eventType, long clusterId,
- String stackName, String stackVersion, String serviceName) {
+ public ServiceEvent(AmbariEventType eventType, long clusterId, String stackName, String stackVersion,
+ String serviceName, String stackServiceName, String serviceGroupName) {
super(eventType, clusterId);
m_stackName = stackName;
m_stackVersion = stackVersion;
m_serviceName = serviceName;
+ m_stackServiceName = stackServiceName;
+ m_serviceGroupName = serviceGroupName;
}
/**
@@ -60,6 +72,20 @@ public abstract class ServiceEvent extends ClusterEvent {
}
/**
+ * @return the stackServiceName (never {@code null}).
+ */
+ public String getStackServiceName() {
+ return m_stackServiceName;
+ }
+
+ /**
+ * @return the service group name (never {@code null}).
+ */
+ public String getServiceGroupName() {
+ return m_serviceGroupName;
+ }
+
+ /**
* @return the stackName (never {@code null}).
*/
public String getStackName() {