You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by mr...@apache.org on 2017/12/05 20:36:02 UTC
[36/51] [abbrv] ambari git commit: AMBARI-22481. Make Ambari LDAP
configuration API consistent with existing API (rlevas)
AMBARI-22481. Make Ambari LDAP configuration API consistent with existing API (rlevas)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4240f849
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4240f849
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4240f849
Branch: refs/heads/branch-feature-AMBARI-14714
Commit: 4240f8496175bf9fb369b9411e71ad1127e356ad
Parents: c3150a4
Author: Robert Levas <rl...@hortonworks.com>
Authored: Thu Nov 30 12:04:12 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Thu Nov 30 12:04:12 2017 -0500
----------------------------------------------------------------------
.../server/api/handlers/CreateHandler.java | 8 +-
.../server/api/handlers/UpdateHandler.java | 8 +-
.../resources/ResourceInstanceFactoryImpl.java | 4 +-
...ootServiceComponentConfigurationService.java | 15 ++
.../api/services/ldap/AmbariConfiguration.java | 46 ----
.../api/services/ldap/LdapConfigOperation.java | 43 ----
.../services/ldap/LdapConfigurationRequest.java | 49 ----
.../services/ldap/LdapConfigurationService.java | 185 --------------
.../api/services/ldap/LdapRequestInfo.java | 61 -----
.../services/serializers/JsonSerializer.java | 38 ++-
.../commands/StackAdvisorCommand.java | 14 +-
.../AmbariServerConfigurationCategory.java | 69 ++++++
.../AmbariServerConfigurationHandler.java | 110 +++++++++
.../AmbariServerLDAPConfigurationHandler.java | 172 +++++++++++++
.../internal/OperationStatusMetaData.java | 90 +++++++
...ootServiceComponentConfigurationHandler.java | 114 +++++++++
...iceComponentConfigurationHandlerFactory.java | 54 +++++
...eComponentConfigurationResourceProvider.java | 243 ++++++++-----------
.../apache/ambari/server/ldap/LdapModule.java | 4 -
.../ldap/domain/AmbariLdapConfigKeys.java | 83 -------
.../ldap/domain/AmbariLdapConfiguration.java | 85 +++----
.../domain/AmbariLdapConfigurationFactory.java | 34 ---
.../domain/AmbariLdapConfigurationKeys.java | 83 +++++++
.../AmbariLdapConfigurationProvider.java | 19 +-
.../server/ldap/service/AmbariLdapFacade.java | 4 +-
.../ambari/server/ldap/service/LdapFacade.java | 9 +-
.../DefaultLdapAttributeDetectionService.java | 8 +-
.../ads/DefaultLdapConfigurationService.java | 4 +-
.../ads/detectors/GroupMemberAttrDetector.java | 4 +-
.../ads/detectors/GroupNameAttrDetector.java | 7 +-
.../ads/detectors/GroupObjectClassDetector.java | 8 +-
.../detectors/UserGroupMemberAttrDetector.java | 5 +-
.../ads/detectors/UserNameAttrDetector.java | 4 +-
.../ads/detectors/UserObjectClassDetector.java | 4 +-
.../commands/StackAdvisorCommandTest.java | 4 +-
...ponentConfigurationResourceProviderTest.java | 214 +++++++++++++---
.../server/ldap/LdapModuleFunctionalTest.java | 49 ++--
.../TestAmbariLdapConfigurationFactory.java | 29 ---
.../ldap/service/AmbariLdapFacadeTest.java | 36 ++-
...efaultLdapAttributeDetectionServiceTest.java | 24 +-
.../DefaultLdapConfigurationServiceTest.java | 31 ++-
41 files changed, 1184 insertions(+), 891 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
index b614c5e..484547a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/CreateHandler.java
@@ -24,6 +24,7 @@ import org.apache.ambari.server.api.services.Result;
import org.apache.ambari.server.api.services.ResultImpl;
import org.apache.ambari.server.api.services.ResultMetadata;
import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.controller.internal.OperationStatusMetaData;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.RequestStatus;
import org.apache.ambari.server.controller.spi.RequestStatusMetaData;
@@ -94,6 +95,11 @@ public class CreateHandler extends BaseManagementHandler {
return null;
}
- throw new UnsupportedOperationException();
+ if (requestStatusMetaData.getClass() == OperationStatusMetaData.class) {
+ return (OperationStatusMetaData) requestStatusMetaData;
+ } else {
+ throw new IllegalArgumentException(String.format("RequestStatusDetails is of an expected type: %s",
+ requestStatusMetaData.getClass().getName()));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
index 2f1af51..c578cb9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/handlers/UpdateHandler.java
@@ -24,6 +24,7 @@ import org.apache.ambari.server.api.services.Result;
import org.apache.ambari.server.api.services.ResultImpl;
import org.apache.ambari.server.api.services.ResultMetadata;
import org.apache.ambari.server.api.services.ResultStatus;
+import org.apache.ambari.server.controller.internal.OperationStatusMetaData;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.RequestStatus;
@@ -79,6 +80,11 @@ public class UpdateHandler extends BaseManagementHandler {
return null;
}
- throw new UnsupportedOperationException();
+ if (requestStatusMetaData.getClass() == OperationStatusMetaData.class) {
+ return (OperationStatusMetaData) requestStatusMetaData;
+ } else {
+ throw new IllegalArgumentException(String.format("RequestStatusDetails is of an expected type: %s",
+ requestStatusMetaData.getClass().getName()));
+ }
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/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 fecaedc..47da19b 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
@@ -26,6 +26,7 @@ import java.util.Map;
import java.util.Set;
import org.apache.ambari.server.api.query.QueryImpl;
+import org.apache.ambari.server.api.services.RootServiceComponentConfigurationService;
import org.apache.ambari.server.controller.internal.ClusterKerberosDescriptorResourceProvider;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.controller.utilities.ClusterControllerHelper;
@@ -239,7 +240,8 @@ public class ResourceInstanceFactoryImpl implements ResourceInstanceFactory {
case RootServiceComponentConfiguration:
resourceDefinition = new SimpleResourceDefinition(Resource.Type.RootServiceComponentConfiguration,
- "configuration", "configurations");
+ "configuration", "configurations",
+ null, RootServiceComponentConfigurationService.DIRECTIVES_MAP);
break;
case RootServiceHostComponent:
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfigurationService.java
index c7c37a6..a6be143 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/RootServiceComponentConfigurationService.java
@@ -34,6 +34,7 @@ package org.apache.ambari.server.api.services;
import java.util.HashMap;
import java.util.Map;
+import java.util.Set;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
@@ -48,10 +49,14 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
+import org.apache.ambari.server.api.resources.BaseResourceDefinition;
import org.apache.ambari.server.api.resources.ResourceInstance;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.http.HttpStatus;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Sets;
+
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
@@ -91,6 +96,16 @@ public class RootServiceComponentConfigurationService extends BaseService {
private static final String REQUEST_TYPE =
"org.apache.ambari.server.api.services.RootServiceComponentConfigurationRequestSwagger";
+ public static final String DIRECTIVE_OPERATION = "op";
+
+ private static final Set<String> DIRECTIVES = Sets.newHashSet(DIRECTIVE_OPERATION);
+
+ public static final Map<BaseResourceDefinition.DirectiveType, Set<String>> DIRECTIVES_MAP =
+ ImmutableMap.<BaseResourceDefinition.DirectiveType, Set<String>>builder()
+ .put(BaseResourceDefinition.DirectiveType.CREATE, DIRECTIVES)
+ .put(BaseResourceDefinition.DirectiveType.UPDATE, DIRECTIVES)
+ .build();
+
private final String serviceName;
private final String componentName;
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfiguration.java
deleted file mode 100644
index 7bac65e..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfiguration.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.ldap;
-
-import java.util.Map;
-
-/**
- * Domain POJO representing generic ambari configuration data.
- */
-public class AmbariConfiguration {
-
- /**
- * The type of the configuration, eg.: ldap-configuration
- */
- private String type;
-
- private Map<String, String> properties = null;
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public Map<String, String> getProperties() {
- return properties;
- }
-
- public void setProperties(Map<String, String> data) {
- this.properties = data;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigOperation.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigOperation.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigOperation.java
deleted file mode 100644
index 478d4ff..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigOperation.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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.ldap;
-
-/**
- * Enumeration for supported operations related to LDAP configuration.
- */
-public enum LdapConfigOperation {
- TEST_CONNECTION("test-connection"),
- TEST_ATTRIBUTES("test-attributes"),
- DETECT_ATTRIBUTES("detect-attributes");
-
- private String actionStr;
-
- LdapConfigOperation(String actionStr) {
- this.actionStr = actionStr;
- }
-
- public static LdapConfigOperation fromAction(String action) {
- for (LdapConfigOperation val : LdapConfigOperation.values()) {
- if (val.action().equals(action)) {
- return val;
- }
- }
- throw new IllegalStateException("Action [ " + action + " ] is not supported");
- }
-
- public String action() {
- return this.actionStr;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationRequest.java
deleted file mode 100644
index 0e065e5..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationRequest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.ldap;
-
-
-import com.google.gson.annotations.SerializedName;
-
-/**
- * Request object wrapping information for LDAP configuration related request calls.
- */
-public class LdapConfigurationRequest {
-
- @SerializedName("Configuration")
- private AmbariConfiguration ambariConfiguration;
-
- @SerializedName("RequestInfo")
- private LdapRequestInfo requestInfo;
-
- public LdapConfigurationRequest() {
- }
-
- public AmbariConfiguration getAmbariConfiguration() {
- return ambariConfiguration;
- }
-
- public void setAmbariConfiguration(AmbariConfiguration ambariConfiguration) {
- this.ambariConfiguration = ambariConfiguration;
- }
-
- public LdapRequestInfo getRequestInfo() {
- return requestInfo;
- }
-
- public void setRequestInfo(LdapRequestInfo requestInfo) {
- this.requestInfo = requestInfo;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
deleted file mode 100644
index 22784cd..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * 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.
- */
-
-/*
- * 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.ldap;
-
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-
-import org.apache.ambari.annotations.ApiIgnore;
-import org.apache.ambari.server.StaticallyInject;
-import org.apache.ambari.server.api.services.BaseService;
-import org.apache.ambari.server.api.services.Result;
-import org.apache.ambari.server.api.services.ResultImpl;
-import org.apache.ambari.server.api.services.ResultStatus;
-import org.apache.ambari.server.controller.internal.ResourceImpl;
-import org.apache.ambari.server.controller.spi.Resource;
-import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationFactory;
-import org.apache.ambari.server.ldap.service.LdapFacade;
-import org.apache.ambari.server.security.authorization.AuthorizationException;
-import org.apache.ambari.server.security.authorization.AuthorizationHelper;
-import org.apache.ambari.server.security.authorization.ResourceType;
-import org.apache.ambari.server.security.authorization.RoleAuthorization;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.security.core.Authentication;
-
-import com.google.common.collect.Sets;
-
-/**
- * Endpoint designated to LDAP specific operations.
- */
-@StaticallyInject
-@Path("/ldapconfigs/")
-public class LdapConfigurationService extends BaseService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(LdapConfigurationService.class);
-
- @Inject
- private static LdapFacade ldapFacade;
-
- @Inject
- private static AmbariLdapConfigurationFactory ambariLdapConfigurationFactory;
-
-
- @POST
- @ApiIgnore // until documented
- @Path("/validate")
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response validateConfiguration(LdapConfigurationRequest ldapConfigurationRequest) {
-
- // check if the user is authorized to perform the operation
- authorize();
-
- Set<String> groups = Sets.newHashSet();
- Object responseEntity = null;
-
- Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
- try {
-
- validateRequest(ldapConfigurationRequest);
-
- AmbariLdapConfiguration ambariLdapConfiguration = ambariLdapConfigurationFactory.createLdapConfiguration(
- ldapConfigurationRequest.getAmbariConfiguration().getProperties());
-
- LdapConfigOperation action = LdapConfigOperation.fromAction(ldapConfigurationRequest.getRequestInfo().getAction());
- switch (action) {
-
- case TEST_CONNECTION:
-
- LOGGER.info("Testing connection to the LDAP server ...");
- ldapFacade.checkConnection(ambariLdapConfiguration);
-
- break;
- case TEST_ATTRIBUTES:
-
- LOGGER.info("Testing LDAP attributes ....");
- groups = ldapFacade.checkLdapAttributes(ldapConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
- responseEntity = groups;
-
- break;
- case DETECT_ATTRIBUTES:
-
- LOGGER.info("Detecting LDAP attributes ...");
- ambariLdapConfiguration = ldapFacade.detectAttributes(ambariLdapConfiguration);
- responseEntity = ambariLdapConfiguration;
-
- break;
- default:
- LOGGER.warn("No action provided ...");
- throw new IllegalArgumentException("No request action provided");
- }
-
- } catch (Exception e) {
- result.setResultStatus(new ResultStatus(ResultStatus.STATUS.SERVER_ERROR, e));
- responseEntity = e.getMessage();
- }
-
- return Response.status(result.getStatus().getStatusCode()).entity(responseEntity).build();
- }
-
- private void setResult(Set<String> groups, Result result) {
- Resource resource = new ResourceImpl(Resource.Type.RootServiceComponentConfiguration);
- resource.setProperty("groups", groups);
- result.getResultTree().addChild(resource, "payload");
- }
-
- private void validateRequest(LdapConfigurationRequest ldapConfigurationRequest) {
- String errMsg;
-
- if (null == ldapConfigurationRequest) {
- errMsg = "No ldap configuraiton request provided";
- LOGGER.error(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
-
- if (null == ldapConfigurationRequest.getRequestInfo()) {
- errMsg = String.format("No request information provided. Request: [%s]", ldapConfigurationRequest);
- LOGGER.error(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
-
- if (null == ldapConfigurationRequest.getAmbariConfiguration()
- || ldapConfigurationRequest.getAmbariConfiguration().getProperties() != null) {
- errMsg = String.format("No / Invalid configuration data provided. Request: [%s]", ldapConfigurationRequest);
- LOGGER.error(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
- }
-
- private void authorize() {
- try {
- Authentication authentication = AuthorizationHelper.getAuthentication();
-
- if (authentication == null || !authentication.isAuthenticated()) {
- throw new AuthorizationException("Authentication data is not available, authorization to perform the requested operation is not granted");
- }
-
- if (!AuthorizationHelper.isAuthorized(authentication, ResourceType.AMBARI, null, requiredAuthorizations())) {
- throw new AuthorizationException("The authenticated user does not have the appropriate authorizations to create the requested resource(s)");
- }
- } catch (AuthorizationException e) {
- LOGGER.error("Unauthorized operation.", e);
- throw new IllegalArgumentException("User is not authorized to perform the operation", e);
- }
-
- }
-
- private Set<RoleAuthorization> requiredAuthorizations() {
- return Sets.newHashSet(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION);
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRequestInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRequestInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRequestInfo.java
deleted file mode 100644
index eeecfee..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRequestInfo.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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.ldap;
-
-import java.util.Map;
-
-import org.apache.ambari.server.controller.RequestPostRequest;
-
-/**
- * Bean holding LDAP request specific request information.
- */
-public class LdapRequestInfo implements RequestPostRequest.RequestInfo {
-
- // no-arg costructor facilitating JSON serialization
- public LdapRequestInfo() {
- }
-
- private String action;
-
- private Map<String, Object> parameters;
-
- @Override
- public String getAction() {
- return action;
- }
-
- public void setAction(String action) {
- this.action = action;
- }
-
- public void setParameters(Map<String, Object> parameters) {
- this.parameters = parameters;
- }
-
- @Override
- public String getCommand() {
- return null;
- }
-
- @Override
- public RequestPostRequest.OperationLevel getOperationLevel() {
- return null;
- }
-
- @Override
- public Map<String, Object> getParameters() {
- return parameters;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
index 0604d2b..a045d74 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/serializers/JsonSerializer.java
@@ -31,6 +31,7 @@ import org.apache.ambari.server.api.services.ResultMetadata;
import org.apache.ambari.server.api.services.ResultStatus;
import org.apache.ambari.server.api.util.TreeNode;
import org.apache.ambari.server.api.util.TreeNodeImpl;
+import org.apache.ambari.server.controller.internal.OperationStatusMetaData;
import org.apache.ambari.server.controller.spi.Resource;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
@@ -112,6 +113,8 @@ public class JsonSerializer implements ResultSerializer {
if (resultMetadata.getClass() == DeleteResultMetadata.class) {
processResultMetadata((DeleteResultMetadata) resultMetadata);
+ } else if (resultMetadata.getClass() == OperationStatusMetaData.class) {
+ processResultMetadata((OperationStatusMetaData) resultMetadata);
} else {
throw new IllegalArgumentException("ResultDetails is not of type DeleteResultDetails, cannot parse");
}
@@ -144,6 +147,30 @@ public class JsonSerializer implements ResultSerializer {
m_generator.writeEndObject();
}
+ private void processResultMetadata(OperationStatusMetaData metaData) throws IOException {
+ m_generator.writeStartObject();
+ m_generator.writeObjectFieldStart("operationResults");
+
+ for (OperationStatusMetaData.Result result : metaData.getResults()) {
+ m_generator.writeObjectFieldStart(result.getId());
+ m_generator.writeStringField("status", result.isSuccess() ? "success" : "error");
+
+ if (result.getMessage() != null) {
+ m_generator.writeStringField("message", result.getMessage());
+ }
+
+ if (result.getResponse() != null) {
+ m_generator.writeFieldName("response");
+ m_mapper.writeValue(m_generator, result.getResponse());
+ }
+
+ m_generator.writeEndObject();
+ }
+
+ m_generator.writeEndObject();
+ m_generator.writeEndObject();
+ }
+
private void processNode(TreeNode<Resource> node) throws IOException {
if (isObject(node)) {
m_generator.writeStartObject();
@@ -158,10 +185,11 @@ public class JsonSerializer implements ResultSerializer {
}
if (isArray(node)) {
- if (node.getName() != null)
+ if (node.getName() != null) {
m_generator.writeArrayFieldStart(node.getName());
- else
+ } else {
m_generator.writeStartArray();
+ }
}
for (TreeNode<Resource> child : node.getChildren()) {
@@ -186,11 +214,11 @@ public class JsonSerializer implements ResultSerializer {
// Determines whether or not the given node is an array
private boolean isArray(TreeNode<Resource> node) {
return (node.getObject() == null && node.getName() != null) ||
- (node.getObject() == null && node.getName() == null &&
- node.getChildren().size() > 1);
+ (node.getObject() == null && node.getName() == null &&
+ node.getChildren().size() > 1);
}
- private TreeNode<Map<String, Object>> getTreeProperties (Map<String, Map<String, Object>> propertiesMap) {
+ private TreeNode<Map<String, Object>> getTreeProperties(Map<String, Map<String, Object>> propertiesMap) {
TreeNode<Map<String, Object>> treeProperties = new TreeNodeImpl<>(null, new LinkedHashMap<>(), null);
for (Map.Entry<String, Map<String, Object>> entry : propertiesMap.entrySet()) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
index 4ec15ef..6e6b37e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java
@@ -47,6 +47,7 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorResponse;
import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner;
import org.apache.ambari.server.controller.RootComponent;
import org.apache.ambari.server.controller.RootService;
+import org.apache.ambari.server.controller.internal.AmbariServerConfigurationCategory;
import org.apache.ambari.server.controller.internal.RootServiceComponentConfigurationResourceProvider;
import org.apache.ambari.server.controller.spi.Resource;
import org.apache.ambari.server.state.ServiceInfo;
@@ -78,7 +79,6 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
private static final String GET_HOSTS_INFO_URI = "/api/v1/hosts"
+ "?fields=Hosts/*&Hosts/host_name.in(%s)";
- static final String LDAP_CONFIGURATION_PROPERTY = "ldap-configuration";
private static final String GET_SERVICES_INFO_URI = "/api/v1/stacks/%s/versions/%s/"
+ "?fields=Versions/stack_name,Versions/stack_version,Versions/parent_stack_version"
@@ -91,11 +91,11 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
+ "&services/StackServices/service_name.in(%s)";
private static final String GET_AMBARI_LDAP_CONFIG_URI = String.format("/api/v1/services/%s/components/%s/configurations?%s=%s&fields=%s",
- RootService.AMBARI.name(),
- RootComponent.AMBARI_SERVER.name(),
- RootServiceComponentConfigurationResourceProvider.CONFIGURATION_CATEGORY_PROPERTY_ID,
- LDAP_CONFIGURATION_PROPERTY,
- RootServiceComponentConfigurationResourceProvider.CONFIGURATION_PROPERTIES_PROPERTY_ID);
+ RootService.AMBARI.name(),
+ RootComponent.AMBARI_SERVER.name(),
+ RootServiceComponentConfigurationResourceProvider.CONFIGURATION_CATEGORY_PROPERTY_ID,
+ AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName(),
+ RootServiceComponentConfigurationResourceProvider.CONFIGURATION_PROPERTIES_PROPERTY_ID);
private static final String SERVICES_PROPERTY = "services";
private static final String SERVICES_COMPONENTS_PROPERTY = "components";
@@ -230,7 +230,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
throw new StackAdvisorException("Unexpected JSON document encountered: missing the Configuration/properties object");
}
- root.put(LDAP_CONFIGURATION_PROPERTY, ldapConfigurationProperties);
+ root.put(AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName(), ldapConfigurationProperties);
} else if (numConfigs > 1) {
throw new StackAdvisorException(String.format("Multiple (%s) LDAP configs are found in the DB.", numConfigs));
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationCategory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationCategory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationCategory.java
new file mode 100644
index 0000000..f4fc83f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationCategory.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * AmbariServerConfigurationCategory is an enumeration of the different Ambari server specific
+ * configuration categories.
+ */
+public enum AmbariServerConfigurationCategory {
+ LDAP_CONFIGURATION("ldap-configuration");
+
+ private final String categoryName;
+
+ AmbariServerConfigurationCategory(String categoryName) {
+ this.categoryName = categoryName;
+ }
+
+ public String getCategoryName() {
+ return categoryName;
+ }
+
+ /**
+ * Safely returns an {@link AmbariServerConfigurationCategory} given the category's descriptive name
+ *
+ * @param categoryName a descriptive name
+ * @return an {@link AmbariServerConfigurationCategory}
+ */
+ public static AmbariServerConfigurationCategory translate(String categoryName) {
+ if (!StringUtils.isEmpty(categoryName)) {
+ categoryName = categoryName.trim();
+ for (AmbariServerConfigurationCategory category : values()) {
+ if (category.getCategoryName().equals(categoryName)) {
+ return category;
+ }
+ }
+ }
+
+ throw new IllegalArgumentException(String.format("Invalid Ambari server configuration category name: %s", categoryName));
+ }
+
+ /**
+ * Safely returns the {@link AmbariServerConfigurationCategory}'s descriptive name or <code>null</code>
+ * if no {@link AmbariServerConfigurationCategory} was supplied.
+ *
+ * @param category an {@link AmbariServerConfigurationCategory}
+ * @return the descriptive name of an {@link AmbariServerConfigurationCategory}
+ */
+ public static String translate(AmbariServerConfigurationCategory category) {
+ return (category == null) ? null : category.getCategoryName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
new file mode 100644
index 0000000..34285d6
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerConfigurationHandler.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.events.AmbariConfigurationChangedEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+/**
+ * AmbariServerConfigurationHandler handles Ambari server specific configuration properties.
+ */
+@StaticallyInject
+class AmbariServerConfigurationHandler extends RootServiceComponentConfigurationHandler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AmbariServerConfigurationHandler.class);
+
+ @Inject
+ private static AmbariConfigurationDAO ambariConfigurationDAO;
+
+ @Inject
+ private static AmbariEventPublisher publisher;
+
+
+ @Override
+ public Map<String, Map<String, String>> getConfigurations(String categoryName)
+ throws NoSuchResourceException {
+ Map<String, Map<String, String>> configurations = null;
+
+ List<AmbariConfigurationEntity> entities = (categoryName == null)
+ ? ambariConfigurationDAO.findAll()
+ : ambariConfigurationDAO.findByCategory(categoryName);
+
+ if (entities != null) {
+ configurations = new HashMap<>();
+
+ for (AmbariConfigurationEntity entity : entities) {
+ String category = entity.getCategoryName();
+ Map<String, String> properties = configurations.get(category);
+
+ if (properties == null) {
+ properties = new TreeMap<>();
+ configurations.put(category, properties);
+ }
+
+ properties.put(entity.getPropertyName(), entity.getPropertyValue());
+ }
+ }
+
+ return configurations;
+ }
+
+ @Override
+ public void removeConfiguration(String categoryName) throws NoSuchResourceException {
+ if (null == categoryName) {
+ LOGGER.debug("No resource id provided in the request");
+ } else {
+ LOGGER.debug("Deleting Ambari configuration with id: {}", categoryName);
+ try {
+ if (ambariConfigurationDAO.removeByCategory(categoryName) > 0) {
+ publisher.publish(new AmbariConfigurationChangedEvent(categoryName));
+ }
+ } catch (IllegalStateException e) {
+ throw new NoSuchResourceException(e.getMessage());
+ }
+ }
+ }
+
+ @Override
+ public void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified) {
+ if (ambariConfigurationDAO.reconcileCategory(categoryName, properties, removePropertiesIfNotSpecified)) {
+ // notify subscribers about the configuration changes
+ publisher.publish(new AmbariConfigurationChangedEvent(categoryName));
+ }
+ }
+
+ @Override
+ public OperationResult performOperation(String categoryName, Map<String, String> properties,
+ boolean mergeExistingProperties, String operation,
+ Map<String, Object> operationParameters) throws SystemException {
+ throw new SystemException(String.format("The requested operation is not supported for this category: %s", categoryName));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
new file mode 100644
index 0000000..6f16c49
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/AmbariServerLDAPConfigurationHandler.java
@@ -0,0 +1,172 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ambari.server.StaticallyInject;
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.SystemException;
+import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.LdapFacade;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.Inject;
+
+/**
+ * AmbariServerLDAPConfigurationHandler handles Ambari server LDAP-specific configuration properties.
+ */
+@StaticallyInject
+class AmbariServerLDAPConfigurationHandler extends AmbariServerConfigurationHandler {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AmbariServerLDAPConfigurationHandler.class);
+
+ @Inject
+ private static LdapFacade ldapFacade;
+
+ @Override
+ public OperationResult performOperation(String categoryName, Map<String, String> properties,
+ boolean mergeExistingProperties, String operation, Map<String, Object> operationParameters) throws SystemException {
+
+ if (!AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName().equals(categoryName)) {
+ throw new SystemException(String.format("Unexpected category name for Ambari server LDAP properties: %s", categoryName));
+ }
+
+ OperationType operationType = OperationType.translate(operation);
+ if (operation == null) {
+ throw new SystemException("Unexpected operation for Ambari server LDAP properties");
+ }
+
+ Map<String, String> ldapConfigurationProperties = new HashMap<>();
+
+ // If we need to merge with the properties of an existing ldap-configuration property set, attempt
+ // to retrieve if. If one does not exist, that is ok.
+ if (mergeExistingProperties) {
+ try {
+ Map<String, Map<String, String>> _configurations = getConfigurations(categoryName);
+ if (_configurations != null) {
+ Map<String, String> _ldapProperties = _configurations.get(categoryName);
+
+ if (_ldapProperties != null) {
+ ldapConfigurationProperties.putAll(_ldapProperties);
+ }
+ }
+ } catch (NoSuchResourceException e) {
+ // Ignore this. There is no existing ldap-configuration category and that is ok.
+ }
+ }
+
+ if (properties != null) {
+ ldapConfigurationProperties.putAll(properties);
+ }
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapConfigurationProperties);
+
+ boolean success = true;
+ String message = null;
+ Object resultData = null;
+
+ try {
+ switch (operationType) {
+ case TEST_CONNECTION:
+ LOGGER.debug("Testing connection to the LDAP server ...");
+ ldapFacade.checkConnection(ambariLdapConfiguration);
+ break;
+
+ case TEST_ATTRIBUTES:
+ LOGGER.debug("Testing LDAP attributes ....");
+ Set<String> groups = ldapFacade.checkLdapAttributes(operationParameters, ambariLdapConfiguration);
+ resultData = Collections.singletonMap("groups", groups);
+ break;
+
+ case DETECT_ATTRIBUTES:
+ LOGGER.info("Detecting LDAP attributes ...");
+ ambariLdapConfiguration = ldapFacade.detectAttributes(ambariLdapConfiguration);
+ resultData = Collections.singletonMap("attributes", ambariLdapConfiguration.toMap());
+ break;
+
+ default:
+ LOGGER.warn("No action provided ...");
+ throw new IllegalArgumentException("No request action provided");
+ }
+ } catch (AmbariLdapException e) {
+ success = false;
+ message = determineCause(e);
+ if (StringUtils.isEmpty(message)) {
+ message = "An unexpected error has occurred.";
+ }
+
+ LOGGER.warn(String.format("Failed to perform %s: %s", operationType.name(), message), e);
+ }
+
+ return new OperationResult(operationType.getOperation(), success, message, resultData);
+ }
+
+ private String determineCause(Throwable throwable) {
+ if (throwable == null) {
+ return null;
+ } else {
+ Throwable cause = throwable.getCause();
+ if ((cause == null) || (cause == throwable)) {
+ return throwable.getMessage();
+ } else {
+ String message = determineCause(cause);
+ return (message == null) ? throwable.getMessage() : message;
+ }
+ }
+ }
+
+ enum OperationType {
+ TEST_CONNECTION("test-connection"),
+ TEST_ATTRIBUTES("test-attributes"),
+ DETECT_ATTRIBUTES("detect-attributes");
+
+ private final String operation;
+
+ OperationType(String operation) {
+ this.operation = operation;
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public static OperationType translate(String operation) {
+ if (!StringUtils.isEmpty(operation)) {
+ operation = operation.trim();
+ for (OperationType category : values()) {
+ if (category.getOperation().equals(operation)) {
+ return category;
+ }
+ }
+ }
+
+ throw new IllegalArgumentException(String.format("Invalid Ambari server configuration category name: %s", operation));
+ }
+
+ public static String translate(OperationType operation) {
+ return (operation == null) ? null : operation.getOperation();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/OperationStatusMetaData.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/OperationStatusMetaData.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/OperationStatusMetaData.java
new file mode 100644
index 0000000..2467fc5
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/OperationStatusMetaData.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+import org.apache.ambari.server.api.services.ResultMetadata;
+import org.apache.ambari.server.controller.spi.RequestStatusMetaData;
+
+/**
+ * OperationStatusMetaData is data to return as the status of an operation invoked on a set of resources
+ * while processing a REST API request.
+ * <p>
+ * Zero or more results may be set as part of the data.
+ */
+public class OperationStatusMetaData implements RequestStatusMetaData, ResultMetadata {
+
+ private final Map<String, Result> results = new HashMap<>();
+
+ public void addResult(String id, boolean success, String message, Object response) {
+ results.put(id, new Result(id, success, message, response));
+ }
+
+ public Set<String> getResultIds() {
+ return results.keySet();
+ }
+
+ public Result getResult(String id) {
+ if (results.containsKey(id)) {
+ return results.get(id);
+ }
+
+ throw new NoSuchElementException();
+ }
+
+ public List<Result> getResults() {
+ return new ArrayList<>(results.values());
+ }
+
+ public class Result {
+ private final String id;
+ private final boolean success;
+ private final String message;
+ private final Object response;
+
+ Result(String id, boolean success, String message, Object response) {
+ this.id = id;
+ this.success = success;
+ this.message = message;
+ this.response = response;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Object getResponse() {
+ return response;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
new file mode 100644
index 0000000..3b58ce1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandler.java
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import java.util.Map;
+
+import org.apache.ambari.server.controller.spi.NoSuchResourceException;
+import org.apache.ambari.server.controller.spi.SystemException;
+
+/**
+ * RootServiceComponentConfigurationHandler is an interface to be implemented to handle the different
+ * types of root-level configurations.
+ */
+abstract class RootServiceComponentConfigurationHandler {
+ /**
+ * Retrieve the request configurations.
+ *
+ * @param categoryName the category name (or <code>null</code> for all)
+ * @return a map of category names to properties (name/value pairs).
+ * @throws NoSuchResourceException if the requested data is not found
+ */
+ public abstract Map<String, Map<String, String>> getConfigurations(String categoryName) throws NoSuchResourceException;
+
+ /**
+ * Delete the requested configuration.
+ *
+ * @param categoryName the category name
+ * @throws NoSuchResourceException if the requested category does not exist
+ */
+ public abstract void removeConfiguration(String categoryName) throws NoSuchResourceException;
+
+ /**
+ * Set or update a configuration category with the specified properties.
+ * <p>
+ * If <code>removePropertiesIfNotSpecified</code> is <code>true</code>, the persisted category is to include only the specified properties.
+ * <p>
+ * If <code>removePropertiesIfNotSpecified</code> is <code>false</code>, the persisted category is to include the union of the existing and specified properties.
+ * <p>
+ * In any case, existing property values will be overwritten by the one specified in the property map.
+ *
+ * @param categoryName the category name
+ * @param properties a map of properties to set
+ * @param removePropertiesIfNotSpecified <code>true</code> to ensure the set of properties are only those that have be explicitly specified;
+ * <code>false</code> to update the set of existing properties with the specified set of properties, adding missing properties but not removing any properties
+ */
+ public abstract void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified);
+
+ /**
+ * Preform some operation on the set of data for a category.
+ * <p>
+ * If <code>mergeExistingProperties</code> is <code>false</code>, the operation is to include the union of the existing and specified properties.
+ * <p>
+ * If <code>mergeExistingProperties</code> is <code>false</code>, the operation is to include only the specified properties.
+ *
+ * @param categoryName the category name
+ * @param properties a map of properties to set
+ * @param mergeExistingProperties <code>true</code> to use the the set of existing properties along with the specified set of properties;
+ * <code>false</code> to use set of specified properties only
+ * @param operation the operation to perform
+ * @param operationParameters parameters to supply the name operation
+ * @return an {@link OperationResult}
+ * @throws SystemException if an error occurs while handling the request
+ */
+ public abstract OperationResult performOperation(String categoryName, Map<String, String> properties,
+ boolean mergeExistingProperties, String operation,
+ Map<String, Object> operationParameters) throws SystemException;
+
+ class OperationResult {
+ private final String id;
+ private final boolean success;
+ private final String message;
+ private final Object response;
+
+ OperationResult(String id, boolean success, String message, Object response) {
+ this.id = id;
+ this.success = success;
+ this.message = message;
+ this.response = response;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public boolean isSuccess() {
+ return success;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public Object getResponse() {
+ return response;
+ }
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandlerFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandlerFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandlerFactory.java
new file mode 100644
index 0000000..38b5373
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationHandlerFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ambari.server.controller.internal;
+
+import org.apache.ambari.server.controller.RootComponent;
+import org.apache.ambari.server.controller.RootService;
+
+import com.google.inject.Singleton;
+
+/**
+ * RootServiceComponentConfigurationHandlerFactory produces RootServiceComponentConfigurationHandler
+ * implementations for the relevant service, component, and category.
+ */
+@Singleton
+public class RootServiceComponentConfigurationHandlerFactory {
+
+ /**
+ * Returns the internal configuration handler used to support various configuration storage facilities.
+ *
+ * @param serviceName the service name
+ * @param componentName the component name
+ * @param categoryName the category name
+ * @return a {@link RootServiceComponentConfigurationHandler}
+ */
+ public RootServiceComponentConfigurationHandler getInstance(String serviceName, String componentName, String categoryName) {
+ if (RootService.AMBARI.name().equals(serviceName)) {
+ if (RootComponent.AMBARI_SERVER.name().equals(componentName)) {
+ if (AmbariServerConfigurationCategory.LDAP_CONFIGURATION.getCategoryName().equals(categoryName)) {
+ return new AmbariServerLDAPConfigurationHandler();
+ } else {
+ return new AmbariServerConfigurationHandler();
+ }
+ }
+ }
+
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
index 7807865..b9e7d67 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RootServiceComponentConfigurationResourceProvider.java
@@ -22,14 +22,11 @@ import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
-import java.util.TreeMap;
import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.controller.RootComponent;
-import org.apache.ambari.server.controller.RootService;
+import org.apache.ambari.server.api.services.RootServiceComponentConfigurationService;
import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
import org.apache.ambari.server.controller.spi.NoSuchResourceException;
import org.apache.ambari.server.controller.spi.Predicate;
@@ -41,22 +38,14 @@ 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.controller.utilities.PropertyHelper;
-import org.apache.ambari.server.events.AmbariConfigurationChangedEvent;
-import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
-import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
-import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
import org.apache.ambari.server.security.authorization.RoleAuthorization;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
import com.google.inject.Inject;
public class RootServiceComponentConfigurationResourceProvider extends AbstractAuthorizedResourceProvider {
- private static final Logger LOGGER = LoggerFactory.getLogger(RootServiceComponentConfigurationResourceProvider.class);
-
static final String RESOURCE_KEY = "Configuration";
public static final String CONFIGURATION_CATEGORY_PROPERTY_ID = PropertyHelper.getPropertyId(RESOURCE_KEY, "category");
@@ -89,10 +78,7 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
}
@Inject
- private AmbariConfigurationDAO ambariConfigurationDAO;
-
- @Inject
- private AmbariEventPublisher publisher;
+ private RootServiceComponentConfigurationHandlerFactory rootServiceComponentConfigurationHandlerFactory;
public RootServiceComponentConfigurationResourceProvider() {
super(PROPERTIES, PK_PROPERTY_MAP);
@@ -113,9 +99,20 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
public RequestStatus createResourcesAuthorized(Request request)
throws SystemException, UnsupportedPropertyException, ResourceAlreadyExistsException, NoSuchParentResourceException {
- createOrAddProperties(null, null, null, request.getProperties(), true);
+ OperationStatusMetaData operationStatusMetadata = null;
- return getRequestStatus(null);
+ Map<String, String> requestInfoProperties = request.getRequestInfoProperties();
+ if (requestInfoProperties.containsKey(RootServiceComponentConfigurationService.DIRECTIVE_OPERATION)) {
+ String operationType = requestInfoProperties.get(RootServiceComponentConfigurationService.DIRECTIVE_OPERATION);
+ Map<String, Object> operationParameters = getOperationParameters(requestInfoProperties);
+
+ operationStatusMetadata = performOperation(null, null, null, request.getProperties(),
+ false, operationType, operationParameters);
+ } else {
+ createOrAddProperties(null, null, null, request.getProperties(), true);
+ }
+
+ return getRequestStatus(null, null, operationStatusMetadata);
}
@Override
@@ -163,7 +160,6 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
});
}
-
@Override
protected RequestStatus deleteResourcesAuthorized(Request request, Predicate predicate) throws SystemException,
UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
@@ -172,7 +168,7 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
String componentName = (String) PredicateHelper.getProperties(predicate).get(CONFIGURATION_COMPONENT_NAME_PROPERTY_ID);
String categoryName = (String) PredicateHelper.getProperties(predicate).get(CONFIGURATION_CATEGORY_PROPERTY_ID);
- ConfigurationHandler handler = getConfigurationHandler(serviceName, componentName);
+ RootServiceComponentConfigurationHandler handler = rootServiceComponentConfigurationHandlerFactory.getInstance(serviceName, componentName, categoryName);
if (handler != null) {
handler.removeConfiguration(categoryName);
} else {
@@ -190,9 +186,20 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
String componentName = (String) PredicateHelper.getProperties(predicate).get(CONFIGURATION_COMPONENT_NAME_PROPERTY_ID);
String categoryName = (String) PredicateHelper.getProperties(predicate).get(CONFIGURATION_CATEGORY_PROPERTY_ID);
- createOrAddProperties(serviceName, componentName, categoryName, request.getProperties(), false);
+ OperationStatusMetaData operationStatusMetadata = null;
- return getRequestStatus(null);
+ Map<String, String> requestInfoProperties = request.getRequestInfoProperties();
+ if (requestInfoProperties.containsKey(RootServiceComponentConfigurationService.DIRECTIVE_OPERATION)) {
+ String operationType = requestInfoProperties.get(RootServiceComponentConfigurationService.DIRECTIVE_OPERATION);
+ Map<String, Object> operationParameters = getOperationParameters(requestInfoProperties);
+
+ operationStatusMetadata = performOperation(serviceName, componentName, categoryName, request.getProperties(),
+ true, operationType, operationParameters);
+ } else {
+ createOrAddProperties(serviceName, componentName, categoryName, request.getProperties(), false);
+ }
+
+ return getRequestStatus(null, null, operationStatusMetadata);
}
private Resource toResource(String serviceName, String componentName, String categoryName, Map<String, String> properties, Set<String> requestedIds) {
@@ -211,7 +218,7 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
* value and one or more property (<code>AmbariConfiguration/properties/property.name</code>) values.
* If a category cannot be determined from the propery set, the default category value (passed in)
* is used. If a default category is set, it is assumed that it was parsed from the request predicate
- * (if availabe).
+ * (if available).
*
* @param defaultServiceName the default service name to use if needed
* @param defaultComponentName the default component name to use if needed
@@ -229,8 +236,7 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
for (Map<String, Object> resourceProperties : requestProperties) {
RequestDetails requestDetails = parseProperties(defaultServiceName, defaultComponentName, defaultCategoryName, resourceProperties);
- ConfigurationHandler handler = getConfigurationHandler(requestDetails.serviceName, requestDetails.componentName);
-
+ RootServiceComponentConfigurationHandler handler = rootServiceComponentConfigurationHandlerFactory.getInstance(requestDetails.serviceName, requestDetails.componentName, requestDetails.categoryName);
if (handler != null) {
handler.updateCategory(requestDetails.categoryName, requestDetails.properties, removePropertiesIfNotSpecified);
} else {
@@ -241,6 +247,49 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
}
/**
+ * Performs the requested operation on the set of data for the specified configration data.
+ *
+ * @param defaultServiceName the default service name to use if needed
+ * @param defaultComponentName the default component name to use if needed
+ * @param defaultCategoryName the default category to use if needed
+ * @param requestProperties a collection of property maps parsed from the request
+ * @param mergeExistingProperties <code>true</code> to use the the set of existing properties along with the specified set of properties;
+ * <code>false</code> to use set of specified properties only
+ * @param operationType the operation to perform
+ * @param operationParameters parameters to supply the name operation
+ * @return an {@link OperationStatusMetaData}
+ * @throws SystemException if an error occurs while performing the operation
+ */
+ private OperationStatusMetaData performOperation(String defaultServiceName, String defaultComponentName, String defaultCategoryName,
+ Set<Map<String, Object>> requestProperties, boolean mergeExistingProperties,
+ String operationType, Map<String, Object> operationParameters)
+ throws SystemException {
+
+ OperationStatusMetaData metaData = new OperationStatusMetaData();
+
+ // set of resource properties (each entry in the set belongs to a different resource)
+ if (requestProperties != null) {
+ for (Map<String, Object> resourceProperties : requestProperties) {
+ RequestDetails requestDetails = parseProperties(defaultServiceName, defaultComponentName, defaultCategoryName, resourceProperties);
+
+ RootServiceComponentConfigurationHandler handler = rootServiceComponentConfigurationHandlerFactory.getInstance(requestDetails.serviceName, requestDetails.componentName, requestDetails.categoryName);
+ if (handler != null) {
+ RootServiceComponentConfigurationHandler.OperationResult operationResult = handler.performOperation(requestDetails.categoryName, requestDetails.properties, mergeExistingProperties, operationType, operationParameters);
+ if (operationResult == null) {
+ throw new SystemException(String.format("An unexpected error has occurred while handling an operation for the %s component of the root service, %s", requestDetails.serviceName, requestDetails.componentName));
+ }
+
+ metaData.addResult(operationResult.getId(), operationResult.isSuccess(), operationResult.getMessage(), operationResult.getResponse());
+ } else {
+ throw new SystemException(String.format("Operations may not be performed on configurations for the %s component of the root service, %s", requestDetails.serviceName, requestDetails.componentName));
+ }
+ }
+ }
+
+ return metaData;
+ }
+
+ /**
* Parse the property map from a request into a map of services to components to category names to maps of property names and values.
*
* @param defaultServiceName the default service name to use if one is not found in the map of properties
@@ -300,7 +349,31 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
}
/**
- * Retrieves the requested configration resources
+ * Creates a map of the operation parameters from the data in the request info map.
+ * <p>
+ * Operation parmaters are set under the "parameters" category.
+ *
+ * @param requestInfoProperties a map of request info properties
+ * @return a map of operation request parameters
+ */
+ private Map<String, Object> getOperationParameters(Map<String, String> requestInfoProperties) {
+ Map<String, Object> operationParameters = new HashMap<>();
+
+ for (Map.Entry<String, String> entry : requestInfoProperties.entrySet()) {
+ String propertyCategory = PropertyHelper.getPropertyCategory(entry.getKey());
+ if ((propertyCategory != null) && propertyCategory.equals("parameters")) {
+ String name = PropertyHelper.getPropertyName(entry.getKey());
+ Object value = entry.getValue();
+ operationParameters.put(name, (value == null) ? null : value.toString());
+ }
+ }
+
+ return operationParameters;
+ }
+
+
+ /**
+ * Retrieves the requested configuration resources
*
* @param requestedIds the requested properties ids
* @param propertyMap the request properties
@@ -312,11 +385,11 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
String serviceName = getStringProperty(propertyMap, CONFIGURATION_SERVICE_NAME_PROPERTY_ID);
String componentName = getStringProperty(propertyMap, CONFIGURATION_COMPONENT_NAME_PROPERTY_ID);
+ String categoryName = getStringProperty(propertyMap, CONFIGURATION_CATEGORY_PROPERTY_ID);
- ConfigurationHandler handler = getConfigurationHandler(serviceName, componentName);
+ RootServiceComponentConfigurationHandler handler = rootServiceComponentConfigurationHandlerFactory.getInstance(serviceName, componentName, categoryName);
if (handler != null) {
- String categoryName = getStringProperty(propertyMap, CONFIGURATION_CATEGORY_PROPERTY_ID);
Map<String, Map<String, String>> configurations = handler.getConfigurations(categoryName);
if (configurations != null) {
@@ -329,24 +402,6 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
return resources;
}
- /**
- * Returns the internal configuration handler used to support various configuration storage facilites.
- *
- * @param serviceName the service name
- * @param componentName the component name
- * @return
- */
- private ConfigurationHandler getConfigurationHandler(String serviceName, String componentName) {
- if (RootService.AMBARI.name().equals(serviceName)) {
- if (RootComponent.AMBARI_SERVER.name().equals(componentName)) {
- return new AmbariServerConfigurationHandler();
- }
- }
-
- return null;
- }
-
-
private String getStringProperty(Map<String, Object> propertyMap, String propertyId) {
String value = null;
@@ -361,102 +416,6 @@ public class RootServiceComponentConfigurationResourceProvider extends AbstractA
}
/**
- * ConfigurationHandler is an interface to be implemented to support the relevant types of storage
- * used to persist root-level component configurations.
- */
- private abstract class ConfigurationHandler {
- /**
- * Retrieve the request configurations.
- *
- * @param categoryName the category name (or <code>null</code> for all)
- * @return a map of category names to properties (name/value pairs).
- * @throws NoSuchResourceException if the requested data is not found
- */
- public abstract Map<String, Map<String, String>> getConfigurations(String categoryName) throws NoSuchResourceException;
-
- /**
- * Delete the requested configuration.
- *
- * @param categoryName the category name
- * @throws NoSuchResourceException if the requested category does not exist
- */
- public abstract void removeConfiguration(String categoryName) throws NoSuchResourceException;
-
- /**
- * Set or update a configuration category with the specified properties.
- * <p>
- * If <code>removePropertiesIfNotSpecified</code> is <code>true</code>, the persisted category is to include only the specified properties.
- * <p>
- * If <code>removePropertiesIfNotSpecified</code> is <code>false</code>, the persisted category is to include the union of the existing and specified properties.
- * <p>
- * In any case, existing property values will be overwritten by the one specified in the property map.
- *
- * @param categoryName the category name
- * @param properties a map of properties to set
- * @param removePropertiesIfNotSpecified <code>true</code> to ensure the set of properties are only those that have be explicitly specified;
- * <code>false</code> to update the set of exising properties with the specified set of properties, adding missing properties but not removing any properties
- */
- public abstract void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified);
- }
-
- /**
- * AmbariServerConfigurationHandler handle Ambari server specific configuration properties.
- */
- private class AmbariServerConfigurationHandler extends ConfigurationHandler {
- @Override
- public Map<String, Map<String, String>> getConfigurations(String categoryName)
- throws NoSuchResourceException {
- Map<String, Map<String, String>> configurations = null;
-
- List<AmbariConfigurationEntity> entities = (categoryName == null)
- ? ambariConfigurationDAO.findAll()
- : ambariConfigurationDAO.findByCategory(categoryName);
-
- if (entities != null) {
- configurations = new HashMap<>();
-
- for (AmbariConfigurationEntity entity : entities) {
- String category = entity.getCategoryName();
- Map<String, String> properties = configurations.get(category);
-
- if (properties == null) {
- properties = new TreeMap<>();
- configurations.put(category, properties);
- }
-
- properties.put(entity.getPropertyName(), entity.getPropertyValue());
- }
- }
-
- return configurations;
- }
-
- @Override
- public void removeConfiguration(String categoryName) throws NoSuchResourceException {
- if (null == categoryName) {
- LOGGER.debug("No resource id provided in the request");
- } else {
- LOGGER.debug("Deleting Ambari configuration with id: {}", categoryName);
- try {
- if (ambariConfigurationDAO.removeByCategory(categoryName) > 0) {
- publisher.publish(new AmbariConfigurationChangedEvent(categoryName));
- }
- } catch (IllegalStateException e) {
- throw new NoSuchResourceException(e.getMessage());
- }
- }
- }
-
- @Override
- public void updateCategory(String categoryName, Map<String, String> properties, boolean removePropertiesIfNotSpecified) {
- if (ambariConfigurationDAO.reconcileCategory(categoryName, properties, removePropertiesIfNotSpecified)) {
- // notify subscribers about the configuration changes
- publisher.publish(new AmbariConfigurationChangedEvent(categoryName));
- }
- }
- }
-
- /**
* RequestDetails is a container for details parsed from the request.
*/
private class RequestDetails {
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
index 089da1d..64e94c4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
@@ -16,7 +16,6 @@
package org.apache.ambari.server.ldap;
import org.apache.ambari.server.ldap.domain.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.domain.AmbariLdapConfigurationFactory;
import org.apache.ambari.server.ldap.service.AmbariLdapConfigurationProvider;
import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
import org.apache.ambari.server.ldap.service.AttributeDetector;
@@ -36,7 +35,6 @@ import org.apache.ambari.server.ldap.service.ads.detectors.UserNameAttrDetector;
import org.apache.ambari.server.ldap.service.ads.detectors.UserObjectClassDetector;
import com.google.inject.AbstractModule;
-import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.google.inject.multibindings.Multibinder;
import com.google.inject.name.Names;
@@ -60,8 +58,6 @@ public class LdapModule extends AbstractModule {
bind(AttributeDetectorFactory.class);
- install(new FactoryModuleBuilder().build(AmbariLdapConfigurationFactory.class));
-
// binding the set of user attributes detector
Multibinder<AttributeDetector> userAttributeDetectorBinder = Multibinder.newSetBinder(binder(), AttributeDetector.class,
Names.named(USER_ATTRIBUTES_DETECTORS));
http://git-wip-us.apache.org/repos/asf/ambari/blob/4240f849/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigKeys.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigKeys.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigKeys.java
deleted file mode 100644
index da655ad..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/domain/AmbariLdapConfigKeys.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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.ldap.domain;
-
-/**
- * Constants representing supported LDAP related property names
- * // todo extend this with validation information, description, defaults maybe
- */
-public enum AmbariLdapConfigKeys {
-
- LDAP_ENABLED("ambari.ldap.authentication.enabled"),
- SERVER_HOST("ambari.ldap.connectivity.server.host"),
- SERVER_PORT("ambari.ldap.connectivity.server.port"),
- USE_SSL("ambari.ldap.connectivity.use_ssl"),
-
- TRUST_STORE("ambari.ldap.connectivity.trust_store"),
- TRUST_STORE_TYPE("ambari.ldap.connectivity.trust_store.type"),
- TRUST_STORE_PATH("ambari.ldap.connectivity.trust_store.path"),
- TRUST_STORE_PASSWORD("ambari.ldap.connectivity.trust_store.password"),
- ANONYMOUS_BIND("ambari.ldap.connectivity.anonymous_bind"),
-
- BIND_DN("ambari.ldap.connectivity.bind_dn"),
- BIND_PASSWORD("ambari.ldap.connectivity.bind_password"),
-
- ATTR_DETECTION("ambari.ldap.attributes.detection"), // manual | auto
-
- DN_ATTRIBUTE("ambari.ldap.attributes.dn_attr"),
-
- USER_OBJECT_CLASS("ambari.ldap.attributes.user.object_class"),
- USER_NAME_ATTRIBUTE("ambari.ldap.attributes.user.name_attr"),
- USER_GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.user.group_member_attr"),
- USER_SEARCH_BASE("ambari.ldap.attributes.user.search_base"),
-
- GROUP_OBJECT_CLASS("ambari.ldap.attributes.group.object_class"),
- GROUP_NAME_ATTRIBUTE("ambari.ldap.attributes.group.name_attr"),
- GROUP_MEMBER_ATTRIBUTE("ambari.ldap.attributes.group.member_attr"),
- GROUP_SEARCH_BASE("ambari.ldap.attributes.group.search_base"),
-
- USER_SEARCH_FILTER("ambari.ldap.advanced.user_search_filter"),
- USER_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.user_member_replace_pattern"),
- USER_MEMBER_FILTER("ambari.ldap.advanced.user_member_filter"),
-
- GROUP_SEARCH_FILTER("ambari.ldap.advanced.group_search_filter"),
- GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.advanced.group_member_replace_pattern"),
- GROUP_MEMBER_FILTER("ambari.ldap.advanced.group_member_filter"),
-
- FORCE_LOWERCASE_USERNAMES("ambari.ldap.advanced.force_lowercase_usernames"),
- REFERRAL_HANDLING("ambari.ldap.advanced.referrals"), // folow
- PAGINATION_ENABLED("ambari.ldap.advanced.pagination_enabled"); // true | false
-
- private String propertyName;
-
- AmbariLdapConfigKeys(String propName) {
- this.propertyName = propName;
- }
-
- public String key() {
- return this.propertyName;
- }
-
- public static AmbariLdapConfigKeys fromKeyStr(String keyStr) {
- for (AmbariLdapConfigKeys key : values()) {
- if (key.key().equals(keyStr)) {
- return key;
- }
- }
-
- throw new IllegalStateException("invalid konfiguration key found!");
-
- }
-}