You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by lp...@apache.org on 2017/07/14 12:55:00 UTC

[1/4] ambari git commit: AMBARI-21307 Rest resource for supporting ambari configurations

Repository: ambari
Updated Branches:
  refs/heads/feature-branch-AMBARI-21307 63186bf3e -> 9ad286791


AMBARI-21307 Rest resource for supporting ambari configurations


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/cc7fe2e4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/cc7fe2e4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/cc7fe2e4

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: cc7fe2e4e75adf93adc12582c90999ef7891c675
Parents: 63186bf
Author: lpuskas <lp...@apache.org>
Authored: Wed Jul 5 14:20:18 2017 +0200
Committer: lpuskas <lp...@apache.org>
Committed: Fri Jul 14 14:50:07 2017 +0200

----------------------------------------------------------------------
 .../resources/ResourceInstanceFactoryImpl.java  |   4 +
 .../services/AmbariConfigurationService.java    | 146 +++++++++++
 .../internal/AbstractProviderModule.java        |   2 +-
 .../AmbariConfigurationResourceProvider.java    | 247 +++++++++++++++++++
 .../internal/DefaultProviderModule.java         |  26 +-
 .../ambari/server/controller/spi/Resource.java  |   5 +-
 .../server/orm/dao/AmbariConfigurationDAO.java  |  92 +++++++
 .../orm/entities/AmbariConfigurationEntity.java |  70 ++++++
 .../orm/entities/ConfigurationBaseEntity.java   | 159 ++++++++++++
 .../authorization/RoleAuthorization.java        |  95 +++----
 .../resources/Ambari-DDL-Postgres-CREATE.sql    |  25 +-
 .../src/main/resources/META-INF/persistence.xml |   2 +
 12 files changed, 809 insertions(+), 64 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/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 96e288f..b4c57fc 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
@@ -471,6 +471,10 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
       case RemoteCluster:
         resourceDefinition = new RemoteClusterResourceDefinition();
         break;
