You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by ad...@apache.org on 2018/11/15 20:38:57 UTC
[ambari] branch trunk updated: AMBARI-24901. Handle complex "Add
Service" request in ServiceResourceProvider (#2611)
This is an automated email from the ASF dual-hosted git repository.
adoroszlai pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ambari.git
The following commit(s) were added to refs/heads/trunk by this push:
new 1d87a0a AMBARI-24901. Handle complex "Add Service" request in ServiceResourceProvider (#2611)
1d87a0a is described below
commit 1d87a0a1ee8d5202ed1894bc2917fc8ab7d569fa
Author: Doroszlai, Attila <64...@users.noreply.github.com>
AuthorDate: Thu Nov 15 21:38:53 2018 +0100
AMBARI-24901. Handle complex "Add Service" request in ServiceResourceProvider (#2611)
---
.../ambari/server/api/services/ServiceService.java | 8 +-
.../server/controller/AddServiceRequest.java | 26 ++++-
.../internal/ServiceResourceProvider.java | 38 ++++++
.../ambari/server/controller/internal/Stack.java | 5 +
.../server/topology/addservice/AddServiceInfo.java | 47 ++++++++
.../addservice/AddServiceOrchestrator.java | 127 +++++++++++++++++++++
.../addservice/ResourceProviderAdapter.java | 95 +++++++++++++++
.../server/controller/AddServiceRequestTest.java | 2 +-
8 files changed, 339 insertions(+), 9 deletions(-)
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
index d12cbc4..9440f39 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceService.java
@@ -153,7 +153,7 @@ public class ServiceService extends BaseService {
@Path("{serviceName}")
@Produces(MediaType.TEXT_PLAIN)
@ApiOperation(value = "Creates a service",
- nickname = "ServiceService#createServices"
+ nickname = "ServiceService#createService"
)
@ApiImplicitParams({
@ApiImplicitParam(dataType = SERVICE_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
@@ -176,7 +176,7 @@ public class ServiceService extends BaseService {
/**
* Handles: POST /clusters/{clusterId}/services
- * Create multiple services.
+ * Create services, possibly more than one.
*
* @param body http body
* @param headers http headers
@@ -185,8 +185,8 @@ public class ServiceService extends BaseService {
*/
@POST
@Produces(MediaType.TEXT_PLAIN)
- @ApiOperation(value = "Creates a service",
- nickname = "ServiceService#createService"
+ @ApiOperation(value = "Creates services",
+ nickname = "ServiceService#createServices"
)
@ApiImplicitParams({
@ApiImplicitParam(dataType = SERVICE_REQUEST_TYPE, paramType = PARAM_TYPE_BODY, allowMultiple = true)
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java
index 83a66d8..22a32ce 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AddServiceRequest.java
@@ -22,7 +22,11 @@ import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Collections.emptySet;
import static org.apache.ambari.server.controller.internal.BaseClusterRequest.PROVISION_ACTION_PROPERTY;
import static org.apache.ambari.server.controller.internal.ProvisionClusterRequest.CONFIG_RECOMMENDATION_STRATEGY;
+import static org.apache.ambari.server.controller.internal.ServiceResourceProvider.OPERATION_TYPE;
+import static org.apache.ambari.server.topology.Configurable.CONFIGURATIONS;
+import java.io.IOException;
+import java.io.UncheckedIOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -39,6 +43,8 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableSet;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@@ -50,12 +56,16 @@ import io.swagger.annotations.ApiModelProperty;
@JsonInclude(JsonInclude.Include.NON_EMPTY)
public final class AddServiceRequest {
- static final String OPERATION_TYPE = "operation_type";
static final String STACK_NAME = "stack_name";
static final String STACK_VERSION = "stack_version";
static final String SERVICES = "services";
static final String COMPONENTS = "components";
+ public static final Set<String> TOP_LEVEL_PROPERTIES = ImmutableSet.of(
+ OPERATION_TYPE, CONFIG_RECOMMENDATION_STRATEGY, PROVISION_ACTION_PROPERTY,
+ STACK_NAME, STACK_VERSION, SERVICES, COMPONENTS, CONFIGURATIONS
+ );
+
private final OperationType operationType;
private final ConfigRecommendationStrategy recommendationStrategy;
private final ProvisionAction provisionAction;
@@ -73,7 +83,7 @@ public final class AddServiceRequest {
@JsonProperty(STACK_VERSION) String stackVersion,
@JsonProperty(SERVICES) Set<Service> services,
@JsonProperty(COMPONENTS)Set<Component> components,
- @JsonProperty(Configurable.CONFIGURATIONS) Collection<? extends Map<String, ?>> configs) {
+ @JsonProperty(CONFIGURATIONS) Collection<? extends Map<String, ?>> configs) {
this(operationType, recommendationStrategy, provisionAction, stackName, stackVersion, services, components,
Configurable.parseConfigs(configs));
}
@@ -99,6 +109,14 @@ public final class AddServiceRequest {
checkArgument(!this.services.isEmpty() || !this.components.isEmpty(), "Either services or components must be specified");
}
+ // TODO move to JsonUtils -- pick part of 0252c08d86f
+ public static AddServiceRequest of(String json) {
+ try {
+ return new ObjectMapper().readValue(json, AddServiceRequest.class);
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
@JsonProperty(OPERATION_TYPE)
@ApiModelProperty(name = OPERATION_TYPE)
@@ -148,8 +166,8 @@ public final class AddServiceRequest {
return configuration;
}
- @JsonProperty(Configurable.CONFIGURATIONS)
- @ApiModelProperty(name = Configurable.CONFIGURATIONS)
+ @JsonProperty(CONFIGURATIONS)
+ @ApiModelProperty(name = CONFIGURATIONS)
public Collection<Map<String, Map<String, ?>>> getConfigurationContents() {
return Configurable.convertConfigToMap(configuration);
}
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 936d767..6b561e8 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
@@ -38,6 +38,8 @@ import org.apache.ambari.server.ParentObjectNotFoundException;
import org.apache.ambari.server.RoleCommand;
import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.controller.AddServiceRequest;
+import org.apache.ambari.server.controller.AddServiceRequest.OperationType;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.KerberosHelper;
import org.apache.ambari.server.controller.MaintenanceStateHelper;
@@ -76,6 +78,7 @@ import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.State;
import org.apache.ambari.server.topology.STOMPComponentsDeleteHandler;
+import org.apache.ambari.server.topology.addservice.AddServiceOrchestrator;
import org.apache.ambari.spi.RepositoryType;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
@@ -136,6 +139,8 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
private static final String KERBEROS_ENABLED_PROPERTY_ID = PropertyHelper.getPropertyId(
"ServiceInfo", "kerberos_enabled");
+ public static final String OPERATION_TYPE = "operation_type";
+
protected static final String SERVICE_REPOSITORY_STATE = "ServiceInfo/repository_state";
//Parameters from the predicate
@@ -180,6 +185,7 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
PROPERTY_IDS.add(SSO_INTEGRATION_DESIRED_PROPERTY_ID);
PROPERTY_IDS.add(SSO_INTEGRATION_REQUIRES_KERBEROS_PROPERTY_ID);
PROPERTY_IDS.add(KERBEROS_ENABLED_PROPERTY_ID);
+ PROPERTY_IDS.add(OPERATION_TYPE);
// keys
KEY_PROPERTY_IDS.put(Resource.Type.Service, SERVICE_SERVICE_NAME_PROPERTY_ID);
@@ -197,6 +203,9 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
@Inject
private STOMPComponentsDeleteHandler STOMPComponentsDeleteHandler;
+ @Inject
+ private AddServiceOrchestrator addServiceOrchestrator;
+
/**
* Used to lookup the repository when creating services.
*/
@@ -232,6 +241,15 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
ResourceAlreadyExistsException,
NoSuchParentResourceException {
+ if (request.getProperties().size() == 1) {
+ Map<String, Object> requestProperties = request.getProperties().iterator().next();
+ if (isAddServiceRequest(requestProperties)) {
+ processAddServiceRequest(requestProperties, request.getRequestInfoProperties());
+ notifyCreate(Resource.Type.Service, request);
+ return getRequestStatus(null);
+ }
+ }
+
final Set<ServiceRequest> requests = new HashSet<>();
for (Map<String, Object> propertyMap : request.getProperties()) {
requests.add(getRequest(propertyMap));
@@ -376,6 +394,7 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
}
}
}
+ unsupportedProperties.removeAll(AddServiceRequest.TOP_LEVEL_PROPERTIES);
return unsupportedProperties;
}
@@ -1190,4 +1209,23 @@ public class ServiceResourceProvider extends AbstractControllerResourceProvider
}
}
+
+ private static boolean isAddServiceRequest(Map<String, Object> properties) {
+ return OperationType.ADD_SERVICE.name().equals(properties.get(OPERATION_TYPE));
+ }
+
+ private void processAddServiceRequest(Map<String, Object> requestProperties, Map<String, String> requestInfoProperties) throws NoSuchParentResourceException {
+ AddServiceRequest request = createAddServiceRequest(requestProperties, requestInfoProperties);
+ String clusterName = String.valueOf(requestProperties.get(SERVICE_CLUSTER_NAME_PROPERTY_ID));
+ try {
+ addServiceOrchestrator.processAddServiceRequest(getManagementController().getClusters().getCluster(clusterName), request);
+ } catch (AmbariException e) {
+ throw new NoSuchParentResourceException(e.getMessage(), e);
+ }
+ }
+
+ private static AddServiceRequest createAddServiceRequest(Map<String, Object> requestProperties, Map<String, String> requestInfoProperties) {
+ return AddServiceRequest.of(requestInfoProperties.get(Request.REQUEST_INFO_BODY_PROPERTY));
+ }
+
}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
index 0de4244..1c85d88 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/Stack.java
@@ -44,6 +44,7 @@ import org.apache.ambari.server.state.DependencyInfo;
import org.apache.ambari.server.state.PropertyDependencyInfo;
import org.apache.ambari.server.state.PropertyInfo;
import org.apache.ambari.server.state.ServiceInfo;
+import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.ValueAttributesInfo;
import org.apache.ambari.server.topology.Cardinality;
import org.apache.ambari.server.topology.Configuration;
@@ -151,6 +152,10 @@ public class Stack {
this(stack.getStackName(), stack.getStackVersion(), ambariManagementController);
}
+ public Stack(StackId stackId, AmbariManagementController ambariManagementController) throws AmbariException {
+ this(stackId.getStackName(), stackId.getStackVersion(), ambariManagementController);
+ }
+
/**
* Constructor.
*
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/AddServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/AddServiceInfo.java
new file mode 100644
index 0000000..24e530d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/AddServiceInfo.java
@@ -0,0 +1,47 @@
+/*
+ * 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.topology.addservice;
+
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Processed info for adding new services/components to an existing cluster.
+ */
+public final class AddServiceInfo {
+
+ private final String clusterName;
+ private final Map<String, Map<String, Set<String>>> newServices;
+
+ public AddServiceInfo(String clusterName, Map<String, Map<String, Set<String>>> newServices) {
+ this.clusterName = clusterName;
+ this.newServices = newServices;
+ }
+
+ public String clusterName() {
+ return clusterName;
+ }
+
+ /**
+ * New services to be added to the cluster: service -> component -> host
+ * This should include both explicitly requested services, and services of the requested components.
+ */
+ public Map<String, Map<String, Set<String>>> newServices() {
+ return newServices;
+ }
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/AddServiceOrchestrator.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/AddServiceOrchestrator.java
new file mode 100644
index 0000000..426c833
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/AddServiceOrchestrator.java
@@ -0,0 +1,127 @@
+/*
+ * 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.topology.addservice;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AddServiceRequest;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.internal.Stack;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.State;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class AddServiceOrchestrator {
+
+ private static final Logger LOG = LoggerFactory.getLogger(AddServiceOrchestrator.class);
+
+ @Inject
+ private ResourceProviderAdapter resourceProviders;
+
+ @Inject
+ private AmbariManagementController controller;
+
+ public void processAddServiceRequest(Cluster cluster, AddServiceRequest request) {
+ LOG.info("Received {} request for {}: {}", request.getOperationType(), cluster.getClusterName(), request);
+
+ AddServiceInfo validatedRequest = validate(cluster, request);
+ AddServiceInfo requestWithLayout = recommendLayout(validatedRequest);
+ createResources(requestWithLayout);
+ createHostTasks(requestWithLayout);
+ }
+
+ /**
+ * Performs basic validation of the request and
+ * fills in details about the requested services and components.
+ *
+ * @return validated information about the requested services
+ */
+ private AddServiceInfo validate(Cluster cluster, AddServiceRequest request) {
+ LOG.info("Validating {}", request);
+
+ Map<String, Map<String, Set<String>>> newServices = new LinkedHashMap<>();
+
+ StackId stackId = new StackId(request.getStackName(), request.getStackVersion());
+ try {
+ Stack stack = new Stack(stackId, controller);
+ Set<String> existingServices = cluster.getServices().keySet();
+ for (AddServiceRequest.Component requestedComponent : request.getComponents()) {
+ String serviceName = stack.getServiceForComponent(requestedComponent.getName());
+ if (serviceName == null) {
+ String msg = String.format("No service found for component %s in stack %s", requestedComponent.getName(), stackId);
+ LOG.error(msg);
+ throw new IllegalArgumentException(msg);
+ }
+ if (existingServices.contains(serviceName)) {
+ String msg = String.format("Service %s already exists in cluster %s", serviceName, cluster.getClusterName());
+ LOG.error(msg);
+ throw new IllegalArgumentException(msg);
+ }
+
+ newServices.computeIfAbsent(serviceName, __ -> new HashMap<>())
+ .computeIfAbsent(requestedComponent.getName(), __ -> new HashSet<>())
+ .add(requestedComponent.getFqdn());
+ }
+ } catch (AmbariException e) {
+ LOG.error("Stack {} not found", stackId);
+ throw new IllegalArgumentException(e);
+ }
+
+ return new AddServiceInfo(cluster.getClusterName(), newServices);
+ }
+
+ /**
+ * Requests layout recommendation from the stack advisor.
+ * @return new request, updated based on the recommended layout
+ * @throws IllegalArgumentException if the request cannot be satisfied
+ */
+ private AddServiceInfo recommendLayout(AddServiceInfo request) {
+ LOG.info("Recommending layout for {}", request);
+ // TODO implement
+ return request;
+ }
+
+ /**
+ * Creates the service, component and host component resources for the request.
+ */
+ private void createResources(AddServiceInfo request) {
+ LOG.info("Creating resources for {}", request);
+ resourceProviders.createServices(request);
+ resourceProviders.createComponents(request);
+ resourceProviders.createHostComponents(request);
+ resourceProviders.updateServiceDesiredState(request, State.INSTALLED);
+ resourceProviders.updateServiceDesiredState(request, State.STARTED);
+ }
+
+ private void createHostTasks(AddServiceInfo request) {
+ LOG.info("Creating host tasks for {}", request);
+ // TODO implement
+ }
+
+}
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/ResourceProviderAdapter.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/ResourceProviderAdapter.java
new file mode 100644
index 0000000..70b730e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/addservice/ResourceProviderAdapter.java
@@ -0,0 +1,95 @@
+/*
+ * 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.topology.addservice;
+
+import static java.util.stream.Collectors.toSet;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.internal.RequestImpl;
+import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
+import org.apache.ambari.server.controller.spi.ClusterController;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.ResourceProvider;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+import org.apache.ambari.server.state.State;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * Creates resources using the resource providers.
+ * Translates {@link AddServiceInfo} to internal requests accepted by those.
+ */
+public class ResourceProviderAdapter {
+
+ private static final Logger LOG = LoggerFactory.getLogger(ResourceProviderAdapter.class);
+
+ public void createServices(AddServiceInfo request) {
+ LOG.info("Creating service resources for {}", request);
+
+ Set<Map<String, Object>> properties = request.newServices().keySet().stream()
+ .map(service -> createServiceRequestProperties(request, service))
+ .collect(toSet());
+
+ Request internalRequest = new RequestImpl(null, properties, null, null);
+ ResourceProvider rp = getClusterController().ensureResourceProvider(Resource.Type.Service);
+ try {
+ rp.createResources(internalRequest);
+ } catch (UnsupportedPropertyException | SystemException | ResourceAlreadyExistsException | NoSuchParentResourceException e) {
+ LOG.error("Error creating services", e);
+ throw new RuntimeException("Error creating services", e);
+ }
+ }
+
+ private static Map<String, Object> createServiceRequestProperties(AddServiceInfo request, String service) {
+ ImmutableMap.Builder<String, Object> properties = ImmutableMap.builder();
+
+ properties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, request.clusterName());
+ properties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, service);
+ properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, State.INIT.name());
+
+ return properties.build();
+ }
+
+ private ClusterController getClusterController() {
+ return ClusterControllerHelper.getClusterController();
+ }
+
+ public void createComponents(AddServiceInfo request) {
+ LOG.info("Creating component resources for {}", request);
+ // TODO implement
+ }
+
+ public void createHostComponents(AddServiceInfo request) {
+ LOG.info("Creating host component resources for {}", request);
+ // TODO implement
+ }
+
+ public void updateServiceDesiredState(AddServiceInfo request, State desiredState) {
+ LOG.info("Updating service desired state to {} for {}", desiredState, request);
+ // TODO implement, reuse parts of AmbariContext#createAmbariServiceAndComponentResources
+ }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/AddServiceRequestTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/AddServiceRequestTest.java
index 2ed98b7..cb8d03b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/AddServiceRequestTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/AddServiceRequestTest.java
@@ -29,7 +29,7 @@ import static org.apache.ambari.server.controller.internal.BaseClusterRequest.PR
import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_AND_START;
import static org.apache.ambari.server.controller.internal.ProvisionAction.INSTALL_ONLY;
import static org.apache.ambari.server.controller.internal.ProvisionClusterRequest.CONFIG_RECOMMENDATION_STRATEGY;
-import static org.apache.ambari.server.serveraction.kerberos.KerberosServerAction.OPERATION_TYPE;
+import static org.apache.ambari.server.controller.internal.ServiceResourceProvider.OPERATION_TYPE;
import static org.apache.ambari.server.topology.ConfigRecommendationStrategy.ALWAYS_APPLY;
import static org.apache.ambari.server.topology.ConfigRecommendationStrategy.NEVER_APPLY;
import static org.junit.Assert.assertEquals;