You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by vb...@apache.org on 2017/11/02 15:59:34 UTC
[2/2] ambari git commit: AMBARI-22249. Add service group
dependencies.(vbrodetskyi)
AMBARI-22249. Add service group dependencies.(vbrodetskyi)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/16913b20
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/16913b20
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/16913b20
Branch: refs/heads/branch-feature-AMBARI-14714
Commit: 16913b201706c416cea6cf441f4800dd600568f1
Parents: eaeed81
Author: Vitaly Brodetskyi <vb...@hortonworks.com>
Authored: Thu Nov 2 17:59:14 2017 +0200
Committer: Vitaly Brodetskyi <vb...@hortonworks.com>
Committed: Thu Nov 2 17:59:14 2017 +0200
----------------------------------------------------------------------
.../resources/ResourceInstanceFactoryImpl.java | 4 +
...erviceGroupDependencyResourceDefinition.java | 41 ++
.../ServiceGroupResourceDefinition.java | 1 +
.../server/api/services/ServiceGroupKey.java | 89 ++++
.../api/services/ServiceGroupService.java | 151 +++++-
.../server/controller/ControllerModule.java | 2 +
.../controller/ResourceProviderFactory.java | 5 +-
.../ServiceGroupDependencyRequest.java | 75 +++
.../ServiceGroupDependencyResponse.java | 166 +++++++
.../AbstractControllerResourceProvider.java | 2 +
.../internal/DefaultProviderModule.java | 2 +
.../ServiceGroupDependencyResourceProvider.java | 484 +++++++++++++++++++
.../ambari/server/controller/spi/Resource.java | 2 +
.../server/orm/entities/ServiceGroupEntity.java | 29 +-
.../org/apache/ambari/server/state/Cluster.java | 4 +
.../ambari/server/state/ServiceGroup.java | 15 +-
.../server/state/ServiceGroupFactory.java | 6 +-
.../ambari/server/state/ServiceGroupImpl.java | 121 ++++-
.../server/state/cluster/ClusterImpl.java | 62 ++-
.../ambari/server/topology/AmbariContext.java | 12 +-
.../main/resources/Ambari-DDL-Derby-CREATE.sql | 9 +
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 9 +
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 9 +
.../resources/Ambari-DDL-Postgres-CREATE.sql | 9 +
.../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 9 +
.../resources/Ambari-DDL-SQLServer-CREATE.sql | 9 +
26 files changed, 1317 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
index 2c5edb7..c009cbb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ResourceInstanceFactoryImpl.java
@@ -112,6 +112,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
resourceDefinition = new ServiceGroupResourceDefinition();
break;
+ case ServiceGroupDependency:
+ resourceDefinition = new ServiceGroupDependencyResourceDefinition();
+ break;
+
case Service:
resourceDefinition = new ServiceResourceDefinition();
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupDependencyResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupDependencyResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupDependencyResourceDefinition.java
new file mode 100644
index 0000000..5c99161
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupDependencyResourceDefinition.java
@@ -0,0 +1,41 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.api.resources;
+
+
+import org.apache.ambari.server.controller.spi.Resource;
+
+public class ServiceGroupDependencyResourceDefinition extends BaseResourceDefinition {
+
+ /**
+ * Constructor.
+ */
+ public ServiceGroupDependencyResourceDefinition() {
+ super(Resource.Type.ServiceGroupDependency);
+ }
+
+ @Override
+ public String getPluralName() {
+ return "dependencies";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "dependency";
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupResourceDefinition.java
index 13bdd7b..1d123d8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ServiceGroupResourceDefinition.java
@@ -49,6 +49,7 @@ public class ServiceGroupResourceDefinition extends BaseResourceDefinition {
public Set<SubResourceDefinition> getSubResourceDefinitions() {
Set<SubResourceDefinition> subs = new HashSet<SubResourceDefinition>();
subs.add(new SubResourceDefinition(Resource.Type.Service));
+ subs.add(new SubResourceDefinition(Resource.Type.ServiceGroupDependency));
return subs;
}
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupKey.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupKey.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupKey.java
new file mode 100644
index 0000000..9389f0c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupKey.java
@@ -0,0 +1,89 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.api.services;
+
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ServiceGroupKey {
+
+ private Long clusterId;
+ private Long serviceGroupId;
+ private String clusterName;
+ private String serviceGroupName;
+
+ @JsonProperty("cluster_name")
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ @JsonProperty("service_group_name")
+ public String getServiceGroupName() {
+ return serviceGroupName;
+ }
+
+ public void setServiceGroupName(String serviceGroupName) {
+ this.serviceGroupName = serviceGroupName;
+ }
+
+ public Long getClusterId() {
+ return clusterId;
+ }
+
+ public void setClusterId(Long clusterId) {
+ this.clusterId = clusterId;
+ }
+
+ public Long getServiceGroupId() {
+ return serviceGroupId;
+ }
+
+ public void setServiceGroupId(Long serviceGroupId) {
+ this.serviceGroupId = serviceGroupId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ServiceGroupKey)) return false;
+
+ ServiceGroupKey that = (ServiceGroupKey) o;
+
+ if (clusterId != null ? !clusterId.equals(that.clusterId) : that.clusterId != null) return false;
+ if (clusterName != null ? !clusterName.equals(that.clusterName) : that.clusterName != null) return false;
+ if (serviceGroupId != null ? !serviceGroupId.equals(that.serviceGroupId) : that.serviceGroupId != null)
+ return false;
+ if (serviceGroupName != null ? !serviceGroupName.equals(that.serviceGroupName) : that.serviceGroupName != null)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int result = clusterId != null ? clusterId.hashCode() : 0;
+ result = 31 * result + (serviceGroupId != null ? serviceGroupId.hashCode() : 0);
+ result = 31 * result + (clusterName != null ? clusterName.hashCode() : 0);
+ result = 31 * result + (serviceGroupName != null ? serviceGroupName.hashCode() : 0);
+ return result;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupService.java
index 1e2eaf4..0638a06 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ServiceGroupService.java
@@ -35,6 +35,7 @@ import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.ServiceGroupDependencyResponse;
import org.apache.ambari.server.controller.ServiceGroupResponse;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.http.HttpStatus;
@@ -47,13 +48,14 @@ import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
-
/**
* Service responsible for servicegroups resource requests.
*/
@Api(value = "Service Groups", description = "Endpoint for servicegroup specific operations")
public class ServiceGroupService extends BaseService {
private static final String SERVICE_GROUP_REQUEST_TYPE = "org.apache.ambari.server.controller.ServiceGroupRequestSwagger";
+ private static final String SERVICE_GROUP_DEPENDENCY_REQUEST_TYPE = "org.apache.ambari.server.controller.ServiceGroupDependencyRequestSwagger";
+
/**
* Parent cluster Name.
@@ -279,6 +281,143 @@ public class ServiceGroupService extends BaseService {
}
/**
+ * Handles URL: /clusters/{clusterName}/servicegroups/{serviceGroupName}/dependencies
+ * Get all servicegroupdependencies for a cluster.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @return service group dependencies collection resource representation
+ */
+ @GET
+ @Path("{serviceGroupName}/dependencies")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Get all servicegroupdependencies",
+ nickname = "ServiceGroupService#getServiceGroupDependencies",
+ notes = "Returns all servicegroupdependencies.",
+ response = ServiceGroupDependencyResponse.ServiceGroupDependencyResponseSwagger.class,
+ responseContainer = RESPONSE_CONTAINER_LIST)
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION,
+ defaultValue = "ServiceGroupInfo/service_group_name, ServiceGroupInfo/cluster_name",
+ dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION,
+ defaultValue = "ServiceGroupInfo/service_group_name.asc, ServiceGroupInfo/cluster_name.asc",
+ dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_PAGE_SIZE, value = QUERY_PAGE_SIZE_DESCRIPTION, defaultValue = DEFAULT_PAGE_SIZE, dataType = DATA_TYPE_INT, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_FROM, value = QUERY_FROM_DESCRIPTION, defaultValue = DEFAULT_FROM, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
+ @ApiImplicitParam(name = QUERY_TO, value = QUERY_TO_DESCRIPTION, dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY)
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR)
+ })
+ public Response getServiceGroupDependencies(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("serviceGroupName") String serviceGroupName) {
+
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createServiceGroupDependencyResource(m_clusterName, serviceGroupName, null));
+ }
+
+ /**
+ * Handles URL: /clusters/{clusterName}/servicegroups/{serviceGroupName}/dependencies/{serviceGroupDependency}
+ * Get a specific servicegroupdependency.
+ *
+ * @param headers http headers
+ * @param ui uri info
+ * @param serviceGroupName service group name
+ * @param serviceGroupDependency service group dependency name
+ * @return servicegroupdependency resource representation
+ */
+ @GET
+ @Path("{serviceGroupName}/dependencies/{serviceGroupDependency}")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Get the details of a servicegroupdependency",
+ nickname = "ServiceGroupService#getServiceGroupDependency",
+ notes = "Returns the details of a servicegroupdependency",
+ response = ServiceGroupResponse.ServiceGroupResponseSwagger.class,
+ responseContainer = RESPONSE_CONTAINER_LIST)
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "ServiceGroupInfo/*",
+ dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY)
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR)
+ })
+ public Response getServiceGroupDependency(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("serviceGroupName") String serviceGroupName,
+ @PathParam("serviceGroupDependency") String serviceGroupDependency) {
+
+ return handleRequest(headers, body, ui, Request.Type.GET,
+ createServiceGroupDependencyResource(m_clusterName, serviceGroupName, serviceGroupDependency));
+ }
+
+ /**
+ * Handles: POST /clusters/{clusterName}/servicegroups/{serviceGroupName}/dependencies
+ * Create multiple servicegroupdependencies.
+ *
+ * @param body http body
+ * @param headers http headers
+ * @param ui uri info
+ * @return information regarding the created servicegroupdependencies
+ */
+ @POST
+ @Path("{serviceGroupName}/dependencies")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Creates a servicegroupdependency",
+ nickname = "ServiceGroupService#addServiceGroupDependency"
+ )
+ @ApiImplicitParams({
+ @ApiImplicitParam(dataType = SERVICE_GROUP_DEPENDENCY_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+ })
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_ACCEPTED, message = MSG_REQUEST_ACCEPTED),
+ @ApiResponse(code = HttpStatus.SC_BAD_REQUEST, message = MSG_INVALID_ARGUMENTS),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_CONFLICT, message = MSG_RESOURCE_ALREADY_EXISTS),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response addServiceGroupDependency(String body, @Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("serviceGroupName") String serviceGroupName) {
+
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createServiceGroupDependencyResource(m_clusterName, serviceGroupName, null));
+ }
+
+ /**
+ * Handles: DELETE /clusters/{clusterName}/servicegroups/{serviceGroupName}/dependencies/{serviceGroupDependency}
+ * Delete a specific servicegroupdependency.
+
+ * @param headers http headers
+ * @param ui uri info
+ * @param serviceGroupName service group name
+ * @param serviceGroupDependency service group dependency name
+ * @return information regarding the deleted servicegroupdependency
+ */
+ @DELETE
+ @Path("{serviceGroupName}/dependencies/{serviceGroupDependency}")
+ @Produces(MediaType.TEXT_PLAIN)
+ @ApiOperation(value = "Deletes a servicegroupdependency",
+ nickname = "ServiceGroupService#deleteServiceGroupDependency"
+ )
+ @ApiResponses({
+ @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+ @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),
+ @ApiResponse(code = HttpStatus.SC_UNAUTHORIZED, message = MSG_NOT_AUTHENTICATED),
+ @ApiResponse(code = HttpStatus.SC_FORBIDDEN, message = MSG_PERMISSION_DENIED),
+ @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR),
+ })
+ public Response deleteServiceGroupDependency(@Context HttpHeaders headers, @Context UriInfo ui,
+ @PathParam("serviceGroupName") String serviceGroupName,
+ @PathParam("serviceGroupDependency") String serviceGroupDependency) {
+
+ return handleRequest(headers, null, ui, Request.Type.DELETE, createServiceGroupDependencyResource(m_clusterName, serviceGroupName, serviceGroupDependency));
+ }
+ /**
* Create a service resource instance.
*
* @param clusterName cluster Name
@@ -294,4 +433,14 @@ public class ServiceGroupService extends BaseService {
return createResource(Resource.Type.ServiceGroup, mapIds);
}
+
+ ResourceInstance createServiceGroupDependencyResource(String clusterName, String serviceGroupName, String serviceGroupDependency) {
+ Map<Resource.Type, String> mapIds = new HashMap<>();
+ mapIds.put(Resource.Type.Cluster, clusterName);
+ mapIds.put(Resource.Type.ServiceGroup, serviceGroupName);
+ mapIds.put(Resource.Type.ServiceGroupDependency, serviceGroupDependency);
+
+
+ return createResource(Resource.Type.ServiceGroupDependency, mapIds);
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
index ee805b1..cb19099 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java
@@ -73,6 +73,7 @@ import org.apache.ambari.server.controller.internal.HostResourceProvider;
import org.apache.ambari.server.controller.internal.KerberosDescriptorResourceProvider;
import org.apache.ambari.server.controller.internal.MemberResourceProvider;
import org.apache.ambari.server.controller.internal.RepositoryVersionResourceProvider;
+import org.apache.ambari.server.controller.internal.ServiceGroupDependencyResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceGroupResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.internal.UpgradeResourceProvider;
@@ -477,6 +478,7 @@ public class ControllerModule extends AbstractModule {
.implement(ResourceProvider.class, Names.named("hostComponent"), HostComponentResourceProvider.class)
.implement(ResourceProvider.class, Names.named("service"), ServiceResourceProvider.class)
.implement(ResourceProvider.class, Names.named("servicegroup"), ServiceGroupResourceProvider.class)
+ .implement(ResourceProvider.class, Names.named("servicegroupdependency"), ServiceGroupDependencyResourceProvider.class)
.implement(ResourceProvider.class, Names.named("component"), ComponentResourceProvider.class)
.implement(ResourceProvider.class, Names.named("member"), MemberResourceProvider.class)
.implement(ResourceProvider.class, Names.named("repositoryVersion"), RepositoryVersionResourceProvider.class)
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
index b5a6547..20f4864 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ResourceProviderFactory.java
@@ -48,6 +48,9 @@ public interface ResourceProviderFactory {
@Named("servicegroup")
ResourceProvider getServiceGroupResourceProvider(AmbariManagementController managementController);
+ @Named("servicegroupdependency")
+ ResourceProvider getServiceGroupDependencyResourceProvider(AmbariManagementController managementController);
+
@Named("component")
ResourceProvider getComponentResourceProvider(AmbariManagementController managementController);
@@ -83,4 +86,4 @@ public interface ResourceProviderFactory {
@Named("viewInstance")
ViewInstanceResourceProvider getViewInstanceResourceProvider();
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyRequest.java
new file mode 100644
index 0000000..e9cf937
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyRequest.java
@@ -0,0 +1,75 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * 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;
+
+
+public class ServiceGroupDependencyRequest {
+
+ private String clusterName; // REF
+ private String serviceGroupName; // GET/CREATE/UPDATE/DELETE
+ private String dependencyServiceGroupName;
+
+ public ServiceGroupDependencyRequest(String clusterName, String serviceGroupName, String dependencyServiceGroupName) {
+ this.clusterName = clusterName;
+ this.serviceGroupName = serviceGroupName;
+ this.dependencyServiceGroupName = dependencyServiceGroupName;
+ }
+
+ /**
+ * @return the clusterName
+ */
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ /**
+ * @param clusterName the clusterName to set
+ */
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ /**
+ * @return the serviceGroupName
+ */
+ public String getServiceGroupName() {
+ return serviceGroupName;
+ }
+
+ /**
+ * @param serviceGroupName the service group name to set
+ */
+ public void setServiceGroupName(String serviceGroupName) {
+ this.serviceGroupName = serviceGroupName;
+ }
+
+ public String getDependencyServiceGroupName() {
+ return dependencyServiceGroupName;
+ }
+
+ public void setDependencyServiceGroupName(String dependencyServiceGroupName) {
+ this.dependencyServiceGroupName = dependencyServiceGroupName;
+ }
+
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("clusterName=" + clusterName
+ + ", serviceGroupName=" + serviceGroupName);
+ return sb.toString();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyResponse.java
new file mode 100644
index 0000000..1a4b4ed
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ServiceGroupDependencyResponse.java
@@ -0,0 +1,166 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller;
+
+import io.swagger.annotations.ApiModelProperty;
+
+public class ServiceGroupDependencyResponse {
+
+ private Long clusterId;
+ private Long serviceGroupId;
+ private Long dependencyClusterId;
+ private Long dependencyGroupId;
+ private String clusterName;
+ private String serviceGroupName;
+ private String dependencyGroupName;
+ private String dependencyClusterName;
+
+ public ServiceGroupDependencyResponse(Long clusterId, String clusterName, Long serviceGroupId, String serviceGroupName,
+ Long dependencyClusterId, String dependencyClusterName,
+ Long dependencyGroupId, String dependencyGroupName) {
+ this.clusterId = clusterId;
+ this.serviceGroupId = serviceGroupId;
+ this.clusterName = clusterName;
+ this.serviceGroupName = serviceGroupName;
+ this.dependencyGroupId = dependencyGroupId;
+ this.dependencyGroupName = dependencyGroupName;
+ this.dependencyClusterId = dependencyClusterId;
+ this.dependencyClusterName = dependencyClusterName;
+ }
+
+ /**
+ * @return the clusterId
+ */
+ public Long getClusterId() {
+ return clusterId;
+ }
+
+ /**
+ * @param clusterId the clusterId to set
+ */
+ public void setClusterId(Long clusterId) {
+ this.clusterId = clusterId;
+ }
+
+ /**
+ * @return the clusterName
+ */
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ /**
+ * @param clusterName the clusterName to set
+ */
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ /**
+ * @return the service group Id
+ */
+ public Long getServiceGroupId() {
+ return serviceGroupId;
+ }
+
+ /**
+ * @param serviceGroupId the service group Id
+ */
+ public void setServiceGroupId(Long serviceGroupId) {
+ this.serviceGroupId = serviceGroupId;
+ }
+
+ /**
+ * @return the service group name
+ */
+ public String getServiceGroupName() {
+ return serviceGroupName;
+ }
+
+ /**
+ * @param serviceGroupName the service group name
+ */
+ public void setServiceGroupName(String serviceGroupName) {
+ this.serviceGroupName = serviceGroupName;
+ }
+
+ public Long getDependencyGroupId() {
+ return dependencyGroupId;
+ }
+
+ public void setDependencyGroupId(Long dependencyGroupId) {
+ this.dependencyGroupId = dependencyGroupId;
+ }
+
+ public String getDependencyGroupName() {
+ return dependencyGroupName;
+ }
+
+ public void setDependencyGroupName(String dependencyGroupName) {
+ this.dependencyGroupName = dependencyGroupName;
+ }
+
+ public Long getDependencyClusterId() {
+ return dependencyClusterId;
+ }
+
+ public void setDependencyClusterId(Long dependencyClusterId) {
+ this.dependencyClusterId = dependencyClusterId;
+ }
+
+ public String getDependencyClusterName() {
+ return dependencyClusterName;
+ }
+
+ public void setDependencyClusterName(String dependencyClusterName) {
+ this.dependencyClusterName = dependencyClusterName;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ ServiceGroupResponse that = (ServiceGroupResponse) o;
+
+ if (clusterId != null ?
+ !clusterId.equals(this.clusterId) : this.clusterId != null) {
+ return false;
+ }
+ if (clusterName != null ?
+ !clusterName.equals(this.clusterName) : this.clusterName != null) {
+ return false;
+ }
+ if (serviceGroupName != null ?
+ !serviceGroupName.equals(this.serviceGroupName) : this.serviceGroupName != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Interface to help correct Swagger documentation generation
+ */
+ public interface ServiceGroupDependencyResponseSwagger extends ApiModel {
+ @ApiModelProperty(name = "ServiceGroupDependencyInfo")
+ ServiceResponse getServiceGroupDependencyResponse();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
index 60a845d..123f2fe 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractControllerResourceProvider.java
@@ -156,6 +156,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
return resourceProviderFactory.getServiceResourceProvider(managementController);
case ServiceGroup:
return resourceProviderFactory.getServiceGroupResourceProvider(managementController);
+ case ServiceGroupDependency:
+ return resourceProviderFactory.getServiceGroupDependencyResourceProvider(managementController);
case Component:
return resourceProviderFactory.getComponentResourceProvider(managementController);
case Host:
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
index c3293af..c219d23 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultProviderModule.java
@@ -88,6 +88,8 @@ public class DefaultProviderModule extends AbstractProviderModule {
return new AlertResourceProvider(managementController);
case ServiceGroup:
return new ServiceGroupResourceProvider(managementController);
+ case ServiceGroupDependency:
+ return new ServiceGroupDependencyResourceProvider(managementController);
case Registry:
return new RegistryResourceProvider(managementController);
case RegistryRecommendation:
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupDependencyResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupDependencyResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupDependencyResourceProvider.java
new file mode 100644
index 0000000..78610d2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceGroupDependencyResourceProvider.java
@@ -0,0 +1,484 @@
+/**
+ * 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
+ * <p/>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p/>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ClusterNotFoundException;
+import org.apache.ambari.server.ObjectNotFoundException;
+import org.apache.ambari.server.ParentObjectNotFoundException;
+import org.apache.ambari.server.ServiceGroupNotFoundException;
+import org.apache.ambari.server.api.services.ServiceGroupKey;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.KerberosHelper;
+import org.apache.ambari.server.controller.RequestStatusResponse;
+import org.apache.ambari.server.controller.ServiceGroupDependencyRequest;
+import org.apache.ambari.server.controller.ServiceGroupDependencyResponse;
+import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.RequestStatus;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.ResourceAlreadyExistsException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.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.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ServiceGroup;
+import org.apache.ambari.server.utils.StageUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.Validate;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.google.inject.Inject;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+
+public class ServiceGroupDependencyResourceProvider extends AbstractControllerResourceProvider {
+
+
+ // ----- Property ID constants ---------------------------------------------
+
+ public static final String RESPONSE_KEY = "ServiceGroupDependencyInfo";
+ public static final String ALL_PROPERTIES = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "*";
+ public static final String SERVICE_GROUP_DEPENDENCY_CLUSTER_ID_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "cluster_id";
+ public static final String SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "cluster_name";
+ public static final String SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "service_group_id";
+ public static final String SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "service_group_name";
+ public static final String SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_ID_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "dependency_cluster_id";
+ public static final String SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "dependency_cluster_name";
+ public static final String SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "dependency_service_group_id";
+ public static final String SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID = RESPONSE_KEY + PropertyHelper.EXTERNAL_PATH_SEP + "dependency_service_group_name";
+
+ protected ObjectMapper mapper = new ObjectMapper();;
+
+ private static Set<String> pkPropertyIds =
+ new HashSet<String>(Arrays.asList(new String[]{
+ SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID,
+ SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID,
+ SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID}));
+
+ private static Gson gson = StageUtils.getGson();
+
+ /**
+ * The property ids for an service group resource.
+ */
+ private static final Set<String> PROPERTY_IDS = new HashSet<>();
+
+ /**
+ * The key property ids for an service group resource.
+ */
+ private static final Map<Resource.Type, String> KEY_PROPERTY_IDS = new HashMap<>();
+
+ static {
+ // properties
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_CLUSTER_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID);
+ PROPERTY_IDS.add(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
+
+ // keys
+ KEY_PROPERTY_IDS.put(Resource.Type.Cluster, SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID);
+ KEY_PROPERTY_IDS.put(Resource.Type.ServiceGroup, SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
+ KEY_PROPERTY_IDS.put(Resource.Type.ServiceGroupDependency, SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
+ }
+
+ private Clusters clusters;
+
+ /**
+ * kerberos helper
+ */
+ @Inject
+ private KerberosHelper kerberosHelper;
+
+ // ----- Constructors ----------------------------------------------------
+
+ /**
+ * Create a new resource provider for the given management controller.
+ *
+ * @param managementController the management controller
+ */
+ @AssistedInject
+ public ServiceGroupDependencyResourceProvider(@Assisted AmbariManagementController managementController) {
+ super(Resource.Type.ServiceGroupDependency, PROPERTY_IDS, KEY_PROPERTY_IDS, managementController);
+ }
+
+ // ----- ResourceProvider ------------------------------------------------
+
+ @Override
+ protected RequestStatus createResourcesAuthorized(Request request)
+ throws SystemException,
+ UnsupportedPropertyException,
+ ResourceAlreadyExistsException,
+ NoSuchParentResourceException {
+
+ final Set<ServiceGroupDependencyRequest> requests = new HashSet<>();
+ for (Map<String, Object> propertyMap : request.getProperties()) {
+ requests.add(getRequest(propertyMap));
+ }
+ Set<ServiceGroupDependencyResponse> createServiceGroups = null;
+ createServiceGroups = createResources(new Command<Set<ServiceGroupDependencyResponse>>() {
+ @Override
+ public Set<ServiceGroupDependencyResponse> invoke() throws AmbariException, AuthorizationException {
+ return createServiceGroupDependencies(requests);
+ }
+ });
+ Set<Resource> associatedResources = new HashSet<>();
+ if (createServiceGroups != null) {
+ Iterator<ServiceGroupDependencyResponse> itr = createServiceGroups.iterator();
+ while (itr.hasNext()) {
+ ServiceGroupDependencyResponse response = itr.next();
+ notifyCreate(Resource.Type.ServiceGroupDependency, request);
+ Resource resource = new ResourceImpl(Resource.Type.ServiceGroupDependency);
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_CLUSTER_ID_PROPERTY_ID, response.getClusterId());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID, response.getClusterName());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID, response.getServiceGroupId());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID, response.getServiceGroupName());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_ID_PROPERTY_ID, response.getDependencyClusterId());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID, response.getDependencyClusterName());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID, response.getDependencyGroupId());
+ resource.setProperty(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID, response.getDependencyGroupName());
+
+ associatedResources.add(resource);
+ }
+ return getRequestStatus(null, associatedResources);
+ }
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ protected Set<Resource> getResourcesAuthorized(Request request, Predicate predicate) throws
+ SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ServiceGroupDependencyRequest> requests = new HashSet<>();
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+
+ Set<ServiceGroupDependencyResponse> responses = getResources(new Command<Set<ServiceGroupDependencyResponse>>() {
+ @Override
+ public Set<ServiceGroupDependencyResponse> invoke() throws AmbariException {
+ return getServiceGroupDependencies(requests);
+ }
+ });
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ServiceGroupDependencyResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.ServiceGroupDependency);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_CLUSTER_ID_PROPERTY_ID,
+ response.getClusterId(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID,
+ response.getClusterName(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID,
+ response.getServiceGroupId(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID,
+ response.getServiceGroupName(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_ID_PROPERTY_ID,
+ response.getDependencyClusterId(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID,
+ response.getDependencyClusterName(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_ID_PROPERTY_ID,
+ response.getDependencyGroupId(), requestedIds);
+ setResourceProperty(resource, SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID,
+ response.getDependencyGroupName(), requestedIds);
+ resources.add(resource);
+ }
+ return resources;
+ }
+
+ @Override
+ protected RequestStatus updateResourcesAuthorized(final Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ // TODO : Add functionality for updating SG : RENAME, START ALL, STOP ALL services.
+ RequestStatusResponse response = null;
+ return getRequestStatus(response);
+ }
+
+ @Override
+ protected RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate)
+ throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ServiceGroupDependencyRequest> requests = new HashSet<>();
+ DeleteStatusMetaData deleteStatusMetaData = null;
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getRequest(propertyMap));
+ }
+ deleteStatusMetaData = modifyResources(new Command<DeleteStatusMetaData>() {
+ @Override
+ public DeleteStatusMetaData invoke() throws AmbariException, AuthorizationException {
+ deleteServiceGroupDependencies(requests);
+ return new DeleteStatusMetaData();
+ }
+ });
+
+ notifyDelete(Resource.Type.ServiceGroupDependency, predicate);
+ for(ServiceGroupDependencyRequest svgReq : requests) {
+ deleteStatusMetaData.addDeletedKey("cluster_name: " + svgReq.getClusterName() + ", " + " service_group_name: " + svgReq.getServiceGroupName()
+ + "dependency_service_group_name: " + svgReq.getDependencyServiceGroupName());
+ }
+ return getRequestStatus(null, null, deleteStatusMetaData);
+ }
+
+ @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 -------------------------------------------------
+
+ /**
+ * Get a service group request object from a map of property values.
+ *
+ * @param properties the predicate
+ * @return the service request object
+ */
+ private ServiceGroupDependencyRequest getRequest(Map<String, Object> properties) {
+ String clusterName = (String) properties.get(SERVICE_GROUP_DEPENDENCY_CLUSTER_NAME_PROPERTY_ID);
+ String serviceGroupName = (String) properties.get(SERVICE_GROUP_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
+ String dependencyServiceGroupName = (String) properties.get(SERVICE_GROUP_DEPENDENCY_DEPENDENCY_SERVICE_GROUP_NAME_PROPERTY_ID);
+ ServiceGroupDependencyRequest svcRequest = new ServiceGroupDependencyRequest(clusterName, serviceGroupName, dependencyServiceGroupName);
+ return svcRequest;
+ }
+
+ protected Set<ServiceGroupKey> getServiceGroupDependenciesSet(Set<Map<String, String>> serviceGroupDependencies) {
+ Set<ServiceGroupKey> serviceGroupKeys = new HashSet<>();
+ if (serviceGroupDependencies != null) {
+ for (Map<String, String> dependencyProperties : serviceGroupDependencies) {
+ ServiceGroupKey serviceGroupKey = mapper.convertValue(dependencyProperties, ServiceGroupKey.class);
+ serviceGroupKeys.add(serviceGroupKey);
+ }
+ }
+ return serviceGroupKeys;
+ }
+
+ // Create services from the given request.
+ public synchronized Set<ServiceGroupDependencyResponse> createServiceGroupDependencies(Set<ServiceGroupDependencyRequest> requests)
+ throws AmbariException, AuthorizationException {
+
+ if (requests.isEmpty()) {
+ LOG.warn("Received an empty requests set");
+ return null;
+ }
+ AmbariManagementController controller = getManagementController();
+ Clusters clusters = controller.getClusters();
+
+ // do all validation checks
+ validateCreateRequests(requests, clusters);
+
+ Set<ServiceGroupDependencyResponse> createdServiceGroupDependencies = new HashSet<>();
+ for (ServiceGroupDependencyRequest request : requests) {
+ Cluster cluster = clusters.getCluster(request.getClusterName());
+
+ // Already checked that service group does not exist
+ ServiceGroup sg = cluster.addServiceGroupDependency(request.getServiceGroupName(), request.getDependencyServiceGroupName());
+ createdServiceGroupDependencies.addAll(sg.getServiceGroupDependencyResponses());
+ }
+ return createdServiceGroupDependencies;
+ }
+
+ // Get services from the given set of requests.
+ protected Set<ServiceGroupDependencyResponse> getServiceGroupDependencies(Set<ServiceGroupDependencyRequest> requests)
+ throws AmbariException {
+ Set<ServiceGroupDependencyResponse> response = new HashSet<ServiceGroupDependencyResponse>();
+ for (ServiceGroupDependencyRequest request : requests) {
+ try {
+ response.addAll(getServiceGroupDependencies(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<ServiceGroupDependencyResponse> getServiceGroupDependencies(ServiceGroupDependencyRequest request)
+ throws AmbariException {
+ if (request.getClusterName() == null) {
+ throw new AmbariException("Invalid arguments, cluster id"
+ + " 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<ServiceGroupDependencyResponse> responses = new HashSet<>();
+ if (request.getServiceGroupName() != null) {
+ ServiceGroup sg = cluster.getServiceGroup(request.getServiceGroupName());
+ responses.addAll(sg.getServiceGroupDependencyResponses());
+ return responses;
+ }
+ return responses;
+ }
+
+
+ // Delete services based on the given set of requests
+ protected void deleteServiceGroupDependencies(Set<ServiceGroupDependencyRequest> request)
+ throws AmbariException, AuthorizationException {
+
+ Clusters clusters = getManagementController().getClusters();
+
+ Set<ServiceGroupDependencyRequest> removable = new HashSet<>();
+
+ for (ServiceGroupDependencyRequest serviceGroupDependencyRequest : request) {
+ if (null == serviceGroupDependencyRequest.getClusterName()
+ || StringUtils.isEmpty(serviceGroupDependencyRequest.getServiceGroupName())) {
+ throw new AmbariException("invalid arguments");
+ } else {
+
+ if (!AuthorizationHelper.isAuthorized(
+ ResourceType.CLUSTER, getClusterResourceId(serviceGroupDependencyRequest.getClusterName()),
+ RoleAuthorization.SERVICE_ADD_DELETE_SERVICES)) {
+ throw new AuthorizationException("The user is not authorized to delete service groups");
+ }
+
+ Cluster cluster = clusters.getCluster(serviceGroupDependencyRequest.getClusterName());
+ ServiceGroup serviceGroup = cluster.getServiceGroup(serviceGroupDependencyRequest.getServiceGroupName());
+ Set<ServiceGroupKey> serviceGroupKeys = serviceGroup.getServiceGroupDependencies();
+ if (serviceGroupKeys == null || serviceGroupKeys.isEmpty()) {
+ throw new AmbariException("Servcie group name " + serviceGroupDependencyRequest.getServiceGroupName() + " has no" +
+ "dependencies, so nothing to remove.");
+ } else {
+ boolean dependencyAvailable = false;
+ for (ServiceGroupKey serviceGroupKey : serviceGroupKeys) {
+ if (serviceGroupKey.getServiceGroupName().equals(serviceGroupDependencyRequest.getDependencyServiceGroupName())) {
+ dependencyAvailable = true;
+ }
+ }
+ if (!dependencyAvailable) {
+ throw new AmbariException("Servcie group name " + serviceGroupDependencyRequest.getServiceGroupName() + " has no" +
+ "dependency " + serviceGroupDependencyRequest.getDependencyServiceGroupName() + ", so nothing to remove.");
+ }
+
+ serviceGroup.getCluster().deleteServiceGroupDependency(serviceGroupDependencyRequest.getServiceGroupName(),
+ serviceGroupDependencyRequest.getDependencyServiceGroupName());
+ }
+ }
+ }
+ }
+
+
+ private void validateCreateRequests(Set<ServiceGroupDependencyRequest> requests, Clusters clusters)
+ throws AuthorizationException, AmbariException {
+
+ Map<String, Set<String>> serviceGroupNames = new HashMap<>();
+ Set<String> duplicates = new HashSet<>();
+ for (ServiceGroupDependencyRequest request : requests) {
+ final String clusterName = request.getClusterName();
+ final String serviceGroupName = request.getServiceGroupName();
+ final String dependencyServiceGroupName = request.getDependencyServiceGroupName();
+
+ Validate.notNull(clusterName, "Cluster name should be provided when creating a service group");
+
+ // validating service group dependencies
+ if (StringUtils.isEmpty(dependencyServiceGroupName)) {
+ throw new AmbariException("Service group name is empty or null!");
+ } else {
+ Cluster cluster = clusters.getCluster(clusterName);
+ //throws service group not found exception
+ ServiceGroup serviceGroup = cluster.getServiceGroup(dependencyServiceGroupName);
+
+ }
+
+ Validate.notEmpty(serviceGroupName, "Service group name should be provided when adding a service group dependency");
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Received a createServiceGroupDependency request" +
+ ", clusterName=" + 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");
+ }
+
+
+ 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);
+ }
+
+ // throws service group not found exception if theere is no such SG
+ ServiceGroup sg = cluster.getServiceGroup(serviceGroupName);
+ Set<ServiceGroupKey> dependencies = sg.getServiceGroupDependencies();
+ if (dependencies != null) {
+ for (ServiceGroupKey serviceGroupKey : dependencies) {
+ if (serviceGroupKey.getServiceGroupName().equals(dependencyServiceGroupName)) {
+ throw new AmbariException("Service group " + serviceGroupName + " already have dependency for service group "
+ + dependencyServiceGroupName);
+ }
+ }
+ }
+
+ }
+ }
+}
+
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/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 ebf0e9f..3699cd0 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
@@ -78,6 +78,7 @@ public interface Resource {
RootClusterSetting,
Service,
ServiceGroup,
+ ServiceGroupDependency,
Setting,
Host,
Component,
@@ -208,6 +209,7 @@ public interface Resource {
public static final Type Cluster = InternalType.Cluster.getType();
public static final Type RootClusterSetting = InternalType.RootClusterSetting.getType();
public static final Type ServiceGroup = InternalType.ServiceGroup.getType();
+ public static final Type ServiceGroupDependency = InternalType.ServiceGroupDependency.getType();
public static final Type Service = InternalType.Service.getType();
public static final Type Setting = InternalType.Setting.getType();
public static final Type Host = InternalType.Host.getType();
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceGroupEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceGroupEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceGroupEntity.java
index 7f8facb..1bcdd80 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceGroupEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ServiceGroupEntity.java
@@ -18,6 +18,9 @@
package org.apache.ambari.server.orm.entities;
+import java.util.ArrayList;
+import java.util.List;
+
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
@@ -25,6 +28,8 @@ import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.JoinColumn;
+import javax.persistence.JoinTable;
+import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
@@ -32,7 +37,6 @@ import javax.persistence.Table;
import javax.persistence.TableGenerator;
-
@IdClass(ServiceGroupEntityPK.class)
@Table(name = "servicegroups")
@NamedQueries({
@@ -66,6 +70,19 @@ public class ServiceGroupEntity {
@JoinColumn(name = "cluster_id", referencedColumnName = "cluster_id", nullable = false)
private ClusterEntity clusterEntity;
+ @ManyToMany
+ @JoinTable(
+ name = "servicegroupdependencies",
+ joinColumns = {@JoinColumn(name = "service_group_id", referencedColumnName = "id", nullable = false),
+ @JoinColumn(name = "service_group_cluster_id", referencedColumnName = "cluster_id", nullable = false)},
+ inverseJoinColumns = {@JoinColumn(name = "dependent_service_group_id", referencedColumnName = "id", nullable = false),
+ @JoinColumn(name = "dependent_service_group_cluster_id", referencedColumnName = "cluster_id", nullable = false)}
+ )
+ private List<ServiceGroupEntity> serviceGroupDependencies = new ArrayList<>();
+
+ @ManyToMany(mappedBy="serviceGroupDependencies")
+ private List<ServiceGroupEntity> dependencies = new ArrayList<>();
+
public Long getClusterId() {
return clusterId;
}
@@ -91,6 +108,14 @@ public class ServiceGroupEntity {
this.serviceGroupName = serviceGroupName;
}
+ public List<ServiceGroupEntity> getServiceGroupDependencies() {
+ return serviceGroupDependencies;
+ }
+
+ public void setServiceGroupDependencies(List<ServiceGroupEntity> serviceGroupDependencies) {
+ this.serviceGroupDependencies = serviceGroupDependencies;
+ }
+
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -120,4 +145,4 @@ public class ServiceGroupEntity {
this.clusterEntity = clusterEntity;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
index 8fd878e..5ba61b7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Cluster.java
@@ -90,6 +90,8 @@ public interface Cluster {
*/
ServiceGroup addServiceGroup(String serviceGroupName) throws AmbariException;
+ ServiceGroup addServiceGroupDependency(String serviceGroupName, String dependencyServiceGroupName) throws AmbariException;
+
/**
* Get a service
*
@@ -510,6 +512,8 @@ public interface Cluster {
*/
void deleteServiceGroup(String serviceGroupName) throws AmbariException;
+ void deleteServiceGroupDependency(String serviceGroupName, String dependencyServiceGroupName) throws AmbariException;
+
/**
* Gets if the cluster can be deleted
*
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroup.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroup.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroup.java
index 9850462..3d59c96 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroup.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroup.java
@@ -18,8 +18,13 @@
package org.apache.ambari.server.state;
+import java.util.Set;
+
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.ServiceGroupKey;
+import org.apache.ambari.server.controller.ServiceGroupDependencyResponse;
import org.apache.ambari.server.controller.ServiceGroupResponse;
+import org.apache.ambari.server.orm.entities.ServiceGroupEntity;
public interface ServiceGroup {
@@ -33,8 +38,14 @@ public interface ServiceGroup {
Cluster getCluster();
+ Set<ServiceGroupKey> getServiceGroupDependencies();
+
+ void setServiceGroupDependencies(Set<ServiceGroupKey> serviceGroupDependencies);
+
ServiceGroupResponse convertToResponse();
+ Set<ServiceGroupDependencyResponse> getServiceGroupDependencyResponses();
+
void debugDump(StringBuilder sb);
void refresh();
@@ -47,4 +58,6 @@ public interface ServiceGroup {
boolean canBeRemoved();
void delete() throws AmbariException;
-}
\ No newline at end of file
+
+ ServiceGroupEntity deleteDependency(String dependencyServiceGroupName) throws AmbariException;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupFactory.java
index 7146bdf..3c5e956 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupFactory.java
@@ -18,6 +18,9 @@
package org.apache.ambari.server.state;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.ServiceGroupKey;
import org.apache.ambari.server.orm.entities.ServiceGroupEntity;
import com.google.inject.assistedinject.Assisted;
@@ -25,7 +28,8 @@ import com.google.inject.assistedinject.Assisted;
public interface ServiceGroupFactory {
ServiceGroup createNew(Cluster cluster,
- @Assisted("serviceGroupName") String serviceGroupName);
+ @Assisted("serviceGroupName") String serviceGroupName,
+ @Assisted("serviceGroupDependencies") Set<ServiceGroupKey> serviceGroupDependencies);
ServiceGroup createExisting(Cluster cluster, ServiceGroupEntity serviceGroupEntity);
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupImpl.java
index 735a946..7737c0d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceGroupImpl.java
@@ -18,7 +18,15 @@
package org.apache.ambari.server.state;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.ServiceGroupKey;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ServiceGroupDependencyResponse;
import org.apache.ambari.server.controller.ServiceGroupResponse;
import org.apache.ambari.server.events.ServiceGroupInstalledEvent;
import org.apache.ambari.server.events.ServiceGroupRemovedEvent;
@@ -50,13 +58,16 @@ public class ServiceGroupImpl implements ServiceGroup {
private Long serviceGroupId;
private String serviceGroupName;
+ private Set<ServiceGroupKey> serviceGroupDependencies = new HashSet<>();
@AssistedInject
public ServiceGroupImpl(@Assisted Cluster cluster,
@Assisted("serviceGroupName") String serviceGroupName,
+ @Assisted("serviceGroupDependencies") Set<ServiceGroupKey> serviceGroupDependencies,
ClusterDAO clusterDAO,
ServiceGroupDAO serviceGroupDAO,
- AmbariEventPublisher eventPublisher) throws AmbariException {
+ AmbariEventPublisher eventPublisher,
+ AmbariManagementController controller) throws AmbariException {
this.cluster = cluster;
this.clusterDAO = clusterDAO;
@@ -70,6 +81,27 @@ public class ServiceGroupImpl implements ServiceGroup {
serviceGroupEntity.setServiceGroupId(serviceGroupId);
serviceGroupEntity.setServiceGroupName(serviceGroupName);
+ List<ServiceGroupEntity> serviceGroupEntities = new ArrayList<>();
+ if (serviceGroupDependencies != null) {
+ this.serviceGroupDependencies = serviceGroupDependencies;
+ for (ServiceGroupKey serviceGroupKey : serviceGroupDependencies) {
+ Clusters clusters = controller.getClusters();
+ Cluster dependencyCluster = serviceGroupKey.getClusterName() == null ? cluster :
+ clusters.getCluster(serviceGroupKey.getClusterName());
+ serviceGroupKey.setClusterName(dependencyCluster.getClusterName());
+ ServiceGroup dependencyServiceGroup = dependencyCluster.getServiceGroup(serviceGroupKey.getServiceGroupName());
+
+ ServiceGroupEntityPK serviceGroupEntityPK = new ServiceGroupEntityPK();
+ serviceGroupEntityPK.setServiceGroupId(dependencyServiceGroup.getServiceGroupId());
+ serviceGroupEntityPK.setClusterId(dependencyServiceGroup.getClusterId());
+ ServiceGroupEntity dependentServiceGroupEntity = serviceGroupDAO.findByPK(serviceGroupEntityPK);
+ serviceGroupEntities.add(dependentServiceGroupEntity);
+ }
+ } else {
+ this.serviceGroupDependencies = new HashSet<>();
+ }
+ serviceGroupEntity.setServiceGroupDependencies(serviceGroupEntities);
+
this.serviceGroupEntityPK = getServiceGroupEntityPK(serviceGroupEntity);
persist(serviceGroupEntity);
}
@@ -87,6 +119,7 @@ public class ServiceGroupImpl implements ServiceGroup {
this.serviceGroupId = serviceGroupEntity.getServiceGroupId();
this.serviceGroupName = serviceGroupEntity.getServiceGroupName();
+ this.serviceGroupDependencies = getServiceGroupDependencies(serviceGroupEntity.getServiceGroupDependencies());
this.serviceGroupEntityPK = getServiceGroupEntityPK(serviceGroupEntity);
}
@@ -115,6 +148,16 @@ public class ServiceGroupImpl implements ServiceGroup {
}
@Override
+ public Set<ServiceGroupKey> getServiceGroupDependencies() {
+ return serviceGroupDependencies;
+ }
+
+ @Override
+ public void setServiceGroupDependencies(Set<ServiceGroupKey> serviceGroupDependencies) {
+ this.serviceGroupDependencies = serviceGroupDependencies;
+ }
+
+ @Override
public ServiceGroupResponse convertToResponse() {
ServiceGroupResponse r = new ServiceGroupResponse(cluster.getClusterId(),
cluster.getClusterName(), getServiceGroupId(), getServiceGroupName());
@@ -122,6 +165,61 @@ public class ServiceGroupImpl implements ServiceGroup {
}
@Override
+ public Set<ServiceGroupDependencyResponse> getServiceGroupDependencyResponses() {
+ Set<ServiceGroupDependencyResponse> responses = new HashSet<>();
+ if (getServiceGroupDependencies() != null) {
+ for (ServiceGroupKey sgk : getServiceGroupDependencies()) {
+ responses.add(new ServiceGroupDependencyResponse(cluster.getClusterId(), cluster.getClusterName(),
+ serviceGroupId, serviceGroupName, sgk.getClusterId(), sgk.getClusterName(), sgk.getServiceGroupId(), sgk.getServiceGroupName()));
+ }
+ }
+ return responses;
+ }
+
+ public Set<ServiceGroupKey> getServiceGroupDependencies(List<ServiceGroupEntity> serviceGroupDependencies) {
+ Set<ServiceGroupKey> serviceGroupDependenciesList = new HashSet<>();
+ if (serviceGroupDependencies != null) {
+ for (ServiceGroupEntity sge : serviceGroupDependencies) {
+ ServiceGroupKey serviceGroupKey = new ServiceGroupKey();
+ String clusterName = "";
+ Long clusterId = null;
+ if (sge.getClusterId() == cluster.getClusterId()) {
+ clusterName = cluster.getClusterName();
+ clusterId = cluster.getClusterId();
+ } else {
+ ClusterEntity clusterEntity = clusterDAO.findById(sge.getClusterId());
+ if (clusterEntity != null) {
+ clusterName = clusterEntity.getClusterName();
+ clusterId = clusterEntity.getClusterId();
+ } else {
+ LOG.error("Unable to get cluster id for service group " + sge.getServiceGroupName());
+ }
+ }
+
+ ServiceGroupEntityPK serviceGroupEntityPK = new ServiceGroupEntityPK();
+ serviceGroupEntityPK.setClusterId(sge.getClusterId());
+ serviceGroupEntityPK.setServiceGroupId(sge.getServiceGroupId());
+ ServiceGroupEntity serviceGroupEntity = serviceGroupDAO.findByPK(serviceGroupEntityPK);
+ String serviceGroupDependencyName = "";
+ Long serviceGroupDependencId = null;
+ if (serviceGroupEntity != null) {
+ serviceGroupDependencyName = serviceGroupEntity.getServiceGroupName();
+ serviceGroupDependencId = serviceGroupEntity.getServiceGroupId();
+ } else {
+ LOG.error("Unable to get service group entity for service group " + sge.getServiceGroupName());
+ }
+
+ serviceGroupKey.setServiceGroupName(serviceGroupDependencyName);
+ serviceGroupKey.setServiceGroupId(serviceGroupDependencId);
+ serviceGroupKey.setClusterName(clusterName);
+ serviceGroupKey.setClusterId(clusterId);
+ serviceGroupDependenciesList.add(serviceGroupKey);
+ }
+ }
+ return serviceGroupDependenciesList;
+ }
+
+ @Override
public Cluster getCluster() {
return cluster;
}
@@ -190,6 +288,25 @@ public class ServiceGroupImpl implements ServiceGroup {
eventPublisher.publish(event);
}
+ @Override
+ @Transactional
+ public ServiceGroupEntity deleteDependency(String dependencyServiceGroupName) throws AmbariException {
+ ServiceGroupEntityPK pk = new ServiceGroupEntityPK();
+ pk.setClusterId(getClusterId());
+ pk.setServiceGroupId(getServiceGroupId());
+ ServiceGroupEntity serviceGroupEntity = serviceGroupDAO.findByPK(pk);
+ ServiceGroupEntity dependencyToRemove = null;
+ for (ServiceGroupEntity dependency : serviceGroupEntity.getServiceGroupDependencies()) {
+ if (dependency.getServiceGroupName().equals(dependencyServiceGroupName)) {
+ dependencyToRemove = dependency;
+ break;
+ }
+ }
+ serviceGroupEntity.getServiceGroupDependencies().remove(dependencyToRemove);
+ serviceGroupEntity = serviceGroupDAO.merge(serviceGroupEntity);
+ return serviceGroupEntity;
+ }
+
@Transactional
protected void removeEntities() throws AmbariException {
@@ -210,4 +327,4 @@ public class ServiceGroupImpl implements ServiceGroup {
pk.setServiceGroupId(serviceGroupEntity.getServiceGroupId());
return pk;
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
index 1e4d81f..e896d0e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/cluster/ClusterImpl.java
@@ -54,6 +54,7 @@ import org.apache.ambari.server.ServiceGroupNotFoundException;
import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.agent.ExecutionCommand.KeyNames;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.ServiceGroupKey;
import org.apache.ambari.server.controller.AmbariSessionManager;
import org.apache.ambari.server.controller.ClusterResponse;
import org.apache.ambari.server.controller.ConfigurationResponse;
@@ -81,6 +82,7 @@ import org.apache.ambari.server.orm.dao.HostConfigMappingDAO;
import org.apache.ambari.server.orm.dao.HostDAO;
import org.apache.ambari.server.orm.dao.HostVersionDAO;
import org.apache.ambari.server.orm.dao.ServiceConfigDAO;
+import org.apache.ambari.server.orm.dao.ServiceGroupDAO;
import org.apache.ambari.server.orm.dao.StackDAO;
import org.apache.ambari.server.orm.dao.TopologyRequestDAO;
import org.apache.ambari.server.orm.dao.UpgradeDAO;
@@ -99,6 +101,7 @@ import org.apache.ambari.server.orm.entities.ResourceEntity;
import org.apache.ambari.server.orm.entities.ServiceConfigEntity;
import org.apache.ambari.server.orm.entities.ServiceDesiredStateEntity;
import org.apache.ambari.server.orm.entities.ServiceGroupEntity;
+import org.apache.ambari.server.orm.entities.ServiceGroupEntityPK;
import org.apache.ambari.server.orm.entities.StackEntity;
import org.apache.ambari.server.orm.entities.TopologyRequestEntity;
import org.apache.ambari.server.orm.entities.UpgradeEntity;
@@ -273,6 +276,9 @@ public class ClusterImpl implements Cluster {
@Inject
private TopologyRequestDAO topologyRequestDAO;
+ @Inject
+ private ServiceGroupDAO serviceGroupDAO;
+
/**
* Data access object used for looking up stacks from the database.
*/
@@ -905,7 +911,43 @@ public class ClusterImpl implements Cluster {
+ ", clusterId=" + getClusterId() + ", serviceGroupName=" + serviceGroupName);
}
- ServiceGroup serviceGroup = serviceGroupFactory.createNew(this, serviceGroupName);
+ ServiceGroup serviceGroup = serviceGroupFactory.createNew(this, serviceGroupName, new HashSet<ServiceGroupKey>());
+ addServiceGroup(serviceGroup);
+ return serviceGroup;
+ }
+
+ @Override
+ public ServiceGroup addServiceGroupDependency(String serviceGroupName, String dependencyServiceGroupName) throws AmbariException {
+ if (!serviceGroups.containsKey(serviceGroupName)) {
+ throw new AmbariException("Service group doesn't exist" + ", clusterName=" + getClusterName()
+ + ", clusterId=" + getClusterId() + ", serviceGroupName=" + serviceGroupName);
+ }
+
+ if (!serviceGroups.containsKey(dependencyServiceGroupName)) {
+ throw new AmbariException("Dependent service group doesn't exist" + ", clusterName=" + getClusterName()
+ + ", clusterId=" + getClusterId() + ", serviceGroupName=" + serviceGroupName);
+ }
+
+ ServiceGroupEntity serviceGroupEntity = null;
+ clusterGlobalLock.writeLock().lock();
+ try {
+ ServiceGroupEntityPK serviceGroupEntityPK = new ServiceGroupEntityPK();
+ serviceGroupEntityPK.setClusterId(getClusterId());
+ serviceGroupEntityPK.setServiceGroupId(serviceGroups.get(serviceGroupName).getServiceGroupId());
+ serviceGroupEntity = serviceGroupDAO.findByPK(serviceGroupEntityPK);
+
+ ServiceGroupEntityPK dependencyServiceGroupEntityPK = new ServiceGroupEntityPK();
+ dependencyServiceGroupEntityPK.setClusterId(getClusterId());
+ dependencyServiceGroupEntityPK.setServiceGroupId(serviceGroups.get(dependencyServiceGroupName).getServiceGroupId());
+ ServiceGroupEntity dependencyServiceGroupEntity = serviceGroupDAO.findByPK(dependencyServiceGroupEntityPK);
+
+ serviceGroupEntity.getServiceGroupDependencies().add(dependencyServiceGroupEntity);
+ serviceGroupEntity = serviceGroupDAO.merge(serviceGroupEntity);
+ } finally {
+ clusterGlobalLock.writeLock().unlock();
+ }
+
+ ServiceGroup serviceGroup = serviceGroupFactory.createExisting(this, serviceGroupEntity);
addServiceGroup(serviceGroup);
return serviceGroup;
}
@@ -1409,6 +1451,24 @@ public class ClusterImpl implements Cluster {
}
}
+ @Override
+ public void deleteServiceGroupDependency(String serviceGroupName, String dependencyServiceGroupName) throws AmbariException {
+ clusterGlobalLock.writeLock().lock();
+ try {
+ ServiceGroup serviceGroup = getServiceGroup(serviceGroupName);
+ LOG.info("Deleting service group dependency, dependencyServiceGroupName=" + dependencyServiceGroupName + " in cluster" + ", clusterName="
+ + getClusterName() + ", serviceGroupName=" + serviceGroup.getServiceGroupName());
+
+ Long serviceGroupId = serviceGroup.getServiceGroupId();
+ ServiceGroupEntity serviceGroupEntity = serviceGroup.deleteDependency(dependencyServiceGroupName);
+ ServiceGroup updatedServiceGroup = serviceGroupFactory.createExisting(this, serviceGroupEntity);
+ serviceGroups.put(updatedServiceGroup.getServiceGroupName(), updatedServiceGroup);
+ serviceGroupsById.put(updatedServiceGroup.getServiceGroupId(), updatedServiceGroup);
+ } finally {
+ clusterGlobalLock.writeLock().unlock();
+ }
+ }
+
/**
* Deletes the specified service also removes references to it from {@link this.serviceComponentHosts}
* and references to ServiceComponentHost objects that belong to the service from {@link this.serviceComponentHostsByHost}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index 9270e7d..fda0566 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -61,6 +61,7 @@ import org.apache.ambari.server.controller.internal.HostComponentResourceProvide
import org.apache.ambari.server.controller.internal.HostResourceProvider;
import org.apache.ambari.server.controller.internal.ProvisionClusterRequest;
import org.apache.ambari.server.controller.internal.RequestImpl;
+import org.apache.ambari.server.controller.internal.ServiceGroupDependencyResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceGroupResourceProvider;
import org.apache.ambari.server.controller.internal.ServiceResourceProvider;
import org.apache.ambari.server.controller.internal.VersionDefinitionResourceProvider;
@@ -128,6 +129,7 @@ public class AmbariContext {
private static HostRoleCommandFactory hostRoleCommandFactory;
private static HostResourceProvider hostResourceProvider;
private static ServiceGroupResourceProvider serviceGroupResourceProvider;
+ private static ServiceGroupDependencyResourceProvider serviceGroupDependencyResourceProvider;
private static ServiceResourceProvider serviceResourceProvider;
private static ComponentResourceProvider componentResourceProvider;
private static HostComponentResourceProvider hostComponentResourceProvider;
@@ -771,6 +773,14 @@ public class AmbariContext {
return serviceGroupResourceProvider;
}
+ private synchronized ServiceGroupDependencyResourceProvider getServiceGroupDependencyResourceProvider() {
+ if (serviceGroupDependencyResourceProvider == null) {
+ serviceGroupResourceProvider = (ServiceGroupResourceProvider) ClusterControllerHelper.
+ getClusterController().ensureResourceProvider(Resource.Type.ServiceGroupDependency);
+ }
+ return serviceGroupDependencyResourceProvider;
+ }
+
private synchronized ServiceResourceProvider getServiceResourceProvider() {
if (serviceResourceProvider == null) {
serviceResourceProvider = (ServiceResourceProvider) ClusterControllerHelper.
@@ -796,4 +806,4 @@ public class AmbariContext {
}
-}
\ No newline at end of file
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
index ce201e4..19e23c5 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -177,6 +177,15 @@ CREATE TABLE servicegroups (
CONSTRAINT PK_servicegroups PRIMARY KEY (id, cluster_id),
CONSTRAINT FK_servicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+CREATE TABLE servicegroupdependencies (
+ service_group_id BIGINT NOT NULL,
+ service_group_cluster_id BIGINT NOT NULL,
+ dependent_service_group_id BIGINT NOT NULL,
+ dependent_service_group_cluster_id BIGINT NOT NULL,
+ CONSTRAINT PK_servicegroupdependencies PRIMARY KEY (service_group_id, service_group_cluster_id, dependent_service_group_id, dependent_service_group_cluster_id),
+ CONSTRAINT FK_servicegroupdependencies_service_group_cluster_id FOREIGN KEY (service_group_id, service_group_cluster_id) REFERENCES servicegroups (id, cluster_id));
+ CONSTRAINT FK_servicegroupdependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_group_id, dependent_service_group_cluster_id) REFERENCES servicegroups (id, cluster_id));
+
CREATE TABLE clusterservices (
id BIGINT NOT NULL,
service_name VARCHAR(255) NOT NULL,
http://git-wip-us.apache.org/repos/asf/ambari/blob/16913b20/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
index f4d9554..b1990df 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -196,6 +196,15 @@ CREATE TABLE servicegroups (
CONSTRAINT PK_servicegroups PRIMARY KEY (id, cluster_id),
CONSTRAINT FK_servicegroups_cluster_id FOREIGN KEY (cluster_id) REFERENCES clusters (cluster_id));
+CREATE TABLE servicegroupdependencies (
+ service_group_id BIGINT NOT NULL,
+ service_group_cluster_id BIGINT NOT NULL,
+ dependent_service_group_id BIGINT NOT NULL,
+ dependent_service_group_cluster_id BIGINT NOT NULL,
+ CONSTRAINT PK_servicegroupdependencies PRIMARY KEY (service_group_id, service_group_cluster_id, dependent_service_group_id, dependent_service_group_cluster_id),
+ CONSTRAINT FK_servicegroupdependencies_service_group_cluster_id FOREIGN KEY (service_group_id, service_group_cluster_id) REFERENCES servicegroups (id, cluster_id));
+ CONSTRAINT FK_servicegroupdependencies_dependent_service_group_cluster_id FOREIGN KEY (dependent_service_group_id, dependent_service_group_cluster_id) REFERENCES servicegroups (id, cluster_id));
+
CREATE TABLE clusterservices (
id BIGINT NOT NULL,
service_name VARCHAR(255) NOT NULL,