+      case AmbariConfiguration:
+        resourceDefinition = new SimpleResourceDefinition(Resource.Type.AmbariConfiguration, "ambariconfiguration", "ambariconfigurations");
+
+        break;
 
       default:
         throw new IllegalArgumentException("Unsupported resource type: " + type);

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
new file mode 100644
index 0000000..0fa6e44
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed 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 java.util.Collections;
+
+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.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.http.HttpStatus;
+
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiImplicitParams;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+/**
+ * Rest endpoint for managing ambari configurations. Supports CRUD operations.
+ * Ambari configurations are resources that relate to the ambari server instance even before a cluster is provisioned.
+ *
+ * Ambari configuration resources may be shared with components and services in the cluster
+ * (by recommending them as default values)
+ *
+ * Eg. LDAP configuration is stored as ambariconfiguration.
+ * The request payload has the form:
+ *
+ * <pre>
+ *      {
+ *        "AmbariConfiguration": {
+ *            "type": "ldap-configuration",
+ *            "data": [
+ *                {
+ *                 "authentication.ldap.primaryUrl": "localhost:33389"
+ *                },
+ *                {
+ *                "authentication.ldap.secondaryUrl": "localhost:333"
+ *                 },
+ *                 {
+ *                 "authentication.ldap.baseDn": "dc=ambari,dc=apache,dc=org"
+ *                 }
+ *                 // ......
+ *             ]
+ *         }
+ *     }
+ * </pre>
+ */
+@Path("/configurations/")
+@Api(value = "/configurations", description = "Endpoint for Ambari configuration related operations")
+public class AmbariConfigurationService extends BaseService {
+
+  /**
+   * Creates an ambari configuration resource.
+   *
+   * @param body    the payload in json format
+   * @param headers http headers
+   * @param uri     request uri information
+   * @return
+   */
+  @POST
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Creates an ambari configuration resource")
+  @ApiImplicitParams({
+    @ApiImplicitParam(dataType = "", 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_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 createAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri) {
+    return handleRequest(headers, body, uri, Request.Type.POST, createResource(Resource.Type.AmbariConfiguration,
+      Collections.EMPTY_MAP));
+  }
+
+  @GET
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Retrieve ambari configuration resources")
+  public Response getAmbariConfigurations(String body, @Context HttpHeaders headers, @Context UriInfo uri) {
+    return handleRequest(headers, body, uri, Request.Type.GET, createResource(Resource.Type.AmbariConfiguration,
+      Collections.EMPTY_MAP));
+  }
+
+  @GET
+  @Path("{configurationId}")
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Retrieve ambari configuration resource")
+  public Response getAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri,
+                                         @PathParam("configurationId") String configurationId) {
+    return handleRequest(headers, body, uri, Request.Type.GET, createResource(Resource.Type.AmbariConfiguration,
+      Collections.singletonMap(Resource.Type.AmbariConfiguration, configurationId)));
+  }
+
+  @PUT
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Update ambari configuration resources")
+  public Response updateAmbariConfiguration() {
+    throw new UnsupportedOperationException("Not yet implemented");
+  }
+
+  @DELETE
+  @Path("{configurationId}")
+  @Produces(MediaType.TEXT_PLAIN)
+  @ApiOperation(value = "Deletes an ambari configuration resource")
+  @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 deleteAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri,
+                                            @PathParam("configurationId") String configurationId) {
+    return handleRequest(headers, body, uri, Request.Type.DELETE, createResource(Resource.Type.AmbariConfiguration,
+      Collections.singletonMap(Resource.Type.AmbariConfiguration, configurationId)));
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
index f3211bf..fc63594 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AbstractProviderModule.java
@@ -221,7 +221,7 @@ public abstract class AbstractProviderModule implements ProviderModule,
   private final Map<Resource.Type, List<PropertyProvider>> propertyProviders = new HashMap<>();
 
   @Inject
-  AmbariManagementController managementController;
+  protected AmbariManagementController managementController;
 
   @Inject
   TimelineMetricCacheProvider metricCacheProvider;

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
new file mode 100644
index 0000000..5e5af9e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
@@ -0,0 +1,247 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.StaticallyInject;
+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.PredicateHelper;
+import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.apache.ambari.server.orm.entities.ConfigurationBaseEntity;
+import org.apache.ambari.server.security.authorization.RoleAuthorization;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Resource provider for AmbariConfiguration resources.
+ */
+@StaticallyInject
+public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResourceProvider {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationResourceProvider.class);
+  private static final String DEFAULT_VERSION_TAG = "Default version";
+  private static final Integer DEFAULT_VERSION = 1;
+
+  /**
+   * Resource property id constants.
+   */
+  private enum ResourcePropertyId {
+
+    ID("AmbariConfiguration/id"),
+    TYPE("AmbariConfiguration/type"),
+    VERSION("AmbariConfiguration/version"),
+    VERSION_TAG("AmbariConfiguration/version_tag"),
+    DATA("AmbariConfiguration/data");
+
+    private String propertyId;
+
+    ResourcePropertyId(String propertyId) {
+      this.propertyId = propertyId;
+    }
+
+    String getPropertyId() {
+      return this.propertyId;
+    }
+
+    public static ResourcePropertyId fromString(String propertyIdStr) {
+      ResourcePropertyId propertyIdFromStr = null;
+
+      for (ResourcePropertyId id : ResourcePropertyId.values()) {
+        if (id.getPropertyId().equals(propertyIdStr)) {
+          propertyIdFromStr = id;
+          break;
+        }
+      }
+
+      if (propertyIdFromStr == null) {
+        throw new IllegalArgumentException("Unsupported property type: " + propertyIdStr);
+      }
+
+      return propertyIdFromStr;
+
+    }
+  }
+
+  private static Set<String> properties = Sets.newHashSet(
+    ResourcePropertyId.ID.getPropertyId(),
+    ResourcePropertyId.TYPE.getPropertyId(),
+    ResourcePropertyId.VERSION.getPropertyId(),
+    ResourcePropertyId.VERSION_TAG.getPropertyId(),
+    ResourcePropertyId.DATA.getPropertyId());
+
+  private static Map<Resource.Type, String> pkPropertyMap = Collections.unmodifiableMap(
+    new HashMap<Resource.Type, String>() {{
+      put(Resource.Type.AmbariConfiguration, ResourcePropertyId.ID.getPropertyId());
+    }}
+  );
+
+
+  @Inject
+  private static AmbariConfigurationDAO ambariConfigurationDAO;
+
+  private Gson gson;
+
+  protected AmbariConfigurationResourceProvider() {
+    super(properties, pkPropertyMap);
+    setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION));
+    setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION));
+
+    gson = new GsonBuilder().create();
+  }
+
+  @Override
+  protected Set<String> getPKPropertyIds() {
+    return Sets.newHashSet("AmbariConfiguration/id");
+  }
+
+  @Override
+  public RequestStatus createResourcesAuthorized(Request request) throws SystemException, UnsupportedPropertyException,
+    ResourceAlreadyExistsException, NoSuchParentResourceException {
+
+    LOGGER.info("Creating new ambari configuration resource ...");
+    AmbariConfigurationEntity ambariConfigurationEntity = getEntityFromRequest(request);
+
+    LOGGER.info("Persisting new ambari configuration: {} ", ambariConfigurationEntity);
+    ambariConfigurationDAO.persist(ambariConfigurationEntity);
+
+    return getRequestStatus(null);
+  }
+
+
+  @Override
+  protected Set<Resource> getResourcesAuthorized(Request request, Predicate predicate) throws SystemException,
+    UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    Set<Resource> resources = Sets.newHashSet();
+
+    List<AmbariConfigurationEntity> ambariConfigurationEntities = ambariConfigurationDAO.findAll();
+    for (AmbariConfigurationEntity ambariConfigurationEntity : ambariConfigurationEntities) {
+      try {
+        resources.add(toResource(ambariConfigurationEntity, getPropertyIds()));
+      } catch (AmbariException e) {
+        LOGGER.error("Error while retrieving ambari configuration", e);
+      }
+    }
+    return resources;
+  }
+
+  @Override
+  protected RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate) throws SystemException,
+    UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+
+    Long idFromRequest = Long.valueOf((String) PredicateHelper.getProperties(predicate).get(ResourcePropertyId.ID.getPropertyId()));
+
+    if (null == idFromRequest) {
+      LOGGER.debug("No resource id provided in the request");
+    } else {
+      LOGGER.debug("Deleting amari configuration with id: {}", idFromRequest);
+      try {
+        ambariConfigurationDAO.deleteById(idFromRequest);
+      } catch (IllegalStateException e) {
+        throw new NoSuchResourceException(e.getMessage());
+      }
+
+    }
+
+    return getRequestStatus(null);
+
+  }
+
+  private Resource toResource(AmbariConfigurationEntity entity, Set<String> requestedIds) throws AmbariException {
+    Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
+    Set<Map<String, String>> configurationSet = gson.fromJson(entity.getConfigurationBaseEntity().getConfigurationData(), Set.class);
+
+    setResourceProperty(resource, ResourcePropertyId.ID.getPropertyId(), entity.getId(), requestedIds);
+    setResourceProperty(resource, ResourcePropertyId.TYPE.getPropertyId(), entity.getConfigurationBaseEntity().getType(), requestedIds);
+    setResourceProperty(resource, ResourcePropertyId.DATA.getPropertyId(), configurationSet, requestedIds);
+
+    return resource;
+  }
+
+  private AmbariConfigurationEntity getEntityFromRequest(Request request) {
+
+    AmbariConfigurationEntity ambariConfigurationEntity = new AmbariConfigurationEntity();
+    ambariConfigurationEntity.setConfigurationBaseEntity(new ConfigurationBaseEntity());
+
+
+    for (ResourcePropertyId resourcePropertyId : ResourcePropertyId.values()) {
+      Object requestValue = getValueFromRequest(resourcePropertyId, request);
+
+      switch (resourcePropertyId) {
+        case DATA:
+          if (requestValue == null) {
+            throw new IllegalArgumentException("No configuration data is provided in the request");
+          }
+
+          ambariConfigurationEntity.getConfigurationBaseEntity().setConfigurationData(gson.toJson(requestValue));
+          break;
+        case TYPE:
+          ambariConfigurationEntity.getConfigurationBaseEntity().setType((String) requestValue);
+          break;
+
+        case VERSION:
+          Integer version = (requestValue == null) ? DEFAULT_VERSION : Integer.valueOf((Integer) requestValue);
+          ambariConfigurationEntity.getConfigurationBaseEntity().setVersion((version));
+          break;
+        case VERSION_TAG:
+          String versionTag = requestValue == null ? DEFAULT_VERSION_TAG : (String) requestValue;
+          ambariConfigurationEntity.getConfigurationBaseEntity().setVersionTag(versionTag);
+          break;
+        default:
+          LOGGER.debug("Ignored property in the request: {}", resourcePropertyId);
+          break;
+      }
+    }
+    ambariConfigurationEntity.getConfigurationBaseEntity().setCreateTimestamp(Calendar.getInstance().getTimeInMillis());
+    return ambariConfigurationEntity;
+
+  }
+
+  private Object getValueFromRequest(ResourcePropertyId resourcePropertyIdEnum, Request request) {
+    LOGGER.debug("Locating resource property [{}] in the request ...", resourcePropertyIdEnum);
+    Object requestValue = null;
+    for (Map<String, Object> propertyMap : request.getProperties()) {
+      if (propertyMap.containsKey(resourcePropertyIdEnum.getPropertyId())) {
+        requestValue = propertyMap.get(resourcePropertyIdEnum.getPropertyId());
+        LOGGER.debug("Found resource property {} in the request, value: {} ...", resourcePropertyIdEnum, requestValue);
+        break;
+      }
+    }
+    return requestValue;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/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 074f8e1..6e7ca0a 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
@@ -21,20 +21,18 @@ package org.apache.ambari.server.controller.internal;
 import java.util.Map;
 import java.util.Set;
 
-import org.apache.ambari.server.controller.AmbariManagementController;
-import org.apache.ambari.server.controller.AmbariServer;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 import org.apache.ambari.server.controller.utilities.PropertyHelper;
-
-import com.google.inject.Inject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * The default provider module implementation.
  */
 public class DefaultProviderModule extends AbstractProviderModule {
-  @Inject
-  private AmbariManagementController managementController;
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(DefaultProviderModule.class);
 
   // ----- Constructors ------------------------------------------------------
 
@@ -42,9 +40,7 @@ public class DefaultProviderModule extends AbstractProviderModule {
    * Create a default provider module.
    */
   public DefaultProviderModule() {
-    if (managementController == null) {
-      managementController = AmbariServer.getController();
-    }
+    super();
   }
 
 
@@ -52,8 +48,10 @@ public class DefaultProviderModule extends AbstractProviderModule {
 
   @Override
   protected ResourceProvider createResourceProvider(Resource.Type type) {
-    Set<String>               propertyIds    = PropertyHelper.getPropertyIds(type);
-    Map<Resource.Type,String> keyPropertyIds = PropertyHelper.getKeyPropertyIds(type);
+
+    LOGGER.debug("Creating resource provider for the type: {}", type);
+    Set<String> propertyIds = PropertyHelper.getPropertyIds(type);
+    Map<Resource.Type, String> keyPropertyIds = PropertyHelper.getKeyPropertyIds(type);
 
     switch (type.getInternalType()) {
       case Workflow:
@@ -124,10 +122,12 @@ public class DefaultProviderModule extends AbstractProviderModule {
         return new ArtifactResourceProvider(managementController);
       case RemoteCluster:
         return new RemoteClusterResourceProvider();
-
+      case AmbariConfiguration:
+        return new AmbariConfigurationResourceProvider();
       default:
+        LOGGER.debug("Delegating creation of resource provider for: {} to the AbstractControllerResourceProvider", type.getInternalType());
         return AbstractControllerResourceProvider.getResourceProvider(type, propertyIds,
-            keyPropertyIds, managementController);
+          keyPropertyIds, managementController);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/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 362b4e6..7835373 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
@@ -160,7 +160,8 @@ public interface Resource {
     VersionDefinition,
     ClusterKerberosDescriptor,
     LoggingQuery,
-    RemoteCluster;
+    RemoteCluster,
+    AmbariConfiguration;
 
     /**
      * Get the {@link Type} that corresponds to this InternalType.
@@ -282,6 +283,8 @@ public interface Resource {
     public static final Type ClusterKerberosDescriptor = InternalType.ClusterKerberosDescriptor.getType();
     public static final Type LoggingQuery = InternalType.LoggingQuery.getType();
     public static final Type RemoteCluster = InternalType.RemoteCluster.getType();
+    public static final Type AmbariConfiguration = InternalType.AmbariConfiguration.getType();
+
 
     /**
      * The type name.

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
new file mode 100644
index 0000000..dea37eb
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed 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.orm.dao;
+
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+import javax.persistence.EntityManager;
+import javax.persistence.TypedQuery;
+
+import org.apache.ambari.server.orm.RequiresSession;
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.persist.Transactional;
+
+/**
+ * DAO dealing with ambari configuration related JPA operations.
+ */
+
+@Singleton
+// todo extend CrudDao (amend crud dao to handle NPEs)
+public class AmbariConfigurationDAO {
+
+  private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationDAO.class);
+
+  @Inject
+  private Provider<EntityManager> entityManagerProvider;
+
+  /**
+   * DAO utilities for dealing mostly with {@link TypedQuery} results.
+   */
+  @Inject
+  private DaoUtils daoUtils;
+
+  public AmbariConfigurationEntity findByid(Long id) {
+    return entityManagerProvider.get().find(AmbariConfigurationEntity.class, id);
+  }
+
+  @RequiresSession
+  @Transactional
+  public void persist(AmbariConfigurationEntity entity) {
+    LOGGER.debug("Persisting ambari configuration: {}", entity);
+    entityManagerProvider.get().persist(entity);
+  }
+
+  @RequiresSession
+  public List<AmbariConfigurationEntity> findAll() {
+    TypedQuery<AmbariConfigurationEntity> query = entityManagerProvider.get().createNamedQuery(
+      "AmbariConfigurationEntity.findAll", AmbariConfigurationEntity.class);
+    return daoUtils.selectList(query);
+  }
+
+
+  @RequiresSession
+  @Transactional
+  public void deleteById(Long ambariConfigurationId) {
+
+    if (ambariConfigurationId == null) {
+      throw new IllegalArgumentException("No Ambari Configuration id provided.");
+    }
+
+    LOGGER.debug("Removing Ambari Configuration with id :{}", ambariConfigurationId);
+
+    AmbariConfigurationEntity ambariConfigurationEntity = findByid(ambariConfigurationId);
+    if (ambariConfigurationEntity == null) {
+      String msg = String.format("No Ambari Configuration found with id: %s", ambariConfigurationId);
+      LOGGER.debug(msg);
+      throw new IllegalStateException(msg);
+    }
+
+    entityManagerProvider.get().remove(ambariConfigurationEntity);
+    LOGGER.debug("Ambari Configuration with id: {}", ambariConfigurationId);
+  }
+
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java
new file mode 100644
index 0000000..34fa221
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AmbariConfigurationEntity.java
@@ -0,0 +1,70 @@
+/*
+ * Licensed 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.orm.entities;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.MapsId;
+import javax.persistence.NamedQueries;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToOne;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "ambari_configuration")
+@NamedQueries({
+  @NamedQuery(
+    name = "AmbariConfigurationEntity.findAll",
+    query = "select ace from AmbariConfigurationEntity ace")
+})
+
+public class AmbariConfigurationEntity {
+
+  @Id
+  @Column(name = "id")
+  private Long id;
+
+  @OneToOne(cascade = CascadeType.ALL)
+  @MapsId
+  @JoinColumn(name = "id")
+  private ConfigurationBaseEntity configurationBaseEntity;
+
+  public Long getId() {
+    return id;
+  }
+
+  public void setId(Long id) {
+    this.id = id;
+  }
+
+  public ConfigurationBaseEntity getConfigurationBaseEntity() {
+    return configurationBaseEntity;
+  }
+
+  public void setConfigurationBaseEntity(ConfigurationBaseEntity configurationBaseEntity) {
+    this.configurationBaseEntity = configurationBaseEntity;
+  }
+
+  @Override
+  public String toString() {
+    return "AmbariConfigurationEntity{" +
+      "id=" + id +
+      ", configurationBaseEntity=" + configurationBaseEntity +
+      '}';
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java
new file mode 100644
index 0000000..9ad30d7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/ConfigurationBaseEntity.java
@@ -0,0 +1,159 @@
+/*
+ * Licensed 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.orm.entities;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import javax.persistence.TableGenerator;
+
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+
+@Table(name = "configuration_base")
+@TableGenerator(
+  name = "configuration_id_generator",
+  table = "ambari_sequences",
+  pkColumnName = "sequence_name",
+  valueColumnName = "sequence_value",
+  pkColumnValue = "configuration_id_seq",
+  initialValue = 1
+)
+@Entity
+public class ConfigurationBaseEntity {
+
+  @Id
+  @Column(name = "id")
+  @GeneratedValue(strategy = GenerationType.TABLE, generator = "configuration_id_generator")
+  private Long id;
+
+  @Column(name = "version")
+  private Integer version;
+
+  @Column(name = "version_tag")
+  private String versionTag;
+
+  @Column(name = "type")
+  private String type;
+
+  @Column(name = "data")
+  private String configurationData;
+
+  @Column(name = "attributes")
+  private String configurationAttributes;
+
+  @Column(name = "create_timestamp")
+  private Long createTimestamp;
+
+  public Long getId() {
+    return id;
+  }
+
+  public Integer getVersion() {
+    return version;
+  }
+
+  public void setVersion(Integer version) {
+    this.version = version;
+  }
+
+  public String getVersionTag() {
+    return versionTag;
+  }
+
+  public void setVersionTag(String versionTag) {
+    this.versionTag = versionTag;
+  }
+
+  public String getType() {
+    return type;
+  }
+
+  public void setType(String type) {
+    this.type = type;
+  }
+
+  public String getConfigurationData() {
+    return configurationData;
+  }
+
+  public void setConfigurationData(String configurationData) {
+    this.configurationData = configurationData;
+  }
+
+  public String getConfigurationAttributes() {
+    return configurationAttributes;
+  }
+
+  public void setConfigurationAttributes(String configurationAttributes) {
+    this.configurationAttributes = configurationAttributes;
+  }
+
+  public Long getCreateTimestamp() {
+    return createTimestamp;
+  }
+
+  public void setCreateTimestamp(Long createTimestamp) {
+    this.createTimestamp = createTimestamp;
+  }
+
+  @Override
+  public String toString() {
+    return "ConfigurationBaseEntity{" +
+      "id=" + id +
+      ", version=" + version +
+      ", versionTag='" + versionTag + '\'' +
+      ", type='" + type + '\'' +
+      ", configurationData='" + configurationData + '\'' +
+      ", configurationAttributes='" + configurationAttributes + '\'' +
+      ", createTimestamp=" + createTimestamp +
+      '}';
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ConfigurationBaseEntity that = (ConfigurationBaseEntity) o;
+
+    return new EqualsBuilder()
+      .append(id, that.id)
+      .append(version, that.version)
+      .append(versionTag, that.versionTag)
+      .append(type, that.type)
+      .append(configurationData, that.configurationData)
+      .append(configurationAttributes, that.configurationAttributes)
+      .append(createTimestamp, that.createTimestamp)
+      .isEquals();
+  }
+
+  @Override
+  public int hashCode() {
+    return new HashCodeBuilder(17, 37)
+      .append(id)
+      .append(version)
+      .append(versionTag)
+      .append(type)
+      .append(configurationData)
+      .append(configurationAttributes)
+      .append(createTimestamp)
+      .toHashCode();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
index cd35c2c..3c50628 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/security/authorization/RoleAuthorization.java
@@ -39,6 +39,7 @@ public enum RoleAuthorization {
   AMBARI_MANAGE_VIEWS("AMBARI.MANAGE_VIEWS"),
   AMBARI_RENAME_CLUSTER("AMBARI.RENAME_CLUSTER"),
   AMBARI_RUN_CUSTOM_COMMAND("AMBARI.RUN_CUSTOM_COMMAND"),
+  AMBARI_MANAGE_CONFIGURATION("AMBARI.MANAGE_CONFIGURATION"),
   CLUSTER_MANAGE_CREDENTIALS("CLUSTER.MANAGE_CREDENTIALS"),
   CLUSTER_MODIFY_CONFIGS("CLUSTER.MODIFY_CONFIGS"),
   CLUSTER_MANAGE_CONFIG_GROUPS("CLUSTER.MANAGE_CONFIG_GROUPS"),
@@ -84,58 +85,58 @@ public enum RoleAuthorization {
   VIEW_USE("VIEW.USE");
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_VIEW_CLUSTER = EnumSet.of(
-      CLUSTER_VIEW_STATUS_INFO,
-      CLUSTER_VIEW_ALERTS,
-      CLUSTER_VIEW_CONFIGS,
-      CLUSTER_VIEW_METRICS,
-      CLUSTER_VIEW_STACK_DETAILS,
-      CLUSTER_MODIFY_CONFIGS,
-      CLUSTER_MANAGE_CONFIG_GROUPS,
-      CLUSTER_TOGGLE_ALERTS,
-      CLUSTER_TOGGLE_KERBEROS,
-      CLUSTER_UPGRADE_DOWNGRADE_STACK);
+    CLUSTER_VIEW_STATUS_INFO,
+    CLUSTER_VIEW_ALERTS,
+    CLUSTER_VIEW_CONFIGS,
+    CLUSTER_VIEW_METRICS,
+    CLUSTER_VIEW_STACK_DETAILS,
+    CLUSTER_MODIFY_CONFIGS,
+    CLUSTER_MANAGE_CONFIG_GROUPS,
+    CLUSTER_TOGGLE_ALERTS,
+    CLUSTER_TOGGLE_KERBEROS,
+    CLUSTER_UPGRADE_DOWNGRADE_STACK);
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_UPDATE_CLUSTER = EnumSet.of(
-      CLUSTER_TOGGLE_ALERTS,
-      CLUSTER_TOGGLE_KERBEROS,
-      CLUSTER_UPGRADE_DOWNGRADE_STACK,
-      CLUSTER_MODIFY_CONFIGS,
-      CLUSTER_MANAGE_AUTO_START,
-      SERVICE_MODIFY_CONFIGS);
+    CLUSTER_TOGGLE_ALERTS,
+    CLUSTER_TOGGLE_KERBEROS,
+    CLUSTER_UPGRADE_DOWNGRADE_STACK,
+    CLUSTER_MODIFY_CONFIGS,
+    CLUSTER_MANAGE_AUTO_START,
+    SERVICE_MODIFY_CONFIGS);
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_VIEW_SERVICE = EnumSet.of(
-      SERVICE_VIEW_ALERTS,
-      SERVICE_VIEW_CONFIGS,
-      SERVICE_VIEW_METRICS,
-      SERVICE_VIEW_STATUS_INFO,
-      SERVICE_COMPARE_CONFIGS,
-      SERVICE_ADD_DELETE_SERVICES,
-      SERVICE_DECOMMISSION_RECOMMISSION,
-      SERVICE_ENABLE_HA,
-      SERVICE_MANAGE_CONFIG_GROUPS,
-      SERVICE_MODIFY_CONFIGS,
-      SERVICE_START_STOP,
-      SERVICE_TOGGLE_MAINTENANCE,
-      SERVICE_TOGGLE_ALERTS,
-      SERVICE_MOVE,
-      SERVICE_RUN_CUSTOM_COMMAND,
-      SERVICE_RUN_SERVICE_CHECK);
+    SERVICE_VIEW_ALERTS,
+    SERVICE_VIEW_CONFIGS,
+    SERVICE_VIEW_METRICS,
+    SERVICE_VIEW_STATUS_INFO,
+    SERVICE_COMPARE_CONFIGS,
+    SERVICE_ADD_DELETE_SERVICES,
+    SERVICE_DECOMMISSION_RECOMMISSION,
+    SERVICE_ENABLE_HA,
+    SERVICE_MANAGE_CONFIG_GROUPS,
+    SERVICE_MODIFY_CONFIGS,
+    SERVICE_START_STOP,
+    SERVICE_TOGGLE_MAINTENANCE,
+    SERVICE_TOGGLE_ALERTS,
+    SERVICE_MOVE,
+    SERVICE_RUN_CUSTOM_COMMAND,
+    SERVICE_RUN_SERVICE_CHECK);
 
   public static final Set<RoleAuthorization> AUTHORIZATIONS_UPDATE_SERVICE = EnumSet.of(
-      SERVICE_ADD_DELETE_SERVICES,
-      SERVICE_DECOMMISSION_RECOMMISSION,
-      SERVICE_ENABLE_HA,
-      SERVICE_MANAGE_CONFIG_GROUPS,
-      SERVICE_MODIFY_CONFIGS,
-      SERVICE_START_STOP,
-      SERVICE_TOGGLE_MAINTENANCE,
-      SERVICE_TOGGLE_ALERTS,
-      SERVICE_MOVE,
-      SERVICE_RUN_CUSTOM_COMMAND,
-      SERVICE_RUN_SERVICE_CHECK,
-      SERVICE_MANAGE_ALERTS,
-      SERVICE_MANAGE_AUTO_START,
-      SERVICE_SET_SERVICE_USERS_GROUPS);
+    SERVICE_ADD_DELETE_SERVICES,
+    SERVICE_DECOMMISSION_RECOMMISSION,
+    SERVICE_ENABLE_HA,
+    SERVICE_MANAGE_CONFIG_GROUPS,
+    SERVICE_MODIFY_CONFIGS,
+    SERVICE_START_STOP,
+    SERVICE_TOGGLE_MAINTENANCE,
+    SERVICE_TOGGLE_ALERTS,
+    SERVICE_MOVE,
+    SERVICE_RUN_CUSTOM_COMMAND,
+    SERVICE_RUN_SERVICE_CHECK,
+    SERVICE_MANAGE_ALERTS,
+    SERVICE_MANAGE_AUTO_START,
+    SERVICE_SET_SERVICE_USERS_GROUPS);
 
   private final String id;
 
@@ -162,7 +163,7 @@ public enum RoleAuthorization {
   /**
    * Safely translates a role authorization Id to a RoleAuthorization
    *
-   * @param authenticationId  an authentication id
+   * @param authenticationId an authentication id
    * @return a RoleAuthorization or null if no translation can be made
    */
   public static RoleAuthorization translate(String authenticationId) {

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index 5899179..dffff86 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -62,8 +62,26 @@ CREATE TABLE clusters (
   desired_cluster_state VARCHAR(255) NOT NULL,
   desired_stack_id BIGINT NOT NULL,
   CONSTRAINT PK_clusters PRIMARY KEY (cluster_id),
-  CONSTRAINT FK_clusters_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack(stack_id),
-  CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource(resource_id));
+  CONSTRAINT FK_clusters_desired_stack_id FOREIGN KEY (desired_stack_id) REFERENCES stack (stack_id),
+  CONSTRAINT FK_clusters_resource_id FOREIGN KEY (resource_id) REFERENCES adminresource (resource_id)
+);
+
+CREATE TABLE configuration_base (
+  id               BIGINT       NOT NULL,
+  version_tag      VARCHAR(255) NOT NULL,
+  version          BIGINT       NOT NULL,
+  type             VARCHAR(255) NOT NULL,
+  data             TEXT         NOT NULL,
+  attributes       TEXT,
+  create_timestamp BIGINT       NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_configuration_configuration_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
 
 CREATE TABLE clusterconfig (
   config_id BIGINT NOT NULL,
@@ -1089,6 +1107,7 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value) VALUES
   ('remote_cluster_id_seq', 0),
   ('remote_cluster_service_id_seq', 0),
   ('servicecomponent_version_id_seq', 0),
+  ('configuration_id_seq', 0),
   ('hostcomponentdesiredstate_id_seq', 0);
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES
@@ -1173,6 +1192,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage administrative settings' UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1378,6 +1398,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/cc7fe2e4/ambari-server/src/main/resources/META-INF/persistence.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/META-INF/persistence.xml b/ambari-server/src/main/resources/META-INF/persistence.xml
index e4045ef..0f8e964 100644
--- a/ambari-server/src/main/resources/META-INF/persistence.xml
+++ b/ambari-server/src/main/resources/META-INF/persistence.xml
@@ -96,6 +96,8 @@
     <class>org.apache.ambari.server.orm.entities.KerberosDescriptorEntity</class>
     <class>org.apache.ambari.server.orm.entities.RemoteAmbariClusterEntity</class>
     <class>org.apache.ambari.server.orm.entities.RemoteAmbariClusterServiceEntity</class>
+    <class>org.apache.ambari.server.orm.entities.ConfigurationBaseEntity</class>
+    <class>org.apache.ambari.server.orm.entities.AmbariConfigurationEntity</class>
 
     <properties>
       <property name="eclipselink.cache.size.default" value="10000" />


[3/4] ambari git commit: AMBARI-21307 Implemented PUT operation, added unit tests

Posted by lp...@apache.org.
AMBARI-21307 Implemented PUT operation, added unit tests


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9ad28679
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9ad28679
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9ad28679

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 9ad2867911f894db369ce498b71c1582b7605906
Parents: 86cff07
Author: lpuskas <lp...@apache.org>
Authored: Thu Jul 13 16:20:58 2017 +0200
Committer: lpuskas <lp...@apache.org>
Committed: Fri Jul 14 14:50:08 2017 +0200

----------------------------------------------------------------------
 .../services/AmbariConfigurationService.java    |  89 ++++---
 .../server/controller/ControllerModule.java     |   2 +
 .../controller/ResourceProviderFactory.java     |  23 +-
 .../AbstractControllerResourceProvider.java     |   2 +
 .../AmbariConfigurationResourceProvider.java    |  88 +++++--
 .../internal/DefaultProviderModule.java         |   2 -
 .../server/orm/dao/AmbariConfigurationDAO.java  |   4 +
 ...AmbariConfigurationResourceProviderTest.java | 231 +++++++++++++++++++
 8 files changed, 363 insertions(+), 78 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
index 0c159b9..0632361 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
@@ -56,16 +56,10 @@ import io.swagger.annotations.ApiResponses;
  *            "data": [
  *                {
  *                 "authentication.ldap.primaryUrl": "localhost:33389"
- *                },
- *                {
- *                "authentication.ldap.secondaryUrl": "localhost:333"
- *                 },
- *                 {
+                   "authentication.ldap.secondaryUrl": "localhost:333"
  *                 "authentication.ldap.baseDn": "dc=ambari,dc=apache,dc=org"
- *                 }
- *                 // ......
- *             ]
- *         }
+  *                 // ......
+ *         ]
  *     }
  * </pre>
  */
@@ -74,7 +68,7 @@ import io.swagger.annotations.ApiResponses;
 public class AmbariConfigurationService extends BaseService {
 
   private static final String AMBARI_CONFIGURATION_REQUEST_TYPE =
-      "org.apache.ambari.server.api.services.AmbariConfigurationRequestSwagger";
+    "org.apache.ambari.server.api.services.AmbariConfigurationRequestSwagger";
 
   /**
    * Creates an ambari configuration resource.
@@ -87,9 +81,9 @@ public class AmbariConfigurationService extends BaseService {
   @POST
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Creates an ambari configuration resource",
-      nickname = "AmbariConfigurationService#createAmbariConfiguration")
+    nickname = "AmbariConfigurationService#createAmbariConfiguration")
   @ApiImplicitParams({
-      @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+    @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
   })
   @ApiResponses({
     @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
@@ -108,24 +102,24 @@ public class AmbariConfigurationService extends BaseService {
   @GET
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Retrieve all ambari configuration resources",
-      nickname = "AmbariConfigurationService#getAmbariConfigurations",
-      notes = "Returns all Ambari configurations.",
-      response = AmbariConfigurationResponseSwagger.class,
-      responseContainer = RESPONSE_CONTAINER_LIST)
+    nickname = "AmbariConfigurationService#getAmbariConfigurations",
+    notes = "Returns all Ambari configurations.",
+    response = AmbariConfigurationResponseSwagger.class,
+    responseContainer = RESPONSE_CONTAINER_LIST)
   @ApiImplicitParams({
-      @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION,
-          defaultValue = "AmbariConfiguration/data, AmbariConfiguration/id, AmbariConfiguration/type",
-          dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
-      @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION,
-          defaultValue = "AmbariConfiguration/id",
-          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)
+    @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION,
+      defaultValue = "AmbariConfiguration/data, AmbariConfiguration/id, AmbariConfiguration/type",
+      dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
+    @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION,
+      defaultValue = "AmbariConfiguration/id",
+      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)
+    @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
+    @ApiResponse(code = HttpStatus.SC_INTERNAL_SERVER_ERROR, message = MSG_SERVER_ERROR)
   })
   public Response getAmbariConfigurations(String body, @Context HttpHeaders headers, @Context UriInfo uri) {
     return handleRequest(headers, body, uri, Request.Type.GET, createResource(Resource.Type.AmbariConfiguration,
@@ -136,16 +130,16 @@ public class AmbariConfigurationService extends BaseService {
   @Path("{configurationId}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Retrieve the details of an ambari configuration resource",
-      nickname = "AmbariConfigurationService#getAmbariConfiguration",
-      response = AmbariConfigurationResponseSwagger.class)
+    nickname = "AmbariConfigurationService#getAmbariConfiguration",
+    response = AmbariConfigurationResponseSwagger.class)
   @ApiImplicitParams({
-      @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*",
-          dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY)
+    @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*",
+      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)
+    @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 getAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri,
                                          @PathParam("configurationId") String configurationId) {
@@ -154,30 +148,35 @@ public class AmbariConfigurationService extends BaseService {
   }
 
   @PUT
+  @Path("{configurationId}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Updates ambari configuration resources - Not implemented yet",
     nickname = "AmbariConfigurationService#updateAmbariConfiguration")
   @ApiImplicitParams({
-      @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+    @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY),
+    @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*",
+      dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY)
   })
   @ApiResponses({
-      @ApiResponse(code = HttpStatus.SC_OK, 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_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),
+    @ApiResponse(code = HttpStatus.SC_OK, 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_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 updateAmbariConfiguration() {
-    throw new UnsupportedOperationException("Not yet implemented");
+  public Response updateAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri,
+                                            @PathParam("configurationId") String configurationId) {
+    return handleRequest(headers, body, uri, Request.Type.PUT, createResource(Resource.Type.AmbariConfiguration,
+      Collections.singletonMap(Resource.Type.AmbariConfiguration, configurationId)));
   }
 
   @DELETE
   @Path("{configurationId}")
   @Produces(MediaType.TEXT_PLAIN)
   @ApiOperation(value = "Deletes an ambari configuration resource",
-      nickname = "AmbariConfigurationService#deleteAmbariConfiguration")
+    nickname = "AmbariConfigurationService#deleteAmbariConfiguration")
   @ApiResponses({
     @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
     @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/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 f3c2ec8..7a248f3 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
@@ -62,6 +62,7 @@ import org.apache.ambari.server.cleanup.ClasspathScannerUtils;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.configuration.Configuration.ConnectionPoolType;
 import org.apache.ambari.server.configuration.Configuration.DatabaseType;
+import org.apache.ambari.server.controller.internal.AmbariConfigurationResourceProvider;
 import org.apache.ambari.server.controller.internal.ComponentResourceProvider;
 import org.apache.ambari.server.controller.internal.CredentialResourceProvider;
 import org.apache.ambari.server.controller.internal.HostComponentResourceProvider;
@@ -467,6 +468,7 @@ public class ControllerModule extends AbstractModule {
         .implement(ResourceProvider.class, Names.named("credential"), CredentialResourceProvider.class)
         .implement(ResourceProvider.class, Names.named("kerberosDescriptor"), KerberosDescriptorResourceProvider.class)
         .implement(ResourceProvider.class, Names.named("upgrade"), UpgradeResourceProvider.class)
+        .implement(ResourceProvider.class, Names.named("ambariConfiguration"), AmbariConfigurationResourceProvider.class)
         .build(ResourceProviderFactory.class));
 
     install(new FactoryModuleBuilder().implement(

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/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 3912138..36dfdf9 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
@@ -22,23 +22,22 @@ package org.apache.ambari.server.controller;
 import java.util.Map;
 import java.util.Set;
 
+import javax.inject.Named;
+
 import org.apache.ambari.server.controller.internal.UpgradeResourceProvider;
 import org.apache.ambari.server.controller.spi.Resource;
 import org.apache.ambari.server.controller.spi.Resource.Type;
 import org.apache.ambari.server.controller.spi.ResourceProvider;
 
-import com.google.inject.name.Named;
 
 public interface ResourceProviderFactory {
   @Named("host")
-  ResourceProvider getHostResourceProvider(Set<String> propertyIds,
-      Map<Type, String> keyPropertyIds,
-      AmbariManagementController managementController);
+  ResourceProvider getHostResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds,
+                                           AmbariManagementController managementController);
 
   @Named("hostComponent")
-  ResourceProvider getHostComponentResourceProvider(Set<String> propertyIds,
-      Map<Type, String> keyPropertyIds,
-      AmbariManagementController managementController);
+  ResourceProvider getHostComponentResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds,
+                                                    AmbariManagementController managementController);
 
   @Named("service")
   ResourceProvider getServiceResourceProvider(AmbariManagementController managementController);
@@ -47,9 +46,8 @@ public interface ResourceProviderFactory {
   ResourceProvider getComponentResourceProvider(AmbariManagementController managementController);
 
   @Named("member")
-  ResourceProvider getMemberResourceProvider(Set<String> propertyIds,
-      Map<Type, String> keyPropertyIds,
-      AmbariManagementController managementController);
+  ResourceProvider getMemberResourceProvider(Set<String> propertyIds, Map<Type, String> keyPropertyIds,
+                                             AmbariManagementController managementController);
 
   @Named("hostKerberosIdentity")
   ResourceProvider getHostKerberosIdentityResourceProvider(AmbariManagementController managementController);
@@ -61,11 +59,12 @@ public interface ResourceProviderFactory {
   ResourceProvider getRepositoryVersionResourceProvider();
 
   @Named("kerberosDescriptor")
-  ResourceProvider getKerberosDescriptorResourceProvider(AmbariManagementController managementController,
-                                                         Set<String> propertyIds,
+  ResourceProvider getKerberosDescriptorResourceProvider(AmbariManagementController managementController, Set<String> propertyIds,
                                                          Map<Resource.Type, String> keyPropertyIds);
 
   @Named("upgrade")
   UpgradeResourceProvider getUpgradeResourceProvider(AmbariManagementController managementController);
 
+  @Named("ambariConfiguration")
+  ResourceProvider getAmbariConfigurationResourceProvider();
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/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 b35b2a8..95d33cf 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
@@ -254,6 +254,8 @@ public abstract class AbstractControllerResourceProvider extends AbstractAuthori
         return new ClusterKerberosDescriptorResourceProvider(managementController);
       case LoggingQuery:
         return new LoggingResourceProvider(propertyIds, keyPropertyIds, managementController);
+      case AmbariConfiguration:
+        return resourceProviderFactory.getAmbariConfigurationResourceProvider();
       default:
         throw new IllegalArgumentException("Unknown type " + type);
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
index e8f186d..2302d8b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
@@ -25,7 +25,6 @@ import java.util.Set;
 import javax.inject.Inject;
 
 import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.StaticallyInject;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
@@ -46,11 +45,11 @@ import org.slf4j.LoggerFactory;
 import com.google.common.collect.Sets;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
+import com.google.inject.assistedinject.AssistedInject;
 
 /**
  * Resource provider for AmbariConfiguration resources.
  */
-@StaticallyInject
 public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResourceProvider {
 
   private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationResourceProvider.class);
@@ -60,7 +59,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
   /**
    * Resource property id constants.
    */
-  private enum ResourcePropertyId {
+  public enum ResourcePropertyId {
 
     ID("AmbariConfiguration/id"),
     TYPE("AmbariConfiguration/type"),
@@ -112,11 +111,12 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
 
 
   @Inject
-  private static AmbariConfigurationDAO ambariConfigurationDAO;
+  private AmbariConfigurationDAO ambariConfigurationDAO;
 
   private Gson gson;
 
-  protected AmbariConfigurationResourceProvider() {
+  @AssistedInject
+  public AmbariConfigurationResourceProvider() {
     super(PROPERTIES, PK_PROPERTY_MAP);
     setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION));
     setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION));
@@ -134,7 +134,12 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
     ResourceAlreadyExistsException, NoSuchParentResourceException {
 
     LOGGER.info("Creating new ambari configuration resource ...");
-    AmbariConfigurationEntity ambariConfigurationEntity = getEntityFromRequest(request);
+    AmbariConfigurationEntity ambariConfigurationEntity = null;
+    try {
+      ambariConfigurationEntity = getEntityFromRequest(request);
+    } catch (AmbariException e) {
+      throw new NoSuchParentResourceException(e.getMessage());
+    }
 
     LOGGER.info("Persisting new ambari configuration: {} ", ambariConfigurationEntity);
     ambariConfigurationDAO.create(ambariConfigurationEntity);
@@ -148,6 +153,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
     UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
     Set<Resource> resources = Sets.newHashSet();
 
+    // retrieves allconfigurations, filtering is done at a higher level
     List<AmbariConfigurationEntity> ambariConfigurationEntities = ambariConfigurationDAO.findAll();
     for (AmbariConfigurationEntity ambariConfigurationEntity : ambariConfigurationEntities) {
       try {
@@ -181,40 +187,86 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
 
   }
 
+  @Override
+  protected RequestStatus updateResourcesAuthorized(Request request, Predicate predicate) throws SystemException,
+    UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
+    Long idFromRequest = Long.valueOf((String) PredicateHelper.getProperties(predicate).get(ResourcePropertyId.ID.getPropertyId()));
+
+    AmbariConfigurationEntity persistedEntity = ambariConfigurationDAO.findByPK(idFromRequest);
+    if (persistedEntity == null) {
+      String errorMsg = String.format("Entity with primary key [ %s ] not found in the database.", idFromRequest);
+      LOGGER.error(errorMsg);
+      throw new NoSuchResourceException(errorMsg);
+    }
+
+    try {
+
+      AmbariConfigurationEntity entityFromRequest = getEntityFromRequest(request);
+      persistedEntity.getConfigurationBaseEntity().setVersionTag(entityFromRequest.getConfigurationBaseEntity().getVersionTag());
+      persistedEntity.getConfigurationBaseEntity().setVersion(entityFromRequest.getConfigurationBaseEntity().getVersion());
+      persistedEntity.getConfigurationBaseEntity().setType(entityFromRequest.getConfigurationBaseEntity().getType());
+      persistedEntity.getConfigurationBaseEntity().setConfigurationData(entityFromRequest.getConfigurationBaseEntity().getConfigurationData());
+      persistedEntity.getConfigurationBaseEntity().setConfigurationAttributes(entityFromRequest.getConfigurationBaseEntity().getConfigurationAttributes());
+
+
+      ambariConfigurationDAO.create(persistedEntity);
+    } catch (AmbariException e) {
+      throw new NoSuchParentResourceException(e.getMessage());
+    }
+
+    return getRequestStatus(null);
+
+  }
+
   private Resource toResource(AmbariConfigurationEntity entity, Set<String> requestedIds) throws AmbariException {
+
+    if (null == entity) {
+      throw new IllegalArgumentException("Null entity can't be transformed into a resource");
+    }
+
+    if (null == entity.getConfigurationBaseEntity()) {
+      throw new IllegalArgumentException("Invalid configuration entity can't be transformed into a resource");
+    }
     Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
     Set<Map<String, String>> configurationSet = gson.fromJson(entity.getConfigurationBaseEntity().getConfigurationData(), Set.class);
 
     setResourceProperty(resource, ResourcePropertyId.ID.getPropertyId(), entity.getId(), requestedIds);
     setResourceProperty(resource, ResourcePropertyId.TYPE.getPropertyId(), entity.getConfigurationBaseEntity().getType(), requestedIds);
     setResourceProperty(resource, ResourcePropertyId.DATA.getPropertyId(), configurationSet, requestedIds);
+    setResourceProperty(resource, ResourcePropertyId.VERSION.getPropertyId(), entity.getConfigurationBaseEntity().getVersion(), requestedIds);
+    setResourceProperty(resource, ResourcePropertyId.VERSION_TAG.getPropertyId(), entity.getConfigurationBaseEntity().getVersionTag(), requestedIds);
 
     return resource;
   }
 
-  private AmbariConfigurationEntity getEntityFromRequest(Request request) {
+  private AmbariConfigurationEntity getEntityFromRequest(Request request) throws AmbariException {
 
     AmbariConfigurationEntity ambariConfigurationEntity = new AmbariConfigurationEntity();
     ambariConfigurationEntity.setConfigurationBaseEntity(new ConfigurationBaseEntity());
 
+    // set of resource properties (eache entry in the set belongs to a different resource)
+    Set<Map<String, Object>> resourcePropertiesSet = request.getProperties();
+
+    if (resourcePropertiesSet.size() != 1) {
+      throw new AmbariException("There must be only one resource specified in the request");
+    }
+
 
     for (ResourcePropertyId resourcePropertyId : ResourcePropertyId.values()) {
-      Object requestValue = getValueFromRequest(resourcePropertyId, request);
+      Object requestValue = getValueFromResourceProperties(resourcePropertyId, resourcePropertiesSet.iterator().next());
 
       switch (resourcePropertyId) {
         case DATA:
           if (requestValue == null) {
             throw new IllegalArgumentException("No configuration data is provided in the request");
           }
-
           ambariConfigurationEntity.getConfigurationBaseEntity().setConfigurationData(gson.toJson(requestValue));
           break;
         case TYPE:
           ambariConfigurationEntity.getConfigurationBaseEntity().setType((String) requestValue);
           break;
-
         case VERSION:
-          Integer version = (requestValue == null) ? DEFAULT_VERSION : Integer.valueOf((Integer) requestValue);
+          Integer version = (requestValue == null) ? DEFAULT_VERSION : Integer.valueOf((String) requestValue);
           ambariConfigurationEntity.getConfigurationBaseEntity().setVersion((version));
           break;
         case VERSION_TAG:
@@ -231,15 +283,13 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
 
   }
 
-  private Object getValueFromRequest(ResourcePropertyId resourcePropertyIdEnum, Request request) {
-    LOGGER.debug("Locating resource property [{}] in the request ...", resourcePropertyIdEnum);
+  private Object getValueFromResourceProperties(ResourcePropertyId resourcePropertyIdEnum, Map<String, Object> resourceProperties) {
+    LOGGER.debug("Locating resource property [{}] in the resource properties map ...", resourcePropertyIdEnum);
     Object requestValue = null;
-    for (Map<String, Object> propertyMap : request.getProperties()) {
-      if (propertyMap.containsKey(resourcePropertyIdEnum.getPropertyId())) {
-        requestValue = propertyMap.get(resourcePropertyIdEnum.getPropertyId());
-        LOGGER.debug("Found resource property {} in the request, value: {} ...", resourcePropertyIdEnum, requestValue);
-        break;
-      }
+
+    if (resourceProperties.containsKey(resourcePropertyIdEnum.getPropertyId())) {
+      requestValue = resourceProperties.get(resourcePropertyIdEnum.getPropertyId());
+      LOGGER.debug("Found resource property {} in the resource properties map, value: {}", resourcePropertyIdEnum, requestValue);
     }
     return requestValue;
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/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 6e7ca0a..95c7b83 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
@@ -122,8 +122,6 @@ public class DefaultProviderModule extends AbstractProviderModule {
         return new ArtifactResourceProvider(managementController);
       case RemoteCluster:
         return new RemoteClusterResourceProvider();
-      case AmbariConfiguration:
-        return new AmbariConfigurationResourceProvider();
       default:
         LOGGER.debug("Delegating creation of resource provider for: {} to the AbstractControllerResourceProvider", type.getInternalType());
         return AbstractControllerResourceProvider.getResourceProvider(type, propertyIds,

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
index c29a423..5710a7f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
@@ -19,8 +19,11 @@ import javax.inject.Singleton;
 
 import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
 
+import com.google.inject.persist.Transactional;
+
 /**
  * DAO dealing with ambari configuration related JPA operations.
+ * Operations delegate to the JPA provider implementation of CRUD operations.
  */
 
 @Singleton
@@ -31,6 +34,7 @@ public class AmbariConfigurationDAO extends CrudDAO<AmbariConfigurationEntity, L
     super(AmbariConfigurationEntity.class);
   }
 
+  @Transactional
   public void create(AmbariConfigurationEntity entity) {
     super.create(entity);
   }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9ad28679/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java
new file mode 100644
index 0000000..d974682
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProviderTest.java
@@ -0,0 +1,231 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.controller.spi.Predicate;
+import org.apache.ambari.server.controller.spi.Request;
+import org.apache.ambari.server.controller.spi.Resource;
+import org.apache.ambari.server.controller.utilities.PredicateBuilder;
+import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.apache.ambari.server.orm.entities.ConfigurationBaseEntity;
+import org.easymock.Capture;
+import org.easymock.EasyMock;
+import org.easymock.EasyMockRule;
+import org.easymock.EasyMockSupport;
+import org.easymock.Mock;
+import org.easymock.TestSubject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class AmbariConfigurationResourceProviderTest extends EasyMockSupport {
+
+  @Rule
+  public EasyMockRule mocks = new EasyMockRule(this);
+
+  @Mock
+  private Request requestMock;
+
+  @Mock
+  private AmbariConfigurationDAO ambariConfigurationDAO;
+
+  private Capture<AmbariConfigurationEntity> ambariConfigurationEntityCapture;
+
+  private Gson gson;
+
+  private static final String DATA_MOCK_STR = "[\n" +
+    "      {\n" +
+    "        \"authentication.ldap.baseDn\" : \"dc=ambari,dc=apache,dc=org\",\n" +
+    "        \"authentication.ldap.primaryUrl\" : \"localhost:33389\",\n" +
+    "        \"authentication.ldap.secondaryUrl\" : \"localhost:333\"\n" +
+    "      }\n" +
+    "    ]";
+
+  private static final Long PK_LONG = Long.valueOf(1);
+  private static final String PK_STRING = String.valueOf(1);
+  private static final String VERSION_TAG = "test version";
+  private static final String VERSION = "1";
+
+  @TestSubject
+  private AmbariConfigurationResourceProvider ambariConfigurationResourceProvider = new AmbariConfigurationResourceProvider();
+
+  @Before
+  public void setup() {
+    ambariConfigurationEntityCapture = Capture.newInstance();
+    gson = new GsonBuilder().create();
+  }
+
+  @Test
+  public void testCreateAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception {
+
+    // GIVEN
+    // configuration properties parsed from the request
+    Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet(
+      new PropertiesMapBuilder()
+        .withId(PK_LONG)
+        .withVersion(VERSION)
+        .withVersionTag(VERSION_TAG)
+        .withData(DATA_MOCK_STR)
+        .build());
+
+    // mock the request to return the properties
+    EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet);
+
+    // capture the entity the DAO gets called with
+    ambariConfigurationDAO.create(EasyMock.capture(ambariConfigurationEntityCapture));
+    replayAll();
+
+    // WHEN
+    ambariConfigurationResourceProvider.createResourcesAuthorized(requestMock);
+
+    // THEN
+    AmbariConfigurationEntity capturedAmbariConfigurationEntity = ambariConfigurationEntityCapture.getValue();
+    Assert.assertNotNull(capturedAmbariConfigurationEntity);
+    Assert.assertNull("The entity identifier should be null", capturedAmbariConfigurationEntity.getId());
+    Assert.assertEquals("The entity version is not the expected", Integer.valueOf(VERSION),
+      capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersion());
+    Assert.assertEquals("The entity version tag is not the expected", VERSION_TAG,
+      capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getVersionTag());
+    Assert.assertEquals("The entity data is not the expected", DATA_MOCK_STR,
+      gson.fromJson(capturedAmbariConfigurationEntity.getConfigurationBaseEntity().getConfigurationData(), String.class));
+  }
+
+  @Test
+  public void testRemoveAmbariConfigurationRequestResultsInTheProperPersistenceCall() throws Exception {
+    // GIVEN
+    Predicate predicate = new PredicateBuilder().property(
+      AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate();
+
+    Capture<Long> pkCapture = Capture.newInstance();
+    ambariConfigurationDAO.removeByPK(EasyMock.capture(pkCapture));
+    replayAll();
+
+    // WHEN
+    ambariConfigurationResourceProvider.deleteResourcesAuthorized(requestMock, predicate);
+
+    // THEN
+    Assert.assertEquals("The pk of the entity to be removed doen't match the expected id", Long.valueOf(1), pkCapture.getValue());
+  }
+
+
+  @Test
+  public void testRetrieveAmbariConfigurationShouldResultsInTheProperDAOCall() throws Exception {
+    // GIVEN
+    Predicate predicate = new PredicateBuilder().property(
+      AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate();
+
+    EasyMock.expect(ambariConfigurationDAO.findAll()).andReturn(Lists.newArrayList(createDummyAmbariConfigurationEntity()));
+    replayAll();
+
+    // WHEN
+    Set<Resource> resourceSet = ambariConfigurationResourceProvider.getResourcesAuthorized(requestMock, predicate);
+
+    // THEN
+    Assert.assertNotNull(resourceSet);
+    Assert.assertFalse(resourceSet.isEmpty());
+  }
+
+  @Test
+  public void testUpdateAmbariConfigurationShouldResultInTheProperDAOCalls() throws Exception {
+    // GIVEN
+
+    Predicate predicate = new PredicateBuilder().property(
+      AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId()).equals("1").toPredicate();
+
+    // properteies in the request, representing the updated configuration
+    Set<Map<String, Object>> resourcePropertiesSet = Sets.newHashSet(new PropertiesMapBuilder()
+      .withId(PK_LONG)
+      .withVersion("2")
+      .withVersionTag("version-2")
+      .withData(DATA_MOCK_STR).build());
+
+    EasyMock.expect(requestMock.getProperties()).andReturn(resourcePropertiesSet);
+
+    AmbariConfigurationEntity persistedEntity = createDummyAmbariConfigurationEntity();
+    EasyMock.expect(ambariConfigurationDAO.findByPK(PK_LONG)).andReturn(persistedEntity);
+    ambariConfigurationDAO.create(EasyMock.capture(ambariConfigurationEntityCapture));
+
+    replayAll();
+
+    // WHEN
+    ambariConfigurationResourceProvider.updateResourcesAuthorized(requestMock, predicate);
+
+    // the captured entity should be the updated one
+    AmbariConfigurationEntity updatedEntity = ambariConfigurationEntityCapture.getValue();
+
+    // THEN
+    Assert.assertNotNull(updatedEntity);
+    Assert.assertEquals("The updated version is wrong", Integer.valueOf(2), updatedEntity.getConfigurationBaseEntity().getVersion());
+  }
+
+  private class PropertiesMapBuilder {
+
+    private Map<String, Object> resourcePropertiesMap = Maps.newHashMap();
+
+    private PropertiesMapBuilder() {
+    }
+
+    public PropertiesMapBuilder withId(Long id) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.ID.getPropertyId(), id);
+      return this;
+    }
+
+    private PropertiesMapBuilder withVersion(String version) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION.getPropertyId(), version);
+      return this;
+    }
+
+    private PropertiesMapBuilder withVersionTag(String versionTag) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.VERSION_TAG.getPropertyId(), versionTag);
+      return this;
+    }
+
+    private PropertiesMapBuilder withData(String dataJson) {
+      resourcePropertiesMap.put(AmbariConfigurationResourceProvider.ResourcePropertyId.DATA.getPropertyId(), dataJson);
+      return this;
+    }
+
+    public Map<String, Object> build() {
+      return this.resourcePropertiesMap;
+    }
+
+  }
+
+  private AmbariConfigurationEntity createDummyAmbariConfigurationEntity() {
+    AmbariConfigurationEntity acEntity = new AmbariConfigurationEntity();
+    ConfigurationBaseEntity configurationBaseEntity = new ConfigurationBaseEntity();
+    acEntity.setConfigurationBaseEntity(configurationBaseEntity);
+    acEntity.setId(PK_LONG);
+    acEntity.getConfigurationBaseEntity().setConfigurationData(DATA_MOCK_STR);
+    acEntity.getConfigurationBaseEntity().setVersion(Integer.valueOf(VERSION));
+    acEntity.getConfigurationBaseEntity().setVersionTag(VERSION_TAG);
+    acEntity.getConfigurationBaseEntity().setType("ldap-config");
+
+    return acEntity;
+  }
+
+
+}
\ No newline at end of file


[2/4] ambari git commit: AMBARI-21307 Added new resource related changes to the db creation ddl-s

Posted by lp...@apache.org.
AMBARI-21307 Added new resource related changes to the db creation ddl-s


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a698726c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a698726c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a698726c

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: a698726c07d0551435c73bb7d19fe7d6ebc2d1fe
Parents: cc7fe2e
Author: lpuskas <lp...@apache.org>
Authored: Thu Jul 6 18:15:18 2017 +0200
Committer: lpuskas <lp...@apache.org>
Committed: Fri Jul 14 14:50:08 2017 +0200

----------------------------------------------------------------------
 .../AmbariConfigurationResourceProvider.java    | 12 ++--
 .../server/orm/dao/AmbariConfigurationDAO.java  | 65 ++------------------
 .../apache/ambari/server/orm/dao/DaoUtils.java  | 13 +---
 .../main/resources/Ambari-DDL-Derby-CREATE.sql  | 21 +++++++
 .../main/resources/Ambari-DDL-MySQL-CREATE.sql  | 20 ++++++
 .../main/resources/Ambari-DDL-Oracle-CREATE.sql | 20 ++++++
 .../resources/Ambari-DDL-Postgres-CREATE.sql    | 14 ++---
 .../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 20 ++++++
 .../resources/Ambari-DDL-SQLServer-CREATE.sql   | 20 ++++++
 9 files changed, 120 insertions(+), 85 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
index 5e5af9e..e8f186d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariConfigurationResourceProvider.java
@@ -97,14 +97,14 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
     }
   }
 
-  private static Set<String> properties = Sets.newHashSet(
+  private static Set<String> PROPERTIES = Sets.newHashSet(
     ResourcePropertyId.ID.getPropertyId(),
     ResourcePropertyId.TYPE.getPropertyId(),
     ResourcePropertyId.VERSION.getPropertyId(),
     ResourcePropertyId.VERSION_TAG.getPropertyId(),
     ResourcePropertyId.DATA.getPropertyId());
 
-  private static Map<Resource.Type, String> pkPropertyMap = Collections.unmodifiableMap(
+  private static Map<Resource.Type, String> PK_PROPERTY_MAP = Collections.unmodifiableMap(
     new HashMap<Resource.Type, String>() {{
       put(Resource.Type.AmbariConfiguration, ResourcePropertyId.ID.getPropertyId());
     }}
@@ -117,7 +117,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
   private Gson gson;
 
   protected AmbariConfigurationResourceProvider() {
-    super(properties, pkPropertyMap);
+    super(PROPERTIES, PK_PROPERTY_MAP);
     setRequiredCreateAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION));
     setRequiredDeleteAuthorizations(EnumSet.of(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION));
 
@@ -126,7 +126,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
 
   @Override
   protected Set<String> getPKPropertyIds() {
-    return Sets.newHashSet("AmbariConfiguration/id");
+    return Sets.newHashSet(ResourcePropertyId.ID.getPropertyId());
   }
 
   @Override
@@ -137,7 +137,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
     AmbariConfigurationEntity ambariConfigurationEntity = getEntityFromRequest(request);
 
     LOGGER.info("Persisting new ambari configuration: {} ", ambariConfigurationEntity);
-    ambariConfigurationDAO.persist(ambariConfigurationEntity);
+    ambariConfigurationDAO.create(ambariConfigurationEntity);
 
     return getRequestStatus(null);
   }
@@ -170,7 +170,7 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
     } else {
       LOGGER.debug("Deleting amari configuration with id: {}", idFromRequest);
       try {
-        ambariConfigurationDAO.deleteById(idFromRequest);
+        ambariConfigurationDAO.removeByPK(idFromRequest);
       } catch (IllegalStateException e) {
         throw new NoSuchResourceException(e.getMessage());
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
index dea37eb..c29a423 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AmbariConfigurationDAO.java
@@ -14,79 +14,24 @@
 
 package org.apache.ambari.server.orm.dao;
 
-import java.util.List;
-
 import javax.inject.Inject;
-import javax.inject.Provider;
 import javax.inject.Singleton;
-import javax.persistence.EntityManager;
-import javax.persistence.TypedQuery;
 
-import org.apache.ambari.server.orm.RequiresSession;
 import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.inject.persist.Transactional;
 
 /**
  * DAO dealing with ambari configuration related JPA operations.
  */
 
 @Singleton
-// todo extend CrudDao (amend crud dao to handle NPEs)
-public class AmbariConfigurationDAO {
-
-  private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationDAO.class);
-
-  @Inject
-  private Provider<EntityManager> entityManagerProvider;
+public class AmbariConfigurationDAO extends CrudDAO<AmbariConfigurationEntity, Long> {
 
-  /**
-   * DAO utilities for dealing mostly with {@link TypedQuery} results.
-   */
   @Inject
-  private DaoUtils daoUtils;
-
-  public AmbariConfigurationEntity findByid(Long id) {
-    return entityManagerProvider.get().find(AmbariConfigurationEntity.class, id);
-  }
-
-  @RequiresSession
-  @Transactional
-  public void persist(AmbariConfigurationEntity entity) {
-    LOGGER.debug("Persisting ambari configuration: {}", entity);
-    entityManagerProvider.get().persist(entity);
+  public AmbariConfigurationDAO() {
+    super(AmbariConfigurationEntity.class);
   }
 
-  @RequiresSession
-  public List<AmbariConfigurationEntity> findAll() {
-    TypedQuery<AmbariConfigurationEntity> query = entityManagerProvider.get().createNamedQuery(
-      "AmbariConfigurationEntity.findAll", AmbariConfigurationEntity.class);
-    return daoUtils.selectList(query);
+  public void create(AmbariConfigurationEntity entity) {
+    super.create(entity);
   }
-
-
-  @RequiresSession
-  @Transactional
-  public void deleteById(Long ambariConfigurationId) {
-
-    if (ambariConfigurationId == null) {
-      throw new IllegalArgumentException("No Ambari Configuration id provided.");
-    }
-
-    LOGGER.debug("Removing Ambari Configuration with id :{}", ambariConfigurationId);
-
-    AmbariConfigurationEntity ambariConfigurationEntity = findByid(ambariConfigurationId);
-    if (ambariConfigurationEntity == null) {
-      String msg = String.format("No Ambari Configuration found with id: %s", ambariConfigurationId);
-      LOGGER.debug(msg);
-      throw new IllegalStateException(msg);
-    }
-
-    entityManagerProvider.get().remove(ambariConfigurationEntity);
-    LOGGER.debug("Ambari Configuration with id: {}", ambariConfigurationId);
-  }
-
-
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
index cd3faf0..e6112ad 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/DaoUtils.java
@@ -18,8 +18,6 @@
 
 package org.apache.ambari.server.orm.dao;
 
-import static org.apache.ambari.server.orm.DBAccessor.DbType;
-
 import java.util.Collections;
 import java.util.List;
 
@@ -31,19 +29,10 @@ import javax.persistence.criteria.CriteriaBuilder;
 import javax.persistence.criteria.CriteriaQuery;
 import javax.persistence.criteria.Root;
 
-import org.apache.ambari.server.orm.DBAccessor;
-
-import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
 @Singleton
 public class DaoUtils {
-  @Inject
-  private DBAccessor dbAccessor;
-
-  public DbType getDbType() {
-    return dbAccessor.getDbType();
-  }
 
   public <T> List<T> selectAll(EntityManager entityManager, Class<T> entityClass) {
     CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
@@ -92,7 +81,7 @@ public class DaoUtils {
 
   public void setParameters(Query query, Object... parameters) {
     for (int i = 0; i < parameters.length; i++) {
-      query.setParameter(i+1, parameters[i]);
+      query.setParameter(i + 1, parameters[i]);
     }
   }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/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 e341405..84bb746 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -84,6 +84,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (version_tag, type_name, cluster_id),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data VARCHAR(3000) NOT NULL,
+  attributes VARCHAR(3000),
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_configuration_configuration_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
@@ -1144,6 +1161,8 @@ INSERT INTO ambari_sequences (sequence_name, sequence_value)
   union all
   select 'servicecomponent_version_id_seq', 0 FROM SYSIBM.SYSDUMMY1
   union all
+  select 'configuration_id_seq', 0 FROM SYSIBM.SYSDUMMY1
+  union all
   select 'hostcomponentdesiredstate_id_seq', 0 FROM SYSIBM.SYSDUMMY1;
 
 
@@ -1244,6 +1263,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' FROM SYSIBM.SYSDUMMY1 UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configurations' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' FROM SYSIBM.SYSDUMMY1 UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' FROM SYSIBM.SYSDUMMY1 UNION ALL
@@ -1445,6 +1465,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR'  UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/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 ce8736e..95eb3f1 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -104,6 +104,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(100) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(100) NOT NULL,
+  data LONGTEXT NOT NULL,
+  attributes LONGTEXT,
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_configuration_configuration_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
@@ -1109,6 +1126,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) VALUES
   ('remote_cluster_id_seq', 0),
   ('remote_cluster_service_id_seq', 0),
   ('servicecomponent_version_id_seq', 0),
+  ('configuration_id_seq', 0),
   ('hostcomponentdesiredstate_id_seq', 0);
 
 INSERT INTO adminresourcetype (resource_type_id, resource_type_name) VALUES
@@ -1193,6 +1211,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage administrative settings' UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1398,6 +1417,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
index ace3738..9a468a6 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -84,6 +84,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id NUMBER(19) NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version NUMBER(19) NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data CLOB NOT NULL,
+  attributes CLOB,
+  create_timestamp NUMBER(19) NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id NUMBER(19) NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_configuration_configuration_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id NUMBER(19) NOT NULL,
   cluster_id NUMBER(19) NOT NULL,
@@ -1088,6 +1105,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('ambari_oper
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('servicecomponent_version_id_seq', 0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('configuration_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostcomponentdesiredstate_id_seq', 0);
 
 INSERT INTO metainfo("metainfo_key", "metainfo_value") values ('version', '${ambariSchemaVersion}');
@@ -1191,6 +1209,7 @@ INSERT INTO roleauthorization(authorization_id, authorization_name)
   SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' FROM dual UNION ALL
   SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' FROM dual UNION ALL
+  SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_USERS', 'Manage users' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' FROM dual UNION ALL
   SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' FROM dual UNION ALL
@@ -1396,6 +1415,7 @@ INSERT INTO permission_roleauthorization(permission_id, authorization_id)
   SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+  SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
   SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
index dffff86..4c4c324 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -67,13 +67,13 @@ CREATE TABLE clusters (
 );
 
 CREATE TABLE configuration_base (
-  id               BIGINT       NOT NULL,
-  version_tag      VARCHAR(255) NOT NULL,
-  version          BIGINT       NOT NULL,
-  type             VARCHAR(255) NOT NULL,
-  data             TEXT         NOT NULL,
-  attributes       TEXT,
-  create_timestamp BIGINT       NOT NULL,
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data TEXT NOT NULL,
+  attributes TEXT,
+  create_timestamp BIGINT NOT NULL,
   CONSTRAINT PK_configuration_base PRIMARY KEY (id)
 );
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
index 6164b2d..885985e 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -83,6 +83,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id NUMERIC(19) NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version NUMERIC(19) NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data TEXT NOT NULL,
+  attributes TEXT,
+  create_timestamp NUMERIC(19) NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id NUMERIC(19) NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_configuration_configuration_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id NUMERIC(19) NOT NULL,
   cluster_id NUMERIC(19) NOT NULL,
@@ -1087,6 +1104,7 @@ INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_clus
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('remote_cluster_service_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('servicecomponent_version_id_seq', 0);
 INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('hostcomponentdesiredstate_id_seq', 0);
+INSERT INTO ambari_sequences(sequence_name, sequence_value) values ('configuration_id_seq', 0);
 
 insert into adminresourcetype (resource_type_id, resource_type_name)
   select 1, 'AMBARI'
@@ -1187,6 +1205,7 @@ insert into adminpermission(permission_id, permission_name, resource_type_id, pe
     SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
     SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
     SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' UNION ALL
+    SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
     SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
     SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
     SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1392,6 +1411,7 @@ insert into adminpermission(permission_id, permission_name, resource_type_id, pe
     SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+    SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL

http://git-wip-us.apache.org/repos/asf/ambari/blob/a698726c/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
index 52d2b87..1b0af5a 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -97,6 +97,23 @@ CREATE TABLE clusterconfig (
   CONSTRAINT UQ_config_type_tag UNIQUE (cluster_id, type_name, version_tag),
   CONSTRAINT UQ_config_type_version UNIQUE (cluster_id, type_name, version));
 
+CREATE TABLE configuration_base (
+  id BIGINT NOT NULL,
+  version_tag VARCHAR(255) NOT NULL,
+  version BIGINT NOT NULL,
+  type VARCHAR(255) NOT NULL,
+  data VARCHAR(MAX) NOT NULL,
+  attributes VARCHAR(MAX),
+  create_timestamp BIGINT NOT NULL,
+  CONSTRAINT PK_configuration_base PRIMARY KEY (id)
+);
+
+CREATE TABLE ambari_configuration (
+  id BIGINT NOT NULL,
+  CONSTRAINT PK_ambari_configuration PRIMARY KEY (id),
+  CONSTRAINT FK_ambari_configuration_configuration_base FOREIGN KEY (id) REFERENCES configuration_base (id)
+);
+
 CREATE TABLE serviceconfig (
   service_config_id BIGINT NOT NULL,
   cluster_id BIGINT NOT NULL,
@@ -1113,6 +1130,7 @@ BEGIN TRANSACTION
     ('remote_cluster_id_seq', 0),
     ('remote_cluster_service_id_seq', 0),
     ('servicecomponent_version_id_seq', 0),
+    ('configuration_id_seq', 0),
     ('hostcomponentdesiredstate_id_seq', 0);
 
   insert into adminresourcetype (resource_type_id, resource_type_name)
@@ -1201,6 +1219,7 @@ BEGIN TRANSACTION
     SELECT 'AMBARI.ADD_DELETE_CLUSTERS', 'Create new clusters' UNION ALL
     SELECT 'AMBARI.RENAME_CLUSTER', 'Rename clusters' UNION ALL
     SELECT 'AMBARI.MANAGE_SETTINGS', 'Manage settings' UNION ALL
+    SELECT 'AMBARI.MANAGE_CONFIGURATION', 'Manage ambari configuration' UNION ALL
     SELECT 'AMBARI.MANAGE_USERS', 'Manage users' UNION ALL
     SELECT 'AMBARI.MANAGE_GROUPS', 'Manage groups' UNION ALL
     SELECT 'AMBARI.MANAGE_VIEWS', 'Manage Ambari Views' UNION ALL
@@ -1406,6 +1425,7 @@ BEGIN TRANSACTION
     SELECT permission_id, 'AMBARI.ADD_DELETE_CLUSTERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.RENAME_CLUSTER' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_SETTINGS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
+    SELECT permission_id, 'AMBARI.MANAGE_CONFIGURATION' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_USERS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_GROUPS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL
     SELECT permission_id, 'AMBARI.MANAGE_VIEWS' FROM adminpermission WHERE permission_name='AMBARI.ADMINISTRATOR' UNION ALL


[4/4] ambari git commit: Added swagger annotations to the new endpoint

Posted by lp...@apache.org.
Added swagger annotations to the new endpoint


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/86cff073
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/86cff073
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/86cff073

Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 86cff073f15c4745ff5d4f091526d34a7161e2d5
Parents: a698726
Author: Balázs Bence Sári <bs...@hortonworks.com>
Authored: Thu Jul 6 18:36:18 2017 +0200
Committer: lpuskas <lp...@apache.org>
Committed: Fri Jul 14 14:50:08 2017 +0200

----------------------------------------------------------------------
 .../AmbariConfigurationRequestSwagger.java      | 48 +++++++++++++++
 .../AmbariConfigurationResponseSwagger.java     | 40 +++++++++++++
 .../services/AmbariConfigurationService.java    | 62 +++++++++++++++++---
 3 files changed, 143 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/86cff073/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationRequestSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationRequestSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationRequestSwagger.java
new file mode 100644
index 0000000..d6714f9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationRequestSwagger.java
@@ -0,0 +1,48 @@
+/*
+ * Licensed 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 java.util.Map;
+
+import org.apache.ambari.server.controller.ApiModel;
+import org.apache.ambari.server.orm.entities.ConfigurationBaseEntity;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Request data model for {@link org.apache.ambari.server.api.services.AmbariConfigurationService}
+ */
+public interface AmbariConfigurationRequestSwagger extends ApiModel {
+
+  @ApiModelProperty(name = "AmbariConfiguration")
+  AmbariConfigurationRequestInfo getAmbariConfiguration();
+
+  interface AmbariConfigurationRequestInfo {
+    @ApiModelProperty
+    Long getId();
+
+    @ApiModelProperty
+    Map<String, Object> getData();
+
+    @ApiModelProperty
+    String getType();
+
+    @ApiModelProperty
+    Long getVersion();
+
+    @ApiModelProperty(name = "version_tag")
+    String getVersionTag();
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/86cff073/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationResponseSwagger.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationResponseSwagger.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationResponseSwagger.java
new file mode 100644
index 0000000..c55ac1d
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationResponseSwagger.java
@@ -0,0 +1,40 @@
+/*
+ * Licensed 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 java.util.Map;
+
+import org.apache.ambari.server.controller.ApiModel;
+
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * Response data model for {@link org.apache.ambari.server.api.services.AmbariConfigurationService}
+ */
+public interface AmbariConfigurationResponseSwagger extends ApiModel {
+
+  @ApiModelProperty(name = "AmbariConfiguration")
+  AmbariConfigurationResponseInfo getAmbariConfigurationResponse();
+
+  interface AmbariConfigurationResponseInfo {
+    @ApiModelProperty
+    Long getId();
+
+    @ApiModelProperty
+    Map<String, Object> getData();
+
+    @ApiModelProperty
+    String getType();
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/86cff073/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
index 0fa6e44..0c159b9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariConfigurationService.java
@@ -70,9 +70,12 @@ import io.swagger.annotations.ApiResponses;
  * </pre>
  */
 @Path("/configurations/")
-@Api(value = "/configurations", description = "Endpoint for Ambari configuration related operations")
+@Api(value = "Ambari Configurations", description = "Endpoint for Ambari configuration related operations")
 public class AmbariConfigurationService extends BaseService {
 
+  private static final String AMBARI_CONFIGURATION_REQUEST_TYPE =
+      "org.apache.ambari.server.api.services.AmbariConfigurationRequestSwagger";
+
   /**
    * Creates an ambari configuration resource.
    *
@@ -83,9 +86,10 @@ public class AmbariConfigurationService extends BaseService {
    */
   @POST
   @Produces(MediaType.TEXT_PLAIN)
-  @ApiOperation(value = "Creates an ambari configuration resource")
+  @ApiOperation(value = "Creates an ambari configuration resource",
+      nickname = "AmbariConfigurationService#createAmbariConfiguration")
   @ApiImplicitParams({
-    @ApiImplicitParam(dataType = "", paramType = PARAM_TYPE_BODY)
+      @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
   })
   @ApiResponses({
     @ApiResponse(code = HttpStatus.SC_CREATED, message = MSG_SUCCESSFUL_OPERATION),
@@ -103,7 +107,26 @@ public class AmbariConfigurationService extends BaseService {
 
   @GET
   @Produces(MediaType.TEXT_PLAIN)
-  @ApiOperation(value = "Retrieve ambari configuration resources")
+  @ApiOperation(value = "Retrieve all ambari configuration resources",
+      nickname = "AmbariConfigurationService#getAmbariConfigurations",
+      notes = "Returns all Ambari configurations.",
+      response = AmbariConfigurationResponseSwagger.class,
+      responseContainer = RESPONSE_CONTAINER_LIST)
+  @ApiImplicitParams({
+      @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION,
+          defaultValue = "AmbariConfiguration/data, AmbariConfiguration/id, AmbariConfiguration/type",
+          dataType = DATA_TYPE_STRING, paramType = PARAM_TYPE_QUERY),
+      @ApiImplicitParam(name = QUERY_SORT, value = QUERY_SORT_DESCRIPTION,
+          defaultValue = "AmbariConfiguration/id",
+          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 getAmbariConfigurations(String body, @Context HttpHeaders headers, @Context UriInfo uri) {
     return handleRequest(headers, body, uri, Request.Type.GET, createResource(Resource.Type.AmbariConfiguration,
       Collections.EMPTY_MAP));
@@ -112,7 +135,18 @@ public class AmbariConfigurationService extends BaseService {
   @GET
   @Path("{configurationId}")
   @Produces(MediaType.TEXT_PLAIN)
-  @ApiOperation(value = "Retrieve ambari configuration resource")
+  @ApiOperation(value = "Retrieve the details of an ambari configuration resource",
+      nickname = "AmbariConfigurationService#getAmbariConfiguration",
+      response = AmbariConfigurationResponseSwagger.class)
+  @ApiImplicitParams({
+      @ApiImplicitParam(name = QUERY_FIELDS, value = QUERY_FILTER_DESCRIPTION, defaultValue = "AmbariConfiguration/*",
+          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 getAmbariConfiguration(String body, @Context HttpHeaders headers, @Context UriInfo uri,
                                          @PathParam("configurationId") String configurationId) {
     return handleRequest(headers, body, uri, Request.Type.GET, createResource(Resource.Type.AmbariConfiguration,
@@ -121,7 +155,20 @@ public class AmbariConfigurationService extends BaseService {
 
   @PUT
   @Produces(MediaType.TEXT_PLAIN)
-  @ApiOperation(value = "Update ambari configuration resources")
+  @ApiOperation(value = "Updates ambari configuration resources - Not implemented yet",
+    nickname = "AmbariConfigurationService#updateAmbariConfiguration")
+  @ApiImplicitParams({
+      @ApiImplicitParam(dataType = AMBARI_CONFIGURATION_REQUEST_TYPE, paramType = PARAM_TYPE_BODY)
+  })
+  @ApiResponses({
+      @ApiResponse(code = HttpStatus.SC_OK, 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_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 updateAmbariConfiguration() {
     throw new UnsupportedOperationException("Not yet implemented");
   }
@@ -129,7 +176,8 @@ public class AmbariConfigurationService extends BaseService {
   @DELETE
   @Path("{configurationId}")
   @Produces(MediaType.TEXT_PLAIN)
-  @ApiOperation(value = "Deletes an ambari configuration resource")
+  @ApiOperation(value = "Deletes an ambari configuration resource",
+      nickname = "AmbariConfigurationService#deleteAmbariConfiguration")
   @ApiResponses({
     @ApiResponse(code = HttpStatus.SC_OK, message = MSG_SUCCESSFUL_OPERATION),
     @ApiResponse(code = HttpStatus.SC_NOT_FOUND, message = MSG_RESOURCE_NOT_FOUND),