You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by sw...@apache.org on 2013/11/01 19:53:35 UTC
[2/2] git commit: AMBARI-3606. Add ConfigGroup resource provider to
support API calls. (swagle)
AMBARI-3606. Add ConfigGroup resource provider to support API calls. (swagle)
Project: http://git-wip-us.apache.org/repos/asf/incubator-ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ambari/commit/aa8e98f4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ambari/tree/aa8e98f4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ambari/diff/aa8e98f4
Branch: refs/heads/trunk
Commit: aa8e98f467ec64c3227023b3c3dadd61ca98f355
Parents: 12ac556
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Fri Nov 1 11:53:17 2013 -0700
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Fri Nov 1 11:53:17 2013 -0700
----------------------------------------------------------------------
.../ambari/server/api/handlers/ReadHandler.java | 1 +
.../resources/ClusterResourceDefinition.java | 1 +
.../ConfigGroupResourceDefinition.java | 100 +++
.../resources/ResourceInstanceFactoryImpl.java | 4 +
.../server/api/services/ClusterService.java | 8 +
.../server/api/services/ConfigGroupService.java | 157 +++++
.../services/serializers/JsonSerializer.java | 1 -
.../controller/AmbariManagementController.java | 10 +-
.../AmbariManagementControllerImpl.java | 17 +-
.../server/controller/ConfigGroupRequest.java | 102 ++++
.../server/controller/ConfigGroupResponse.java | 100 +++
.../server/controller/ControllerModule.java | 5 +
.../AbstractControllerResourceProvider.java | 2 +
.../internal/AbstractResourceProvider.java | 1 -
.../internal/ClusterControllerImpl.java | 67 +-
.../internal/ConfigGroupResourceProvider.java | 609 +++++++++++++++++++
.../internal/ConfigurationResourceProvider.java | 9 +-
.../DefaultResourcePredicateEvaluator.java | 32 +
.../controller/internal/RequestStatusImpl.java | 1 +
.../controller/internal/ResourceImpl.java | 2 +
.../ambari/server/controller/spi/Resource.java | 1 +
.../spi/ResourcePredicateEvaluator.java | 30 +
.../ambari/server/orm/dao/ClusterDAO.java | 7 +
.../orm/dao/ConfigGroupConfigMappingDAO.java | 10 +
.../orm/dao/ConfigGroupHostMappingDAO.java | 11 +
.../server/orm/entities/ClusterEntity.java | 11 +-
.../org/apache/ambari/server/state/Cluster.java | 30 +
.../apache/ambari/server/state/Clusters.java | 2 +
.../apache/ambari/server/state/ConfigImpl.java | 9 +-
.../server/state/cluster/ClusterImpl.java | 133 ++++
.../server/state/cluster/ClustersImpl.java | 4 +
.../server/state/configgroup/ConfigGroup.java | 150 +++++
.../state/configgroup/ConfigGroupFactory.java | 39 ++
.../state/configgroup/ConfigGroupImpl.java | 513 ++++++++++++++++
.../Ambari-DDL-Postgres-REMOTE-CREATE.sql | 4 +-
.../src/main/resources/key_properties.json | 4 +
.../src/main/resources/properties.json | 9 +
.../api/services/ConfigGroupServiceTest.java | 115 ++++
.../ConfigGroupResourceProviderTest.java | 446 ++++++++++++++
.../ambari/server/state/ConfigGroupTest.java | 214 +++++++
40 files changed, 2944 insertions(+), 27 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
index e4c0064..ffdc1dc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/ReadHandler.java
@@ -78,6 +78,7 @@ public class ReadHandler implements RequestHandler {
} catch (IllegalArgumentException e) {
result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST,
"Invalid Request: " + e.getMessage()));
+ LOG.error("Bad request: ", e);
} catch (RuntimeException e) {
if (LOG.isErrorEnabled()) {
LOG.error("Caught a runtime exception executing a query", e);
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
index eacc6b9..4b0e8e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ClusterResourceDefinition.java
@@ -54,6 +54,7 @@ public class ClusterResourceDefinition extends BaseResourceDefinition {
setChildren.add(new SubResourceDefinition(Resource.Type.Configuration));
setChildren.add(new SubResourceDefinition(Resource.Type.Request));
setChildren.add(new SubResourceDefinition(Resource.Type.Workflow));
+ setChildren.add(new SubResourceDefinition(Resource.Type.ConfigGroup));
return setChildren;
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ConfigGroupResourceDefinition.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ConfigGroupResourceDefinition.java b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ConfigGroupResourceDefinition.java
new file mode 100644
index 0000000..d7bb57d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/resources/ConfigGroupResourceDefinition.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.api.resources;
+
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.util.TreeNode;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.spi.Schema;
+import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ConfigGroupResourceDefinition extends BaseResourceDefinition {
+ /**
+ * Constructor.
+ */
+ public ConfigGroupResourceDefinition() {
+ super(Resource.Type.ConfigGroup);
+ }
+
+ @Override
+ public String getPluralName() {
+ return "config_groups";
+ }
+
+ @Override
+ public String getSingularName() {
+ return "config_group";
+ }
+
+ @Override
+ public List<PostProcessor> getPostProcessors() {
+ List<PostProcessor> listProcessors = super.getPostProcessors();
+ listProcessors.add(new ConfigGroupHrefProcessor());
+
+ return listProcessors;
+ }
+
+ private class ConfigGroupHrefProcessor extends BaseHrefPostProcessor {
+
+ @Override
+ public void process(Request request, TreeNode<Resource> resultNode, String href) {
+ if (resultNode.getObject().getType() == Resource.Type.ConfigGroup) {
+
+ Resource r = resultNode.getObject();
+ Schema schema = ClusterControllerHelper.getClusterController().getSchema(r.getType());
+ Object clusterId = r.getPropertyValue(schema.getKeyPropertyId
+ (Resource.Type.Cluster));
+
+ Map<String, Object> configGroup = r.getPropertiesMap().get("ConfigGroup");
+ String partialUrl = href.substring(0, href.indexOf("/clusters/")
+ + "/clusters/".length()) + clusterId;
+
+ for (Map.Entry<String, Object> entry : configGroup.entrySet()) {
+ if (entry.getKey().contains("hosts") && entry.getValue() != null) {
+ Set<Map<String, Object>> hostSet = (Set<Map<String, Object>>) entry.getValue();
+
+ for (Map<String, Object> hostMap : hostSet) {
+ String idx = partialUrl + "/hosts/" + hostMap.get("host_name");
+ hostMap.put("href", idx);
+ }
+
+ } else if (entry.getKey().contains("desired_configs") && entry
+ .getValue() != null) {
+
+ Set<Map<String, Object>> configSet = (Set<Map<String,
+ Object>>) entry.getValue();
+
+ for (Map<String, Object> configMap : configSet) {
+ String idx = partialUrl + "/configurations?"
+ + "type=" + configMap.get("type")
+ + "&tag=" + configMap.get("tag");
+ configMap.put("href", idx);
+ }
+ }
+
+ }
+ } else {
+ super.process(request, resultNode, href);
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/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 f3a53be..e71f1fc 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
@@ -143,6 +143,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
resourceDefinition = new RootServiceHostComponentResourceDefinition();
break;
+ case ConfigGroup:
+ resourceDefinition = new ConfigGroupResourceDefinition();
+ break;
+
default:
throw new IllegalArgumentException("Unsupported resource type: " + type);
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
index 8451b85..4da4385 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ClusterService.java
@@ -192,6 +192,14 @@ public class ClusterService extends BaseService {
}
/**
+ * Gets the config group service
+ */
+ @Path("{clusterName}/config_groups")
+ public ConfigGroupService getConfigGroupService(@PathParam("clusterName") String clusterName) {
+ return new ConfigGroupService(clusterName);
+ }
+
+ /**
* Create a cluster resource instance.
*
* @param clusterName cluster name
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigGroupService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigGroupService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigGroupService.java
new file mode 100644
index 0000000..4fb9a88
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ConfigGroupService.java
@@ -0,0 +1,157 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.api.services;
+
+import org.apache.ambari.server.api.resources.ResourceInstance;
+import org.apache.ambari.server.controller.spi.Resource;
+
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Service responsible for management of Config Groups
+ */
+public class ConfigGroupService extends BaseService {
+ /**
+ * Parent cluster name.
+ */
+ private String m_clusterName;
+
+ /**
+ * Constructor
+ * @param m_clusterName
+ */
+ public ConfigGroupService(String m_clusterName) {
+ this.m_clusterName = m_clusterName;
+ }
+
+ /**
+ * Handles URL: /clusters/{clusterId}/config_groups
+ * Get all the config groups for a cluster.
+ *
+ * @param headers
+ * @param ui
+ * @return
+ */
+ @GET
+ @Produces("text/plain")
+ public Response getConfigGroups(@Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createConfigGroupResource(m_clusterName, null));
+ }
+
+ /**
+ * Handles URL: /clusters/{clusterId}/config_groups/{groupId}
+ * Get details on a config group.
+ *
+ * @return
+ */
+ @GET
+ @Path("{groupId}")
+ @Produces("text/plain")
+ public Response getConfigGroup(@Context HttpHeaders headers,
+ @Context UriInfo ui, @PathParam("groupId") String groupId) {
+ return handleRequest(headers, null, ui, Request.Type.GET,
+ createConfigGroupResource(m_clusterName, groupId));
+ }
+
+ /**
+ * Handles POST /clusters/{clusterId}/config_groups
+ * Create a new config group
+ *
+ * @param body
+ * @param headers
+ * @param ui
+ * @return
+ */
+ @POST
+ @Produces("text/plain")
+ public Response createConfigGroup(String body, @Context HttpHeaders headers,
+ @Context UriInfo ui) {
+ return handleRequest(headers, body, ui, Request.Type.POST,
+ createConfigGroupResource(m_clusterName, null));
+ }
+
+ /**
+ * Handles PUT /clusters/{clusterId}/config_groups/{groupId}
+ * Update a config group
+ *
+ * @param body
+ * @param headers
+ * @param ui
+ * @param groupId
+ * @return
+ */
+ @PUT
+ @Path("{groupId}")
+ @Produces("text/plain")
+ public Response updateConfigGroup(String body, @Context HttpHeaders
+ headers, @Context UriInfo ui, @PathParam("groupId") String groupId) {
+ return handleRequest(headers, body, ui, Request.Type.PUT,
+ createConfigGroupResource(m_clusterName, groupId));
+ }
+
+ /**
+ * Handles DELETE /clusters/{clusterId}/config_groups/{groupId}
+ * Delete a config group
+ *
+ * @param headers
+ * @param ui
+ * @param groupId
+ * @return
+ */
+ @DELETE
+ @Path("{groupId}")
+ @Produces("text/plain")
+ public Response deleteConfigGroup(@Context HttpHeaders headers,
+ @Context UriInfo ui,
+ @PathParam("groupId") String groupId) {
+ return handleRequest(headers, null, ui, Request.Type.DELETE,
+ createConfigGroupResource(m_clusterName, groupId));
+ }
+
+
+ /**
+ * Create a request resource instance.
+ *
+ * @param clusterName cluster name
+ * @param groupId config group id
+ *
+ * @return a request resource instance
+ */
+ ResourceInstance createConfigGroupResource(String clusterName,
+ String groupId) {
+ Map<Resource.Type,String> mapIds = new HashMap<Resource.Type, String>();
+ mapIds.put(Resource.Type.Cluster, clusterName);
+ mapIds.put(Resource.Type.ConfigGroup, groupId);
+
+ return createResource(Resource.Type.ConfigGroup, mapIds);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
index bb5eddb..038ac90 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
@@ -101,7 +101,6 @@ public class JsonSerializer implements ResultSerializer {
}
private void processNode(TreeNode<Resource> node) throws IOException {
-
if (isObject(node)) {
m_generator.writeStartObject();
writeHref(node);
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
index 32f25ea..40389c2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementController.java
@@ -23,12 +23,14 @@ import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.ConfigFactory;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
import org.apache.ambari.server.state.ServiceComponentFactory;
import org.apache.ambari.server.state.ServiceComponentHost;
import org.apache.ambari.server.state.ServiceFactory;
import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import java.util.Collection;
import java.util.List;
@@ -486,5 +488,11 @@ public interface AmbariManagementController {
Map<String, Map<State, List<ServiceComponentHost>>> changedHosts,
Collection<ServiceComponentHost> ignoredHosts,
boolean runSmokeTest, boolean reconfigureClients) throws AmbariException;
- }
+
+ public ConfigGroupFactory getConfigGroupFactory();
+
+ public ConfigFactory getConfigFactory();
+
+ public String getAuthName();
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 78c3c90..0c8119b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -83,6 +83,7 @@ import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostInstallEvent;
import org.apache.ambari.server.state.svccomphost.ServiceComponentHostMaintenanceEvent;
@@ -151,6 +152,8 @@ public class AmbariManagementControllerImpl implements
private Configuration configs;
@Inject
private AbstractRootServiceResponseFactory rootServiceResponseFactory;
+ @Inject
+ private ConfigGroupFactory configGroupFactory;
final private String masterHostname;
final private Integer masterPort;
@@ -1262,7 +1265,7 @@ public class AmbariManagementControllerImpl implements
// HACK HACK HACK if the service has configs that are NOT included
// in cluster-level, then use them anyway. THIS IS GENERALLY A BAD
- // IDEA, but is included for backward compatability. Do not check host
+ // IDEA, but is included for backward compatibility. Do not check host
// overrides, because that wasn't in the version where this code would
// be the case.
Service service = cluster.getService(serviceName);
@@ -3195,7 +3198,7 @@ public class AmbariManagementControllerImpl implements
/**
* @return the authenticated user's name
*/
- private String getAuthName() {
+ public String getAuthName() {
return AuthorizationHelper.getAuthenticatedName(configs.getAnonymousAuditName());
}
@@ -3292,6 +3295,16 @@ public class AmbariManagementControllerImpl implements
}
@Override
+ public ConfigGroupFactory getConfigGroupFactory() {
+ return configGroupFactory;
+ }
+
+ @Override
+ public ConfigFactory getConfigFactory() {
+ return configFactory;
+ }
+
+ @Override
public ActionManager getActionManager() {
return actionManager;
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupRequest.java
new file mode 100644
index 0000000..4c0d3a2
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupRequest.java
@@ -0,0 +1,102 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller;
+
+import org.apache.ambari.server.state.Config;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class ConfigGroupRequest {
+ private Long id;
+ private String clusterName;
+ private String groupName;
+ private String tag;
+ private String description;
+ private Set<String> hosts;
+ private Map<String, Config> configs;
+
+ public ConfigGroupRequest(Long id, String clusterName, String groupName,
+ String tag, String description, Set<String> hosts,
+ Map<String, Config> configs) {
+ this.id = id;
+ this.clusterName = clusterName;
+ this.groupName = groupName;
+ this.tag = tag;
+ this.description = description;
+ this.hosts = hosts;
+ this.configs = configs;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Set<String> getHosts() {
+ return hosts;
+ }
+
+ public void setHosts(Set<String> hosts) {
+ this.hosts = hosts;
+ }
+
+ public Map<String, Config> getConfigs() {
+ return configs;
+ }
+
+ public void setConfigs(Map<String, Config> configs) {
+ this.configs = configs;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupResponse.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupResponse.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupResponse.java
new file mode 100644
index 0000000..a9f0687
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/ConfigGroupResponse.java
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller;
+
+import java.util.Map;
+import java.util.Set;
+
+public class ConfigGroupResponse {
+ private Long id;
+ private String clusterName;
+ private String groupName;
+ private String tag;
+ private String description;
+ private Set<Map<String, Object>> hosts;
+ private Set<Map<String, Object>> configVersions;
+
+ public ConfigGroupResponse(Long id, String clusterName,
+ String groupName, String tag, String description,
+ Set<Map<String, Object>> hosts,
+ Set<Map<String, Object>> configVersions) {
+ this.id = id;
+ this.clusterName = clusterName;
+ this.groupName = groupName;
+ this.tag = tag;
+ this.description = description;
+ this.hosts = hosts;
+ this.configVersions = configVersions;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getClusterName() {
+ return clusterName;
+ }
+
+ public void setClusterName(String clusterName) {
+ this.clusterName = clusterName;
+ }
+
+ public String getGroupName() {
+ return groupName;
+ }
+
+ public void setGroupName(String groupName) {
+ this.groupName = groupName;
+ }
+
+ public String getTag() {
+ return tag;
+ }
+
+ public void setTag(String tag) {
+ this.tag = tag;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public Set<Map<String, Object>> getHosts() {
+ return hosts;
+ }
+
+ public void setHosts(Set<Map<String, Object>> hosts) {
+ this.hosts = hosts;
+ }
+
+ public Set<Map<String, Object>> getConfigurations() {
+ return configVersions;
+ }
+
+ public void setConfigurations(Set<Map<String, Object>> configurations) {
+ this.configVersions = configurations;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/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 597fbc5..f35e277 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
@@ -18,6 +18,9 @@
package org.apache.ambari.server.controller;
+import org.apache.ambari.server.state.configgroup.ConfigGroup;
+import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
+import org.apache.ambari.server.state.configgroup.ConfigGroupImpl;
import org.apache.ambari.server.state.svccomphost.HBaseMasterPortScanner;
import com.google.gson.Gson;
import com.google.inject.Scopes;
@@ -165,6 +168,8 @@ public class ControllerModule extends AbstractModule {
ServiceComponentHostFactory.class));
install(new FactoryModuleBuilder().implement(
Config.class, ConfigImpl.class).build(ConfigFactory.class));
+ install(new FactoryModuleBuilder().implement(
+ ConfigGroup.class, ConfigGroupImpl.class).build(ConfigGroupFactory.class));
install(new FactoryModuleBuilder().build(StageFactory.class));
bind(HostRoleCommandFactory.class).to(HostRoleCommandFactoryImpl.class);
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/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 1a5a38b..464040e 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
@@ -125,6 +125,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractResourc
return new RootServiceComponentResourceProvider(propertyIds, keyPropertyIds, managementController);
case RootServiceHostComponent:
return new RootServiceHostComponentResourceProvider(propertyIds, keyPropertyIds, managementController);
+ case ConfigGroup:
+ return new ConfigGroupResourceProvider(propertyIds, keyPropertyIds, managementController);
default:
throw new IllegalArgumentException("Unknown type " + type);
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
index 0c8ddc6..cec3d1d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractResourceProvider.java
@@ -340,7 +340,6 @@ public abstract class AbstractResourceProvider extends BaseProvider implements R
return config;
}
-
// ----- Inner interface ---------------------------------------------------
/**
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
index 5bad486..34bc117 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ClusterControllerImpl.java
@@ -75,6 +75,12 @@ public class ClusterControllerImpl implements ClusterController {
*/
private final ResourceComparator comparator = new ResourceComparator();
+ /**
+ * Predicate evaluator
+ */
+ private static final DefaultResourcePredicateEvaluator
+ DEFAULT_RESOURCE_PREDICATE_EVALUATOR =
+ new DefaultResourcePredicateEvaluator();
// ----- Constructors ------------------------------------------------------
@@ -105,6 +111,9 @@ public class ClusterControllerImpl implements ClusterController {
ensurePropertyProviders(type);
Set<Resource> resources;
+ ResourcePredicateEvaluator evaluator = provider instanceof ResourcePredicateEvaluator ?
+ (ResourcePredicateEvaluator) provider : DEFAULT_RESOURCE_PREDICATE_EVALUATOR;
+
if (provider == null) {
resources = Collections.emptySet();
} else {
@@ -128,13 +137,17 @@ public class ClusterControllerImpl implements ClusterController {
if (pageRequest != null) {
switch (pageRequest.getStartingPoint()) {
case Beginning:
- return getPageFromOffset(pageRequest.getPageSize(), 0, sortedResources, predicate);
+ return getPageFromOffset(pageRequest.getPageSize(), 0,
+ sortedResources, predicate, evaluator);
case End:
- return getPageToOffset(pageRequest.getPageSize(), -1, sortedResources, predicate);
+ return getPageToOffset(pageRequest.getPageSize(), -1,
+ sortedResources, predicate, evaluator);
case OffsetStart:
- return getPageFromOffset(pageRequest.getPageSize(), pageRequest.getOffset(), sortedResources, predicate);
+ return getPageFromOffset(pageRequest.getPageSize(),
+ pageRequest.getOffset(), sortedResources, predicate, evaluator);
case OffsetEnd:
- return getPageToOffset(pageRequest.getPageSize(), pageRequest.getOffset(), sortedResources, predicate);
+ return getPageToOffset(pageRequest.getPageSize(),
+ pageRequest.getOffset(), sortedResources, predicate, evaluator);
// TODO : need to support the following cases for pagination
// case PredicateStart:
// case PredicateEnd:
@@ -143,7 +156,8 @@ public class ClusterControllerImpl implements ClusterController {
resources = sortedResources;
}
- return new PageResponseImpl(new ResourceIterable(resources, predicate), 0, null, null);
+ return new PageResponseImpl(new ResourceIterable(resources, predicate, evaluator),
+ 0, null, null);
}
@Override
@@ -417,7 +431,10 @@ public class ClusterControllerImpl implements ClusterController {
*
* @return a page response containing a page of resources
*/
- private PageResponse getPageFromOffset(int pageSize, int offset, NavigableSet<Resource> resources, Predicate predicate) {
+ private PageResponse getPageFromOffset(int pageSize, int offset,
+ NavigableSet<Resource> resources,
+ Predicate predicate,
+ ResourcePredicateEvaluator evaluator) {
int currentOffset = 0;
Resource previous = null;
@@ -435,7 +452,8 @@ public class ClusterControllerImpl implements ClusterController {
pageResources.add(iterator.next());
}
- return new PageResponseImpl(new ResourceIterable(pageResources, predicate),
+ return new PageResponseImpl(new ResourceIterable(pageResources,
+ predicate, evaluator),
currentOffset,
previous,
iterator.hasNext() ? iterator.next() : null);
@@ -451,7 +469,10 @@ public class ClusterControllerImpl implements ClusterController {
*
* @return a page response containing a page of resources
*/
- private PageResponse getPageToOffset(int pageSize, int offset, NavigableSet<Resource> resources, Predicate predicate) {
+ private PageResponse getPageToOffset(int pageSize, int offset,
+ NavigableSet<Resource> resources,
+ Predicate predicate,
+ ResourcePredicateEvaluator evaluator) {
int currentOffset = resources.size() - 1;
Resource next = null;
@@ -472,7 +493,8 @@ public class ClusterControllerImpl implements ClusterController {
--currentOffset;
}
- return new PageResponseImpl(new ResourceIterable(new LinkedHashSet<Resource>(pageResources), predicate),
+ return new PageResponseImpl(new ResourceIterable(new
+ LinkedHashSet<Resource>(pageResources), predicate, evaluator),
currentOffset + 1,
iterator.hasNext() ? iterator.next() : null,
next);
@@ -501,6 +523,11 @@ public class ClusterControllerImpl implements ClusterController {
*/
private final Predicate predicate;
+ /**
+ * The predicate evaluator.
+ */
+ private final ResourcePredicateEvaluator evaluator;
+
// ----- Constructors ----------------------------------------------------
/**
@@ -509,16 +536,18 @@ public class ClusterControllerImpl implements ClusterController {
* @param resources the set of resources to iterate over
* @param predicate the predicate used to filter the set of resources
*/
- private ResourceIterable(Set<Resource> resources, Predicate predicate) {
+ private ResourceIterable(Set<Resource> resources, Predicate predicate,
+ ResourcePredicateEvaluator evaluator) {
this.resources = resources;
this.predicate = predicate;
+ this.evaluator = evaluator;
}
// ----- Iterable --------------------------------------------------------
@Override
public Iterator<Resource> iterator() {
- return new ResourceIterator(resources, predicate);
+ return new ResourceIterator(resources, predicate, evaluator);
}
}
@@ -542,6 +571,10 @@ public class ClusterControllerImpl implements ClusterController {
*/
private Resource nextResource;
+ /**
+ * The predicate evaluator.
+ */
+ private final ResourcePredicateEvaluator evaluator;
// ----- Constructors ----------------------------------------------------
@@ -551,9 +584,11 @@ public class ClusterControllerImpl implements ClusterController {
* @param resources the set of resources to iterate over
* @param predicate the predicate used to filter the set of resources
*/
- private ResourceIterator(Set<Resource> resources, Predicate predicate) {
- this.iterator = resources.iterator();
- this.predicate = predicate;
+ private ResourceIterator(Set<Resource> resources, Predicate predicate,
+ ResourcePredicateEvaluator evaluator) {
+ this.iterator = resources.iterator();
+ this.predicate = predicate;
+ this.evaluator = evaluator;
this.nextResource = getNextResource();
}
@@ -591,8 +626,8 @@ public class ClusterControllerImpl implements ClusterController {
private Resource getNextResource() {
while (iterator.hasNext()) {
Resource next = iterator.next();
-
- if (predicate == null || predicate.evaluate(next)) {
+
+ if (predicate == null || evaluator.evaluate(predicate, next)) {
return next;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
new file mode 100644
index 0000000..982a163
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigGroupResourceProvider.java
@@ -0,0 +1,609 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ClusterNotFoundException;
+import org.apache.ambari.server.DuplicateResourceException;
+import org.apache.ambari.server.HostNotFoundException;
+import org.apache.ambari.server.ParentObjectNotFoundException;
+import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.ConfigGroupRequest;
+import org.apache.ambari.server.controller.ConfigGroupResponse;
+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.ResourcePredicateEvaluator;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.controller.spi.UnsupportedPropertyException;
+import org.apache.ambari.server.controller.utilities.PropertyHelper;
+import org.apache.ambari.server.orm.entities.ConfigGroupEntity;
+import org.apache.ambari.server.security.authorization.AuthorizationHelper;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.ConfigImpl;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.configgroup.ConfigGroup;
+import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+public class ConfigGroupResourceProvider extends
+ AbstractControllerResourceProvider implements ResourcePredicateEvaluator {
+ protected static final String CONFIGGROUP_CLUSTER_NAME_PROPERTY_ID =
+ PropertyHelper.getPropertyId("ConfigGroup", "cluster_name");
+ protected static final String CONFIGGROUP_ID_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ConfigGroup", "id");
+ protected static final String CONFIGGROUP_NAME_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ConfigGroup", "group_name");
+ protected static final String CONFIGGROUP_TAG_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ConfigGroup", "tag");
+ protected static final String CONFIGGROUP_DESC_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ConfigGroup", "description");
+ protected static final String CONFIGGROUP_HOSTNAME_PROPERTY_ID =
+ PropertyHelper.getPropertyId(null, "host_name");
+ public static final String CONFIGGROUP_HOSTS_PROPERTY_ID = PropertyHelper
+ .getPropertyId("ConfigGroup", "hosts");
+ public static final String CONFIGGROUP_CONFIGS_PROPERTY_ID =
+ PropertyHelper.getPropertyId("ConfigGroup", "desired_configs");
+
+ private static Set<String> pkPropertyIds = new HashSet<String>(Arrays
+ .asList(new String[] { CONFIGGROUP_ID_PROPERTY_ID }));
+
+ /**
+ * Create a new resource provider for the given management controller.
+ *
+ * @param propertyIds the property ids
+ * @param keyPropertyIds the key property ids
+ * @param managementController the management controller
+ */
+ protected ConfigGroupResourceProvider(Set<String> propertyIds,
+ Map<Resource.Type, String> keyPropertyIds,
+ AmbariManagementController managementController) {
+ super(propertyIds, keyPropertyIds, managementController);
+ }
+
+ @Override
+ protected Set<String> getPKPropertyIds() {
+ return pkPropertyIds;
+ }
+
+ @Override
+ public RequestStatus createResources(Request request) throws
+ SystemException, UnsupportedPropertyException,
+ ResourceAlreadyExistsException, NoSuchParentResourceException {
+
+ final Set<ConfigGroupRequest> requests = new HashSet<ConfigGroupRequest>();
+ for (Map<String, Object> propertyMap : request.getProperties()) {
+ requests.add(getConfigGroupRequest(propertyMap));
+ }
+ Set<ConfigGroupResponse> responses =
+ createResources(new Command<Set<ConfigGroupResponse>>() {
+ @Override
+ public Set<ConfigGroupResponse> invoke() throws AmbariException {
+ return createConfigGroups(requests);
+ }
+ });
+
+ notifyCreate(Resource.Type.ConfigGroup, request);
+
+ Set<Resource> associatedResources = new HashSet<Resource>();
+ for (ConfigGroupResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.ConfigGroup);
+ resource.setProperty(CONFIGGROUP_ID_PROPERTY_ID, response.getId());
+ associatedResources.add(resource);
+ }
+
+ return getRequestStatus(null, associatedResources);
+ }
+
+ @Override
+ public Set<Resource> getResources(Request request, Predicate predicate) throws
+ SystemException, UnsupportedPropertyException, NoSuchResourceException,
+ NoSuchParentResourceException {
+
+ final Set<ConfigGroupRequest> requests = new HashSet<ConfigGroupRequest>();
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ requests.add(getConfigGroupRequest(propertyMap));
+ }
+
+ Set<ConfigGroupResponse> responses = getResources(new Command<Set<ConfigGroupResponse>>() {
+ @Override
+ public Set<ConfigGroupResponse> invoke() throws AmbariException {
+ return getConfigGroups(requests);
+ }
+ });
+
+ Set<String> requestedIds = getRequestPropertyIds(request, predicate);
+ Set<Resource> resources = new HashSet<Resource>();
+
+ for (ConfigGroupResponse response : responses) {
+ Resource resource = new ResourceImpl(Resource.Type.ConfigGroup);
+
+ setResourceProperty(resource, CONFIGGROUP_ID_PROPERTY_ID,
+ response.getId(), requestedIds);
+ setResourceProperty(resource, CONFIGGROUP_CLUSTER_NAME_PROPERTY_ID,
+ response.getClusterName(), requestedIds);
+ setResourceProperty(resource, CONFIGGROUP_NAME_PROPERTY_ID,
+ response.getGroupName(), requestedIds);
+ setResourceProperty(resource, CONFIGGROUP_TAG_PROPERTY_ID,
+ response.getTag(), requestedIds);
+ setResourceProperty(resource, CONFIGGROUP_DESC_PROPERTY_ID,
+ response.getDescription(), requestedIds);
+ setResourceProperty(resource, CONFIGGROUP_HOSTS_PROPERTY_ID,
+ response.getHosts(), requestedIds);
+ setResourceProperty(resource, CONFIGGROUP_CONFIGS_PROPERTY_ID,
+ response.getConfigurations(), requestedIds);
+
+ resources.add(resource);
+ }
+
+ return resources;
+ }
+
+ @Override
+ public RequestStatus updateResources(Request request, Predicate predicate) throws
+ SystemException, UnsupportedPropertyException,
+ NoSuchResourceException, NoSuchParentResourceException {
+
+ final Set<ConfigGroupRequest> requests = new HashSet<ConfigGroupRequest>();
+
+ Iterator<Map<String,Object>> iterator = request.getProperties().iterator();
+ if (iterator.hasNext()) {
+ for (Map<String, Object> propertyMap : getPropertyMaps(iterator.next(), predicate)) {
+ requests.add(getConfigGroupRequest(propertyMap));
+ }
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ updateConfigGroups(requests);
+ return null;
+ }
+ });
+ }
+
+ notifyUpdate(Resource.Type.ConfigGroup, request, predicate);
+
+ return getRequestStatus(null);
+ }
+
+ @Override
+ public RequestStatus deleteResources(Predicate predicate) throws
+ SystemException, UnsupportedPropertyException, NoSuchResourceException,
+ NoSuchParentResourceException {
+
+ for (Map<String, Object> propertyMap : getPropertyMaps(predicate)) {
+ final ConfigGroupRequest configGroupRequest = getConfigGroupRequest(propertyMap);
+
+ modifyResources(new Command<Void>() {
+ @Override
+ public Void invoke() throws AmbariException {
+ deleteConfigGroup(configGroupRequest);
+ return null;
+ }
+ });
+ }
+
+ notifyDelete(Resource.Type.ConfigGroup, predicate);
+
+ return getRequestStatus(null);
+ }
+
+ private synchronized Set<ConfigGroupResponse> getConfigGroups
+ (Set<ConfigGroupRequest> requests) throws AmbariException {
+ Set<ConfigGroupResponse> responses = new HashSet<ConfigGroupResponse>();
+ if (requests != null) {
+ for (ConfigGroupRequest request : requests) {
+ LOG.debug("Received a Config group request with"
+ + ", clusterName = " + request.getClusterName()
+ + ", groupId = " + request.getId()
+ + ", groupName = " + request.getGroupName()
+ + ", tag = " + request.getTag());
+
+ if (request.getClusterName() == null) {
+ LOG.warn("Cluster name is a required field.");
+ continue;
+ }
+
+ Cluster cluster = getManagementController().getClusters().getCluster
+ (request.getClusterName());
+ Map<Long, ConfigGroup> configGroupMap = cluster.getConfigGroups();
+
+ // By group id
+ if (request.getId() != null) {
+ ConfigGroup configGroup = configGroupMap.get(request.getId());
+ if (configGroup != null) {
+ responses.add(configGroup.convertToResponse());
+ }
+ continue;
+ }
+ // By group name
+ if (request.getGroupName() != null) {
+ for (ConfigGroup configGroup : configGroupMap.values()) {
+ if (configGroup.getName().equals(request.getGroupName())) {
+ responses.add(configGroup.convertToResponse());
+ }
+ }
+ continue;
+ }
+ // By tag only
+ if (request.getTag() != null && request.getHosts().isEmpty()) {
+ for (ConfigGroup configGroup : configGroupMap.values()) {
+ if (configGroup.getTag().equals(request.getTag())) {
+ responses.add(configGroup.convertToResponse());
+ }
+ }
+ continue;
+ }
+ // By hostnames only
+ if (!request.getHosts().isEmpty() && request.getTag() == null) {
+ for (String hostname : request.getHosts()) {
+ Map<Long, ConfigGroup> groupMap = cluster
+ .getConfigGroupsByHostname(hostname);
+
+ if (!groupMap.isEmpty()) {
+ for (ConfigGroup configGroup : groupMap.values()) {
+ responses.add(configGroup.convertToResponse());
+ }
+ }
+ }
+ continue;
+ }
+ // By tag and hostnames
+ if (request.getTag() != null && !request.getHosts().isEmpty()) {
+ for (ConfigGroup configGroup : configGroupMap.values()) {
+ // Has tag
+ if (configGroup.getTag().equals(request.getTag())) {
+ // Has a match with hosts
+ Set<String> groupHosts = new HashSet<String>(configGroup
+ .getHosts().keySet());
+ groupHosts.retainAll(request.getHosts());
+ if (!groupHosts.isEmpty()) {
+ responses.add(configGroup.convertToResponse());
+ }
+ }
+ }
+ continue;
+ }
+ // Select all
+ for (ConfigGroup configGroup : configGroupMap.values()) {
+ responses.add(configGroup.convertToResponse());
+ }
+ }
+ }
+ return responses;
+ }
+
+ private void verifyHostList(Cluster cluster, Map<String, Host> hosts,
+ ConfigGroupRequest request) throws AmbariException {
+
+ Map<Long, ConfigGroup> configGroupMap = cluster.getConfigGroups();
+
+ if (configGroupMap != null) {
+ for (ConfigGroup configGroup : configGroupMap.values()) {
+ if (configGroup.getTag().equals(request.getTag())
+ && !configGroup.getId().equals(request.getId())) {
+ // Check the new host list for duplicated with this group
+ for (Host host : hosts.values()) {
+ if (configGroup.getHosts().containsKey(host.getHostName())) {
+ throw new DuplicateResourceException("Host is already " +
+ "associated with a config group"
+ + ", clusterName = " + configGroup.getClusterName()
+ + ", configGroupName = " + configGroup.getName()
+ + ", tag = " + configGroup.getTag()
+ + ", hostname = " + host.getHostName());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private synchronized void deleteConfigGroup(ConfigGroupRequest request)
+ throws AmbariException {
+ if (request.getId() == null) {
+ throw new AmbariException("Config group id is a required field.");
+ }
+
+ Clusters clusters = getManagementController().getClusters();
+
+ Cluster cluster;
+ try {
+ cluster = clusters.getCluster(request.getClusterName());
+ } catch (ClusterNotFoundException e) {
+ throw new ParentObjectNotFoundException(
+ "Attempted to add a service to a cluster which doesn't exist", e);
+ }
+
+ cluster.deleteConfigGroup(request.getId());
+ }
+
+ private void validateRequest(ConfigGroupRequest request) {
+ if (request.getClusterName() == null
+ || request.getClusterName().isEmpty()
+ || request.getGroupName() == null
+ || request.getGroupName().isEmpty()
+ || request.getTag() == null
+ || request.getTag().isEmpty()) {
+
+ LOG.debug("Received a config group request with cluster name = " +
+ request.getClusterName() + ", group name = " + request.getGroupName()
+ + ", tag = " + request.getTag());
+
+ throw new IllegalArgumentException("Cluster name, " +
+ "group name and tag need to be provided.");
+
+ }
+ }
+
+ private synchronized Set<ConfigGroupResponse> createConfigGroups
+ (Set<ConfigGroupRequest> requests) throws AmbariException {
+
+ if (requests.isEmpty()) {
+ LOG.warn("Received an empty requests set");
+ return null;
+ }
+
+ Set<ConfigGroupResponse> configGroupResponses = new
+ HashSet<ConfigGroupResponse>();
+
+ Clusters clusters = getManagementController().getClusters();
+ ConfigGroupFactory configGroupFactory = getManagementController()
+ .getConfigGroupFactory();
+
+ for (ConfigGroupRequest request : requests) {
+
+ Cluster cluster;
+ try {
+ cluster = clusters.getCluster(request.getClusterName());
+ } catch (ClusterNotFoundException e) {
+ throw new ParentObjectNotFoundException(
+ "Attempted to add a config group to a cluster which doesn't exist", e);
+ }
+
+ validateRequest(request);
+
+ Map<Long, ConfigGroup> configGroupMap = cluster.getConfigGroups();
+ if (configGroupMap != null) {
+ for (ConfigGroup configGroup : configGroupMap.values()) {
+ if (configGroup.getName().equals(request.getGroupName())) {
+ throw new DuplicateResourceException("Config group already " +
+ "exists with the same name, "
+ + "clusterName = " + request.getClusterName()
+ + ", groupName = " + request.getGroupName());
+ }
+ }
+ }
+
+ // Find hosts
+ Map<String, Host> hosts = new HashMap<String, Host>();
+ if (request.getHosts() != null && !request.getHosts().isEmpty()) {
+ for (String hostname : request.getHosts()) {
+ Host host = clusters.getHost(hostname);
+ if (host == null) {
+ throw new HostNotFoundException(hostname);
+ }
+ hosts.put(hostname, host);
+ }
+ }
+
+ verifyHostList(cluster, hosts, request);
+
+ ConfigGroup configGroup = configGroupFactory.createNew(cluster,
+ request.getGroupName(),
+ request.getTag(), request.getDescription(),
+ request.getConfigs(), hosts);
+
+ // Persist before add, since id is auto-generated
+ Logger logger = LoggerFactory.getLogger("configchange");
+ logger.info("Persisting new Config group, "
+ + ", clusterName = " + configGroup.getClusterName()
+ + ", id = " + configGroup.getId()
+ + ", tag = " + configGroup.getTag()
+ + ", user = " + getManagementController().getAuthName());
+
+ configGroup.persist();
+ cluster.addConfigGroup(configGroup);
+
+ ConfigGroupResponse response = new ConfigGroupResponse(configGroup
+ .getId(), configGroup.getClusterName(), configGroup.getName(),
+ configGroup.getTag(), configGroup.getDescription(), null, null);
+
+ configGroupResponses.add(response);
+ }
+
+ return configGroupResponses;
+ }
+
+ private synchronized void updateConfigGroups
+ (Set<ConfigGroupRequest> requests) throws AmbariException {
+
+ if (requests.isEmpty()) {
+ LOG.warn("Received an empty requests set");
+ return;
+ }
+
+ Clusters clusters = getManagementController().getClusters();
+
+ for (ConfigGroupRequest request : requests) {
+
+ Cluster cluster;
+ try {
+ cluster = clusters.getCluster(request.getClusterName());
+ } catch (ClusterNotFoundException e) {
+ throw new ParentObjectNotFoundException(
+ "Attempted to add a service to a cluster which doesn't exist", e);
+ }
+
+ if (request.getId() == null) {
+ throw new AmbariException("Config group Id is a required parameter.");
+ }
+
+ validateRequest(request);
+
+ // Find config group
+ ConfigGroup configGroup = cluster.getConfigGroups().get(request.getId());
+ if (configGroup == null) {
+ throw new AmbariException("Config group not found"
+ + ", clusterName = " + request.getClusterName()
+ + ", groupId = " + request.getId());
+ }
+
+ // Update hosts
+ Map<String, Host> hosts = new HashMap<String, Host>();
+ if (request.getHosts() != null && !request.getHosts().isEmpty()) {
+ for (String hostname : request.getHosts()) {
+ Host host = clusters.getHost(hostname);
+ if (host == null) {
+ throw new HostNotFoundException(hostname);
+ }
+ hosts.put(hostname, host);
+ }
+ }
+
+ verifyHostList(cluster, hosts, request);
+
+ configGroup.setHosts(hosts);
+
+ // Update Configs
+ configGroup.setConfigurations(request.getConfigs());
+
+ // Save
+ configGroup.setName(request.getGroupName());
+ configGroup.setDescription(request.getDescription());
+ configGroup.setTag(request.getTag());
+
+ Logger logger = LoggerFactory.getLogger("configchange");
+ logger.info("Persisting updated Config group, "
+ + ", clusterName = " + configGroup.getClusterName()
+ + ", id = " + configGroup.getId()
+ + ", tag = " + configGroup.getTag()
+ + ", user = " + getManagementController().getAuthName());
+
+ configGroup.persist();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private ConfigGroupRequest getConfigGroupRequest(Map<String, Object> properties) {
+ Object groupIdObj = properties.get(CONFIGGROUP_ID_PROPERTY_ID);
+ Long groupId = null;
+ if (groupIdObj != null) {
+ groupId = groupIdObj instanceof Long ? (Long) groupIdObj :
+ Long.parseLong((String) groupIdObj);
+ }
+
+ ConfigGroupRequest request = new ConfigGroupRequest(
+ groupId,
+ (String) properties.get(CONFIGGROUP_CLUSTER_NAME_PROPERTY_ID),
+ (String) properties.get(CONFIGGROUP_NAME_PROPERTY_ID),
+ (String) properties.get(CONFIGGROUP_TAG_PROPERTY_ID),
+ (String) properties.get(CONFIGGROUP_DESC_PROPERTY_ID),
+ null,
+ null);
+
+ Map<String, Config> configurations = new HashMap<String, Config>();
+ Set<String> hosts = new HashSet<String>();
+
+ Object hostObj = properties.get(CONFIGGROUP_HOSTS_PROPERTY_ID);
+ if (hostObj != null) {
+ if (hostObj instanceof HashSet<?>) {
+ try {
+ Set<Map<String, String>> hostsSet = (Set<Map<String, String>>) hostObj;
+ for (Map<String, String> hostMap : hostsSet) {
+ if (hostMap.containsKey(CONFIGGROUP_HOSTNAME_PROPERTY_ID)) {
+ String hostname = hostMap.get(CONFIGGROUP_HOSTNAME_PROPERTY_ID);
+ hosts.add(hostname);
+ }
+ }
+ } catch (Exception e) {
+ LOG.warn("Host json in unparseable format. " + hostObj, e);
+ }
+ } else {
+ if (hostObj instanceof String) {
+ hosts.add((String) hostObj);
+ }
+ }
+ }
+
+ Object configObj = properties.get(CONFIGGROUP_CONFIGS_PROPERTY_ID);
+ if (configObj != null && configObj instanceof HashSet<?>) {
+ try {
+ Set<Map<String, Object>> configSet = (Set<Map<String, Object>>) configObj;
+ for (Map<String, Object> configMap : configSet) {
+ String type = (String) configMap.get(ConfigurationResourceProvider
+ .CONFIGURATION_CONFIG_TYPE_PROPERTY_ID);
+ String tag = (String) configMap.get(ConfigurationResourceProvider
+ .CONFIGURATION_CONFIG_TAG_PROPERTY_ID);
+
+ Map<String, String> configProperties = new HashMap<String, String>();
+
+ for (Map.Entry<String, Object> entry : configMap.entrySet()) {
+ String propertyCategory = PropertyHelper.getPropertyCategory(entry.getKey());
+ if (propertyCategory != null
+ && propertyCategory.equals("properties")
+ && null != entry.getValue()) {
+ configProperties.put(PropertyHelper.getPropertyName(entry.getKey()),
+ entry.getValue().toString());
+ }
+ }
+
+ Config config = new ConfigImpl(type);
+ config.setVersionTag(tag);
+ config.setProperties(configProperties);
+
+ configurations.put(config.getType(), config);
+ }
+ } catch (Exception e) {
+ LOG.warn("Config json in unparseable format. " + configObj, e);
+ }
+ }
+
+ request.setConfigs(configurations);
+ request.setHosts(hosts);
+
+ return request;
+ }
+
+ /**
+ * Bypassing predicate evaluation for the lack of a matcher for a
+ * non-scalar resource
+ *
+ * @param predicate the predicate
+ * @param resource the resource
+ *
+ * @return
+ */
+ @Override
+ public boolean evaluate(Predicate predicate, Resource resource) {
+ return true;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java
index f9f6564..c40ad68 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ConfigurationResourceProvider.java
@@ -43,15 +43,18 @@ import java.util.Map.Entry;
/**
* Resource provider for configuration resources.
*/
-class ConfigurationResourceProvider extends AbstractControllerResourceProvider {
+public class ConfigurationResourceProvider extends
+ AbstractControllerResourceProvider {
// ----- Property ID constants ---------------------------------------------
// Configurations (values are part of query strings and body post, so they don't have defined categories)
protected static final String CONFIGURATION_CLUSTER_NAME_PROPERTY_ID = PropertyHelper.getPropertyId("Config", "cluster_name");
// TODO : should these be Config/type and Config/tag to be consistent?
- protected static final String CONFIGURATION_CONFIG_TYPE_PROPERTY_ID = PropertyHelper.getPropertyId(null, "type");
- protected static final String CONFIGURATION_CONFIG_TAG_PROPERTY_ID = PropertyHelper.getPropertyId(null, "tag");
+ public static final String CONFIGURATION_CONFIG_TYPE_PROPERTY_ID =
+ PropertyHelper.getPropertyId(null, "type");
+ public static final String CONFIGURATION_CONFIG_TAG_PROPERTY_ID =
+ PropertyHelper.getPropertyId(null, "tag");
/**
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultResourcePredicateEvaluator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultResourcePredicateEvaluator.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultResourcePredicateEvaluator.java
new file mode 100644
index 0000000..9b843aa
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/DefaultResourcePredicateEvaluator.java
@@ -0,0 +1,32 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.spi.ResourcePredicateEvaluator;
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Resource;
+
+/**
+ * The default predicate evaluator.
+ */
+public class DefaultResourcePredicateEvaluator implements ResourcePredicateEvaluator {
+ @Override
+ public boolean evaluate(Predicate predicate, Resource resource) {
+ return predicate.evaluate(resource);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestStatusImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestStatusImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestStatusImpl.java
index 977538a..b0fde8a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestStatusImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RequestStatusImpl.java
@@ -22,6 +22,7 @@ import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.utilities.PropertyHelper;
import java.util.Collections;
+import java.util.HashSet;
import java.util.Set;
/**
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java
index e77ae76..d7c1e78 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ResourceImpl.java
@@ -41,6 +41,8 @@ public class ResourceImpl implements Resource {
private final Map<String, Map<String, Object>> propertiesMap = new TreeMap<String, Map<String, Object>>();
+ private volatile boolean skipPredicateCheck = false;
+
// ----- Constructors ------------------------------------------------------
/**
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/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 e45d59d..3389fca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/Resource.java
@@ -76,6 +76,7 @@ public interface Resource {
Component,
HostComponent,
Configuration,
+ ConfigGroup,
Action,
Request,
Task,
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ResourcePredicateEvaluator.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ResourcePredicateEvaluator.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ResourcePredicateEvaluator.java
new file mode 100644
index 0000000..425ef45
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/spi/ResourcePredicateEvaluator.java
@@ -0,0 +1,30 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.ambari.server.controller.spi;
+
+public interface ResourcePredicateEvaluator {
+ /**
+ * Evaluate the given predicate for the given resource.
+ *
+ * @param predicate the predicate
+ * @param resource the resource
+ *
+ * @return true if the predicate evaluates to true for the resource
+ */
+ public boolean evaluate(Predicate predicate, Resource resource);
+}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
index 3c9c509..6060edc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ClusterDAO.java
@@ -26,6 +26,7 @@ import javax.persistence.TypedQuery;
import com.google.inject.Singleton;
import org.apache.ambari.server.orm.entities.ClusterConfigEntity;
+import org.apache.ambari.server.orm.entities.ClusterConfigEntityPK;
import org.apache.ambari.server.orm.entities.ClusterEntity;
import com.google.inject.Inject;
@@ -86,6 +87,12 @@ public class ClusterDAO {
entityManagerProvider.get().persist(entity);
}
+ @Transactional
+ public ClusterConfigEntity findConfig(ClusterConfigEntityPK configEntityPK) {
+ return entityManagerProvider.get().find(ClusterConfigEntity.class,
+ configEntityPK);
+ }
+
/**
* Retrieve entity data from DB
* @param clusterEntity entity to refresh
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupConfigMappingDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupConfigMappingDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupConfigMappingDAO.java
index 1b91dec..15ae9ee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupConfigMappingDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupConfigMappingDAO.java
@@ -85,4 +85,14 @@ public class ConfigGroupConfigMappingDAO {
entityManagerProvider.get().remove(findByPK
(configGroupConfigMappingEntityPK));
}
+
+ @Transactional
+ public void removeAllByGroup(Long groupId) {
+ TypedQuery<Long> query = entityManagerProvider.get().createQuery
+ ("DELETE FROM ConfigGroupConfigMappingEntity configs WHERE configs" +
+ ".configGroupId = ?1", Long.class);
+
+ daoUtils.executeUpdate(query, groupId);
+ entityManagerProvider.get().flush();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
index cdcdaa9..9ca3fee 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/ConfigGroupHostMappingDAO.java
@@ -25,6 +25,7 @@ import org.apache.ambari.server.orm.entities.ConfigGroupHostMappingEntity;
import org.apache.ambari.server.orm.entities.ConfigGroupHostMappingEntityPK;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
+import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.util.List;
@@ -100,4 +101,14 @@ public class ConfigGroupHostMappingDAO {
entityManagerProvider.get().remove(findByPK
(configGroupHostMappingEntityPK));
}
+
+ @Transactional
+ public void removeAllByGroup(Long groupId) {
+ TypedQuery<Long> query = entityManagerProvider.get().createQuery
+ ("DELETE FROM ConfigGroupHostMappingEntity confighosts WHERE " +
+ "confighosts.configGroupId = ?1", Long.class);
+
+ daoUtils.executeUpdate(query, groupId);
+ entityManagerProvider.get().flush();
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
index 28ce1d4..0ea5614 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ClusterEntity.java
@@ -82,6 +82,9 @@ public class ClusterEntity {
@OneToMany(mappedBy = "clusterEntity", cascade = CascadeType.ALL)
private Collection<ClusterConfigMappingEntity> configMappingEntities;
+ @OneToMany(mappedBy = "clusterEntity", cascade = CascadeType.ALL)
+ private Collection<ConfigGroupEntity> configGroupEntities;
+
public Long getClusterId() {
return clusterId;
}
@@ -197,6 +200,12 @@ public class ClusterEntity {
public void setConfigMappingEntities(Collection<ClusterConfigMappingEntity> entities) {
configMappingEntities = entities;
}
-
+ public Collection<ConfigGroupEntity> getConfigGroupEntities() {
+ return configGroupEntities;
+ }
+
+ public void setConfigGroupEntities(Collection<ConfigGroupEntity> configGroupEntities) {
+ this.configGroupEntities = configGroupEntities;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/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 fc97032..93e4500 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
@@ -25,6 +25,7 @@ import java.util.concurrent.locks.ReadWriteLock;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.controller.ClusterResponse;
+import org.apache.ambari.server.state.configgroup.ConfigGroup;
public interface Cluster {
@@ -225,4 +226,33 @@ public interface Cluster {
* @return
*/
Map<String, Map<String, DesiredConfig>> getAllHostsDesiredConfigs();
+
+ /**
+ * Add a new config group to the set of Config groups associated with this
+ * cluster
+ * @param configGroup
+ * @throws AmbariException
+ */
+ public void addConfigGroup(ConfigGroup configGroup) throws AmbariException;
+
+ /**
+ * Get all config groups associated with this cluster
+ * @return
+ * @throws AmbariException
+ */
+ public Map<Long, ConfigGroup> getConfigGroups() throws AmbariException;
+
+ /**
+ * Delete ths config group identified by the config group id
+ * @param id
+ * @throws AmbariException
+ */
+ public void deleteConfigGroup(Long id) throws AmbariException;
+
+ /**
+ * Find all config groups associated with the give hostname
+ * @param hostname
+ * @return Map of config group id to config group
+ */
+ public Map<Long, ConfigGroup> getConfigGroupsByHostname(String hostname);
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
index 634f594..8cabaeb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/Clusters.java
@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.state.configgroup.ConfigGroup;
/**
* Single entity that tracks all clusters and hosts that are managed
@@ -173,4 +174,5 @@ public interface Clusters {
*/
public void deleteHost(String hostname)
throws AmbariException;
+
}
http://git-wip-us.apache.org/repos/asf/incubator-ambari/blob/aa8e98f4/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
index fe6dc0f..2766a60 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ConfigImpl.java
@@ -65,7 +65,14 @@ public class ConfigImpl implements Config {
this.entity = entity;
injector.injectMembers(this);
}
-
+
+ /**
+ * Constructor for clients not using factory.
+ */
+ public ConfigImpl(String type) {
+ this.type = type;
+ }
+
@Override
public String getType() {
return type;