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/09/14 14:38:37 UTC
[01/38] ambari git commit: AMBARI-21922. Allow SERVER Type Alerts To
Run For Any Service/Component (amagyar) [Forced Update!]
Repository: ambari
Updated Branches:
refs/heads/feature-branch-AMBARI-21307 ac3b69628 -> ac71c44c5 (forced update)
AMBARI-21922. Allow SERVER Type Alerts To Run For Any Service/Component (amagyar)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/252e9898
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/252e9898
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/252e9898
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 252e9898c7e68a94924f63549b45af528d15ad14
Parents: c241b9a
Author: Attila Magyar <am...@hortonworks.com>
Authored: Tue Sep 12 13:12:37 2017 +0200
Committer: Attila Magyar <am...@hortonworks.com>
Committed: Tue Sep 12 13:13:51 2017 +0200
----------------------------------------------------------------------
.../server/orm/dao/AlertDefinitionDAO.java | 13 +++++++++++++
.../orm/entities/AlertDefinitionEntity.java | 4 ++--
.../services/AmbariServerAlertService.java | 20 ++++----------------
.../server/orm/dao/AlertDefinitionDAOTest.java | 6 ++++++
4 files changed, 25 insertions(+), 18 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/252e9898/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
index d71429c..cda03f3 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAO.java
@@ -37,6 +37,7 @@ import org.apache.ambari.server.orm.entities.AlertGroupEntity;
import org.apache.ambari.server.state.alert.AlertDefinition;
import org.apache.ambari.server.state.alert.AlertDefinitionFactory;
import org.apache.ambari.server.state.alert.Scope;
+import org.apache.ambari.server.state.alert.SourceType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -308,6 +309,18 @@ public class AlertDefinitionDAO {
}
/**
+ * @return all definitions with the given sourceType
+ */
+ @RequiresSession
+ public List<AlertDefinitionEntity> findBySourceType(Long clusterId, SourceType sourceType) {
+ return daoUtils.selectList(
+ entityManagerProvider.get()
+ .createNamedQuery("AlertDefinitionEntity.findBySourceType", AlertDefinitionEntity.class)
+ .setParameter("clusterId", clusterId)
+ .setParameter("sourceType", sourceType));
+ }
+
+ /**
* Persists a new alert definition, also creating the associated
* {@link AlertGroupEntity} relationship for the definition's service default
* group. Fires an {@link AlertDefinitionRegistrationEvent}.
http://git-wip-us.apache.org/repos/asf/ambari/blob/252e9898/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
index de203be..2f4941b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/AlertDefinitionEntity.java
@@ -72,8 +72,8 @@ import org.apache.ambari.server.state.alert.SourceType;
@NamedQuery(name = "AlertDefinitionEntity.findByService", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.clusterId = :clusterId"),
@NamedQuery(name = "AlertDefinitionEntity.findByServiceAndComponent", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName = :serviceName AND ad.componentName = :componentName AND ad.clusterId = :clusterId"),
@NamedQuery(name = "AlertDefinitionEntity.findByServiceMaster", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.serviceName IN :services AND ad.scope = :scope AND ad.clusterId = :clusterId AND ad.componentName IS NULL"),
- @NamedQuery(name = "AlertDefinitionEntity.findByIds", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionId IN :definitionIds")})
-
+ @NamedQuery(name = "AlertDefinitionEntity.findByIds", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.definitionId IN :definitionIds"),
+ @NamedQuery(name = "AlertDefinitionEntity.findBySourceType", query = "SELECT ad FROM AlertDefinitionEntity ad WHERE ad.clusterId = :clusterId AND ad.sourceType = :sourceType")})
public class AlertDefinitionEntity {
@Id
http://git-wip-us.apache.org/repos/asf/ambari/blob/252e9898/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
index b8058c8..f5d811d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
@@ -113,28 +113,18 @@ public class AmbariServerAlertService extends AbstractScheduledService {
/**
* {@inheritDoc}
* <p/>
- * Loads all of the {@link Components#AMBARI_SERVER} definitions and schedules
+ * Loads all of the definitions with SERVER source type and schedules
* the ones that are enabled.
*/
@Override
protected void startUp() throws Exception {
Map<String, Cluster> clusterMap = m_clustersProvider.get().getClusters();
for (Cluster cluster : clusterMap.values()) {
- List<AlertDefinitionEntity> entities = m_dao.findByServiceComponent(
- cluster.getClusterId(), Services.AMBARI.name(),
- Components.AMBARI_SERVER.name());
-
- for (AlertDefinitionEntity entity : entities) {
+ for (AlertDefinitionEntity entity : m_dao.findBySourceType(cluster.getClusterId(), SourceType.SERVER)) {
// don't schedule disabled alert definitions
if (!entity.getEnabled()) {
continue;
}
-
- SourceType sourceType = entity.getSourceType();
- if (sourceType != SourceType.SERVER) {
- continue;
- }
-
// schedule the Runnable for the definition
scheduleRunnable(entity);
}
@@ -152,10 +142,8 @@ public class AmbariServerAlertService extends AbstractScheduledService {
protected void runOneIteration() throws Exception {
Map<String, Cluster> clusterMap = m_clustersProvider.get().getClusters();
for (Cluster cluster : clusterMap.values()) {
- // get all of the cluster alerts for AMBARI/AMBARI_SERVER
- List<AlertDefinitionEntity> entities = m_dao.findByServiceComponent(
- cluster.getClusterId(), Services.AMBARI.name(),
- Components.AMBARI_SERVER.name());
+ // get all of the cluster alerts with SERVER source type
+ List<AlertDefinitionEntity> entities = m_dao.findBySourceType(cluster.getClusterId(), SourceType.SERVER);
// for each alert, check to see if it's scheduled correctly
for (AlertDefinitionEntity entity : entities) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/252e9898/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
index 33d9b3d..d559e0c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/orm/dao/AlertDefinitionDAOTest.java
@@ -279,6 +279,12 @@ public class AlertDefinitionDAOTest {
}
@Test
+ public void testFindBySourceType() throws Exception {
+ assertEquals(15, dao.findBySourceType(clusterId, SourceType.SCRIPT).size());
+ assertEquals(0, dao.findBySourceType(clusterId, SourceType.METRIC).size());
+ }
+
+ @Test
public void testRefresh() {
}
[08/38] ambari git commit: AMBARI-21932. Some clients are being
additionally installed via Add service wizard.(jaimin)
Posted by lp...@apache.org.
AMBARI-21932. Some clients are being additionally installed via Add service wizard.(jaimin)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9316ea85
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9316ea85
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9316ea85
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 9316ea858991552a13481f9d2dab3273e73565f2
Parents: aaf6f0a
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Tue Sep 12 11:00:25 2017 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Tue Sep 12 11:02:12 2017 -0700
----------------------------------------------------------------------
ambari-web/app/controllers/wizard/step8_controller.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/9316ea85/ambari-web/app/controllers/wizard/step8_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/wizard/step8_controller.js b/ambari-web/app/controllers/wizard/step8_controller.js
index cc06b5b..b99c6e3 100644
--- a/ambari-web/app/controllers/wizard/step8_controller.js
+++ b/ambari-web/app/controllers/wizard/step8_controller.js
@@ -1333,7 +1333,8 @@ App.WizardStep8Controller = Em.Controller.extend(App.AddSecurityConfigs, App.wiz
clientsToClientMap[_clientName].forEach(function (componentName) {
clientHosts.forEach(function (_clientHost) {
var host = this.get('content.hosts')[_clientHost.hostName];
- if (host.isInstalled && !host.hostComponents.someProperty('HostRoles.component_name', componentName)) {
+ var isClientSelected = clients.someProperty('component_name', componentName);
+ if (host.isInstalled && isClientSelected && !host.hostComponents.someProperty('HostRoles.component_name', componentName)) {
hostNames.pushObject(_clientHost.hostName);
}
}, this);
[25/38] ambari git commit: AMBARI-21307 Rest resource for supporting
ambari configurations
Posted by lp...@apache.org.
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/a02052d5
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a02052d5
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a02052d5
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: a02052d5d96344e68cf943764b1e93a056c91ecc
Parents: df3a66d
Author: lpuskas <lp...@apache.org>
Authored: Wed Jul 5 14:20:18 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:29 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/a02052d5/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 d0d115d..f5fb6e9 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/a02052d5/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/a02052d5/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 1cd2d10..1501a01 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
@@ -224,7 +224,7 @@ public abstract class AbstractProviderModule implements ProviderModule,
* are going to work unless refactoring is complete.
*/
@Inject
- AmbariManagementController managementController;
+ protected AmbariManagementController managementController;
@Inject
TimelineMetricCacheProvider metricCacheProvider;
http://git-wip-us.apache.org/repos/asf/ambari/blob/a02052d5/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/a02052d5/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/a02052d5/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/a02052d5/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/a02052d5/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/a02052d5/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/a02052d5/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/a02052d5/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 355ee80..8550c2b 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/a02052d5/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" />
[37/38] ambari git commit: AMBARI-21307 implemented user attribute
detection. Organized code
Posted by lp...@apache.org.
AMBARI-21307 implemented user attribute detection. Organized code
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7b91bc5b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7b91bc5b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7b91bc5b
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 7b91bc5b005493972ea4ad93b1752115414baed4
Parents: e4a80b1
Author: lpuskas <lp...@apache.org>
Authored: Tue Sep 12 08:10:47 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:32 2017 +0200
----------------------------------------------------------------------
.../services/ldap/LdapConfigurationService.java | 2 +-
.../server/ldap/AmbariLdapConfiguration.java | 9 ++
.../server/ldap/service/AmbariLdapFacade.java | 2 +-
.../server/ldap/service/AttributeDetector.java | 38 ++++++
.../service/LdapAttributeDetectionService.java | 7 +-
.../ambari/server/ldap/service/LdapFacade.java | 2 +-
.../server/ldap/service/LdapSearchService.java | 18 ---
.../ads/DefaultAttributeDetectionService.java | 132 ++++++++++++++++++-
.../ads/DefaultLdapConfigurationService.java | 2 +-
.../ldap/service/ads/ObjectClassDetector.java | 81 ++++++++++++
.../ads/OccurranceAndWeightBasedDetector.java | 81 ++++++++++++
.../service/ads/UserNameAttributeDetector.java | 75 +++++++++++
.../DefaultAttributeDetectionServiceTest.java | 35 ++---
13 files changed, 440 insertions(+), 44 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/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
index 1b8427b..66809c3 100644
--- 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
@@ -107,7 +107,7 @@ public class LdapConfigurationService extends AmbariConfigurationService {
case TEST_ATTRIBUTES:
LOGGER.info("Testing LDAP attributes ....");
- groups = ldapFacade.checkLdapAttibutes(ldapConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+ groups = ldapFacade.checkLdapAttributes(ldapConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
setResult(groups, result);
break;
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index 76faeed..e28c6ed 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -98,6 +98,10 @@ public class AmbariLdapConfiguration {
return value;
}
+ public void setValueFor(AmbariLdapConfig ambariLdapConfig, Object value) {
+ configurationMap.put(ambariLdapConfig.key(), value);
+ }
+
@Inject
public AmbariLdapConfiguration(@Assisted Map<String, Object> configuration) {
this.configurationMap = configuration;
@@ -219,4 +223,9 @@ public class AmbariLdapConfiguration {
return (String) configValue(AmbariLdapConfig.REFERRAL_HANDLING);
}
+
+ @Override
+ public String toString() {
+ return configurationMap.toString();
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index 16bf6b7..f159418 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -90,7 +90,7 @@ public class AmbariLdapFacade implements LdapFacade {
}
@Override
- public Set<String> checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
+ public Set<String> checkLdapAttributes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
String userName = getTestUserNameFromParameters(parameters);
String testUserPass = getTestUserPasswordFromParameters(parameters);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
new file mode 100644
index 0000000..3e20a6a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AttributeDetector.java
@@ -0,0 +1,38 @@
+/*
+ * 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.service;
+
+/**
+ * Operations for detecting LDAP related settings.
+ * Attributes and values are detected based on a sample set of results returned from a search
+ */
+public interface AttributeDetector<T> {
+
+ /**
+ * Collects potential attribute names or values from a set of result entries.
+ *
+ * @param entry a result entry returned by a search operation
+ */
+ void collect(T entry);
+
+ /**
+ * Implements the decision based on whiche the "best" possible attribute or value is selected.
+ *
+ * @return the most probable attribute name or value (based on the logic in the implementer)
+ */
+ String detect();
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
index 70a8977..4cfa81e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
@@ -15,12 +15,11 @@
package org.apache.ambari.server.ldap.service;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnection;
/**
* Contract defining operations to detect user and group attributes.
*/
-public interface LdapAttributeDetectionService {
+public interface LdapAttributeDetectionService<T> {
/**
* Decorates the passed in configuration with the detected ldap user attribute values
@@ -29,7 +28,7 @@ public interface LdapAttributeDetectionService {
* @param ambariLdapConfiguration configuration instance holding connection details
* @return the configuration decorated with user related attributes
*/
- AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+ AmbariLdapConfiguration detectLdapUserAttributes(T ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
/**
* Decorates the passed in configuration with the detected ldap group attribute values
@@ -38,6 +37,6 @@ public interface LdapAttributeDetectionService {
* @param ambariLdapConfiguration configuration instance holding connection details
* @return the configuration decorated with group related attributes
*/
- AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+ AmbariLdapConfiguration detectLdapGroupAttributes(T ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
index 76b16c4..7cd25da 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -48,5 +48,5 @@ public interface LdapFacade {
* @param ambariLdapConfiguration configutration instance with available attributes
* @throws AmbariLdapException if the attribute checking fails
*/
- Set<String> checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
+ Set<String> checkLdapAttributes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
deleted file mode 100644
index f1abc8b..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
+++ /dev/null
@@ -1,18 +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.service;
-
-public interface LdapSearchService {
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
index 55d0765..710adf1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
@@ -14,19 +14,47 @@
package org.apache.ambari.server.ldap.service.ads;
+import java.util.Set;
+
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.AttributeDetector;
import org.apache.ambari.server.ldap.service.LdapAttributeDetectionService;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchResultEntry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.api.util.Strings;
import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.Sets;
+
@Singleton
-public class DefaultAttributeDetectionService implements LdapAttributeDetectionService {
+public class DefaultAttributeDetectionService implements LdapAttributeDetectionService<LdapConnection> {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAttributeDetectionService.class);
+ private static final int SAMPLE_RESULT_SIZE = 50;
+
+ // ordered list of possible username attribute values (the most significant valus should be first)
+
+ private static final Set<String> USER_OBJECT_CLASS_VALUES = Sets.newHashSet("person", "posixAccount");
+ private static final Set<String> USER_GROUP_MEMBER_ATTR_VALUES = Sets.newHashSet("memberOf", "ismemberOf");
+
+ @Inject
+ private UserNameAttributeDetector userNameAttrDetector = new UserNameAttributeDetector(); // todo remove instantition
+
+ @Inject
+ private ObjectClassDetector objectClassDetector = new ObjectClassDetector(); // todo remove instantition
@Inject
public DefaultAttributeDetectionService() {
@@ -36,7 +64,72 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
public AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection connection, AmbariLdapConfiguration ambariLdapConfiguration) {
LOGGER.info("Detecting LDAP user attributes ...");
- return null;
+ // perform a search using the user search base
+ if (Strings.isEmpty(ambariLdapConfiguration.userSearchBase())) {
+ LOGGER.warn("No user search base provided");
+ return ambariLdapConfiguration;
+ }
+
+ SearchCursor searchCursor = null;
+
+ try {
+ // todo should the bind operation be done in the facade?
+ connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
+
+ SearchRequest searchRequest = assembleSearchRequest(ambariLdapConfiguration);
+
+ // do the search
+ searchCursor = connection.search(searchRequest);
+
+ int processedUserCnt = 0;
+
+ while (searchCursor.next()) {
+
+ if (processedUserCnt >= SAMPLE_RESULT_SIZE) {
+ LOGGER.debug("The maximum count of results for attribute detection has exceeded. Quit user attribute detection.");
+ break;
+ }
+
+ Response response = searchCursor.get();
+ // process the SearchResultEntry
+
+ if (response instanceof SearchResultEntry) {
+ Entry resultEntry = ((SearchResultEntry) response).getEntry();
+ LOGGER.info("Processing sample entry: [{}]", resultEntry.getDn());
+ userNameAttrDetector.collect(resultEntry);
+ objectClassDetector.collect(resultEntry);
+ processedUserCnt++;
+ }
+ }
+
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE, userNameAttrDetector.detect());
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, objectClassDetector.detect());
+
+ LOGGER.info("Decorated ambari ldap config : [{}]", ambariLdapConfiguration);
+
+ } catch (Exception e) {
+
+ LOGGER.error("Ldap operation failed", e);
+ } finally {
+ // housekeeping
+ if (null != searchCursor) {
+ searchCursor.close();
+ }
+ }
+
+ return ambariLdapConfiguration;
+ }
+
+ private void detectUserAttributes(Entry resultEntry, AttributeDetector attributeDetector) {
+
+ attributeDetector.collect(resultEntry);
+
+// Set<String> objectClasses = detectUserObjectClass(resultEntry);
+// if (!objectClasses.isEmpty()) {
+// ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, StringUtils.join(objectClasses, ","));
+// }
+
+
}
@Override
@@ -44,4 +137,39 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
LOGGER.info("Detecting LDAP group attributes ...");
return null;
}
+
+ private SearchRequest assembleSearchRequest(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ try {
+
+ SearchRequest req = new SearchRequestImpl();
+ req.setScope(SearchScope.SUBTREE);
+ req.addAttributes("*");
+ req.setTimeLimit(0);
+ req.setBase(new Dn(ambariLdapConfiguration.userSearchBase()));
+ // the filter must be set!
+ req.setFilter(FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString());
+
+ return req;
+
+ } catch (Exception e) {
+ LOGGER.error("Could not assemble ldap search request", e);
+ throw new AmbariLdapException(e);
+ }
+ }
+
+
+ private Set<String> detectUserObjectClass(Entry entry) {
+ LOGGER.info("Detecting user object class. Attributes: {}", entry.getAttributes());
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ private String detectGroupNameAttribute(Entry entry) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ private Set<String> detectGroupObjectClass(Entry entry) {
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
index db8c77f..fa2e44b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
@@ -190,7 +190,7 @@ public class DefaultLdapConfigurationService implements LdapConfigurationService
LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
} else {
- LOGGER.debug("Binding anonimously ...");
+ LOGGER.debug("Binding anonymously ...");
connection.bind();
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
new file mode 100644
index 0000000..2613517
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
@@ -0,0 +1,81 @@
+/*
+ * 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.service.ads;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class ObjectClassDetector extends OccurranceAndWeightBasedDetector {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(ObjectClassDetector.class);
+ private Map<String, Integer> occurranceMap = Maps.newHashMap();
+ private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+
+ private enum ObjectClassValue {
+ PERSON("person", 1),
+ POSIX_ACCOUNT("posixAccount", 1);
+
+ private String ocVal;
+ private Integer weight;
+
+ ObjectClassValue(String attr, Integer weght) {
+ this.ocVal = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String ocVal() {
+ return this.ocVal;
+ }
+
+ }
+
+ @Inject
+ public ObjectClassDetector() {
+ for (ObjectClassValue ocVal : ObjectClassValue.values()) {
+ occurranceMap.put(ocVal.ocVal(), 0);
+ weightsMap.put(ocVal.ocVal(), ocVal.weight());
+ }
+
+ }
+
+ @Override
+ protected Map<String, Integer> occurranceMap() {
+ return occurranceMap;
+ }
+
+ @Override
+ protected Map<String, Integer> weightsMap() {
+ return weightsMap;
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ LOGGER.info("Checking for object class [{}] in entry [{}]", value, entry.getDn());
+ return entry.hasObjectClass(value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
new file mode 100644
index 0000000..32dc238
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
@@ -0,0 +1,81 @@
+/*
+ * 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.service.ads;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.service.AttributeDetector;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public abstract class OccurranceAndWeightBasedDetector implements AttributeDetector<Entry> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OccurranceAndWeightBasedDetector.class);
+
+ protected abstract Map<String, Integer> occurranceMap();
+
+ protected abstract Map<String, Integer> weightsMap();
+
+ protected abstract boolean applies(Entry entry, String value);
+
+ @Override
+ public String detect() {
+ Map.Entry<String, Integer> selectedEntry = null;
+
+ for (Map.Entry<String, Integer> entry : occurranceMap().entrySet()) {
+ if (selectedEntry == null) {
+
+ selectedEntry = entry;
+ LOGGER.info("Initial name attribute: {}", selectedEntry);
+ continue;
+
+ }
+
+ if (selectedEntry.getValue() < entry.getValue()) {
+
+ LOGGER.info("Changing potential name attribute from : [{}] to: [{}]", selectedEntry, entry);
+ selectedEntry = entry;
+
+ }
+ }
+ return selectedEntry.getKey();
+ }
+
+ @Override
+ public void collect(Entry entry) {
+ LOGGER.info("Detecting ldap attributes/values ...");
+
+ for (String attributeValue : occurranceMap().keySet()) {
+ if (applies(entry, attributeValue)) {
+
+ Integer cnt = occurranceMap().get(attributeValue).intValue();
+ if (weightsMap().containsKey(attributeValue)) {
+ cnt = cnt + weightsMap().get(attributeValue);
+ } else {
+ cnt = cnt + 1;
+ }
+ occurranceMap().put(attributeValue, cnt);
+
+ LOGGER.info("Collected potential name attr: {}, count: {}", attributeValue, cnt);
+
+ } else {
+ LOGGER.info("The result entry doesn't contain the attribute: [{}]", attributeValue);
+ }
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
new file mode 100644
index 0000000..bbb4b43
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
@@ -0,0 +1,75 @@
+/*
+ * 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.service.ads;
+
+import java.util.Map;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class UserNameAttributeDetector extends OccurranceAndWeightBasedDetector {
+ private static final Logger LOGGER = LoggerFactory.getLogger(UserNameAttributeDetector.class);
+
+ private Map<String, Integer> occurranceMap = Maps.newHashMap();
+ private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+ private enum NameAttrs {
+ SAM_ACCOUNT_NAME("sAMAccountName", 5),
+ UID("uid", 3),
+ CN("cn", 1);
+
+ private String attrName;
+ private Integer weight;
+
+ NameAttrs(String attr, Integer weght) {
+ this.attrName = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String attrName() {
+ return this.attrName;
+ }
+
+ }
+
+ public UserNameAttributeDetector() {
+ for (NameAttrs nameAttr : NameAttrs.values()) {
+ occurranceMap.put(nameAttr.attrName(), 0);
+ weightsMap.put(nameAttr.attrName(), nameAttr.weight());
+ }
+ }
+
+ protected Map<String, Integer> occurranceMap() {
+ return occurranceMap;
+ }
+
+ protected Map<String, Integer> weightsMap() {
+ return weightsMap;
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ LOGGER.info("Checking for attribute [{}] in entry [{}]", value, entry.getDn());
+ return entry.containsAttribute(value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7b91bc5b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
index 5b3ac20..5cddf1a 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
@@ -69,13 +69,31 @@ public class DefaultAttributeDetectionServiceTest {
}
+ @Test
+ public void functionalTest() throws Exception {
+ // GIVEN
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(getTestPropertiesMap());
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ // WHEN
+ AmbariLdapConfiguration config = attributeDetectionService.detectLdapUserAttributes(ldapConnection, ambariLdapConfiguration);
+
+ // THEN
+
+ ldapConnection.close();
+
+ }
+
private Map<String, Object> getTestPropertiesMap() {
Map<String, Object> ldapPropsMap = Maps.newHashMap();
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.ANONYMOUS_BIND.key(), "true");
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_HOST.key(), "ldap.forumsys.com");
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_PORT.key(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "cn=read-only-admin,dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_PASSWORD.key(), "password");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.DN_ATTRIBUTE.key(), SchemaConstants.CN_AT);
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(), SchemaConstants.PERSON_OC);
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(), SchemaConstants.UID_AT);
@@ -84,19 +102,4 @@ public class DefaultAttributeDetectionServiceTest {
return ldapPropsMap;
}
-
- @Test
- public void functionalTest() throws Exception {
- // GIVEN
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(getTestPropertiesMap());
- LdapConnectionService connectionService = new DefaultLdapConnectionService();
- LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
-
- // WHEN
- AmbariLdapConfiguration config = attributeDetectionService.detectLdapUserAttributes(ldapConnection, ambariLdapConfiguration);
-
- // THEN
-
- }
}
\ No newline at end of file
[35/38] ambari git commit: AMBARI-21307 renamed package,
minor corrections. Changed endpoint name
Posted by lp...@apache.org.
AMBARI-21307 renamed package, minor corrections. Changed endpoint name
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c87043c9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c87043c9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c87043c9
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: c87043c9befee2424dafb2a951580140441e89a8
Parents: a7757b2
Author: lpuskas <lp...@apache.org>
Authored: Mon Aug 14 13:21:07 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:31 2017 +0200
----------------------------------------------------------------------
.../services/AmbariConfigurationService.java | 2 +-
.../api/services/ldap/LdapRestService.java | 15 +-
.../server/ldap/AmbariLdapConfiguration.java | 5 +-
.../apache/ambari/server/ldap/LdapModule.java | 4 +-
...efaultLdapConfigurationValidatorService.java | 243 -------------------
.../ad/DefaultLdapConnectionService.java | 63 -----
...efaultLdapConfigurationValidatorService.java | 243 +++++++++++++++++++
.../ads/DefaultLdapConnectionService.java | 63 +++++
...ltLdapConfigurationValidatorServiceTest.java | 113 ---------
...ltLdapConfigurationValidatorServiceTest.java | 113 +++++++++
10 files changed, 435 insertions(+), 429 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/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 927e518..492509f 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
@@ -63,7 +63,7 @@ import io.swagger.annotations.ApiResponses;
* }
* </pre>
*/
-@Path("/configurations/")
+@Path("/ambariconfigs/")
@Api(value = "Ambari Configurations", description = "Endpoint for Ambari configuration related operations")
public class AmbariConfigurationService extends BaseService {
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
index 8578204..4e654dc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
@@ -34,6 +34,7 @@ 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;
@@ -70,8 +71,9 @@ public class LdapRestService extends BaseService {
@POST
@ApiIgnore // until documented
- @Path("/action") // todo this needs to be moved under the resource
+ @Path("/validate") // todo this needs to be moved under the resource
@Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
public Response validateConfiguration(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
Set<String> groups = Sets.newHashSet();
@@ -95,10 +97,7 @@ public class LdapRestService extends BaseService {
LOGGER.info("Testing LDAP attributes ....");
groups = ldapFacade.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
- // todo factor out the resource creation, design better the structure in the response
- Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
- resource.setProperty("groups", groups);
- result.getResultTree().addChild(resource, "payload");
+ setResult(groups, result);
break;
case "detect-attributes":
@@ -119,6 +118,12 @@ public class LdapRestService extends BaseService {
return Response.status(result.getStatus().getStatusCode()).entity(getResultSerializer().serialize(result)).build();
}
+ private void setResult(Set<String> groups, Result result) {
+ Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
+ resource.setProperty("groups", groups);
+ result.getResultTree().addChild(resource, "payload");
+ }
+
private void validateRequest(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
String errMsg;
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index 8ab587b..b1cbced 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -37,11 +37,12 @@ public class AmbariLdapConfiguration {
public enum LdapConfigProperty {
LDAP_CONFIGURED("ambari.ldap.configured"),
AUTOMATIC_ATTRIBUTE_DETECTION("ambari.ldap.automatic.attribute.detection"),
-
USE_SSL("ambari.ldap.usessl"),
LDAP_SERVER_HOST("ambari.ldap.server.host"),
LDAP_SERVER_PORT("ambari.ldap.server.port"),
- BASE_DN("ambari.ldap.base.dn"),
+ LDAP_TRUSTSTORE_TYPE("ambari.ldap.truststore.type"),
+ LDAP_TRUSTSTORE_PATH("ambari.ldap.truststore.path"),
+ BASE_DN("ambari.ldap.bind.dn"),
BIND_ANONIMOUSLY("ambari.ldap.bindanonymously"),
MANAGER_DN("ambari.ldap.managerdn"),
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/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 1b49159..a4ad2ee 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
@@ -18,8 +18,8 @@ package org.apache.ambari.server.ldap;
import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
import org.apache.ambari.server.ldap.service.LdapConnectionService;
import org.apache.ambari.server.ldap.service.LdapFacade;
-import org.apache.ambari.server.ldap.service.ad.DefaultLdapConfigurationValidatorService;
-import org.apache.ambari.server.ldap.service.ad.DefaultLdapConnectionService;
+import org.apache.ambari.server.ldap.service.ads.DefaultLdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.ads.DefaultLdapConnectionService;
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
deleted file mode 100644
index a8503ca..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
+++ /dev/null
@@ -1,243 +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.service.ad;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
-import org.apache.ambari.server.ldap.service.AmbariLdapException;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
-import org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.message.Response;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.search.FilterBuilder;
-import org.apache.directory.shared.ldap.constants.SchemaConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-/**
- * Implementation of the validation logic using the Apache Directory API.
- */
-@Singleton
-public class DefaultLdapConfigurationValidatorService implements LdapConfigurationValidatorService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
-
- @Inject
- private LdapConnectionService ldapConnectionService;
-
- /**
- * Facilitating the instantiation
- */
- @Inject
- public DefaultLdapConfigurationValidatorService() {
- }
-
- @Override
- public void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- try {
- bind(ambariLdapConfiguration, ldapConnection);
- } catch (LdapException e) {
- LOGGER.error("Could not connect to the LDAP server", e);
- throw new AmbariLdapException(e);
- }
- }
-
-
- /**
- * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
- * Attributes are considered correct if there is at least one entry found.
- *
- * Invalid attributes are signaled by throwing an exception.
- *
- * @param testUserName the test username
- * @param testPassword the test password
- * @param ambariLdapConfiguration configuration instance holding ldap configuration details
- * @return the DN of the test user
- * @throws AmbariException if the attributes are not valid or any errors occurs
- */
- @Override
- public String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- SearchCursor searchCursor = null;
- String userDn = null;
- try {
- LOGGER.info("Checking user attributes for user {} r ...", testUserName);
-
- // bind anonimously or with manager data
- bind(ambariLdapConfiguration, ldapConnection);
-
- // set up a filter based on the provided attributes
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), testUserName))
- .toString();
-
- LOGGER.info("Searching for the user: {} using the search filter: {}", testUserName, filter);
- EntryCursor entryCursor = ldapConnection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
-
- // collecting search result entries
- List<Entry> users = Lists.newArrayList();
- for (Entry entry : entryCursor) {
- users.add(entry);
- userDn = entry.getDn().getNormName();
- }
-
- // there should be at least one user found
- if (users.isEmpty()) {
- String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
- LOGGER.error(msg);
- throw new Exception(msg);
- }
-
- LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
-
- } catch (Exception e) {
-
- LOGGER.error("User attributes validation failed.", e);
- throw new AmbariLdapException(e.getMessage(), e);
-
- } finally {
- closeResources(ldapConnection, searchCursor);
- }
- return userDn;
- }
-
-
- @Override
- public Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- SearchCursor searchCursor = null;
- Set<Response> groupResponses = Sets.newHashSet();
-
- try {
- LOGGER.info("Checking group attributes for user dn {} ...", userDn);
-
- bind(ambariLdapConfiguration, ldapConnection);
-
- // set up a filter based on the provided attributes
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.groupObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.groupMemberAttribute(), userDn)
- ).toString();
-
- LOGGER.info("Searching for the groups the user dn: {} is member of using the search filter: {}", userDn, filter);
-
- // assemble a search request
- SearchRequest searchRequest = new SearchRequestImpl();
- searchRequest.setFilter(filter);
- searchRequest.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
- searchRequest.setScope(SearchScope.SUBTREE);
- searchRequest.addAttributes(ambariLdapConfiguration.groupMemberAttribute(), ambariLdapConfiguration.groupNameAttribute());
-
- // perform the search
- searchCursor = ldapConnection.search(searchRequest);
-
- for (Response response : searchCursor) {
- groupResponses.add(response);
- }
-
- } catch (Exception e) {
-
- LOGGER.error("User attributes validation failed.", e);
- throw new AmbariLdapException(e.getMessage(), e);
-
- } finally {
- closeResources(ldapConnection, searchCursor);
- }
-
- return processGroupResults(groupResponses, ambariLdapConfiguration);
- }
-
- /**
- * Binds to the LDAP server (anonimously or wit manager credentials)
- *
- * @param ambariLdapConfiguration configuration instance
- * @param connection connection instance
- * @throws LdapException if the bind operation fails
- */
- private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
- LOGGER.info("Connecting to LDAP ....");
- if (!ambariLdapConfiguration.bindAnonimously()) {
- LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
- connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
- } else {
- LOGGER.debug("Binding anonimously ...");
- connection.bind();
- }
-
- if (!connection.isConnected()) {
- LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
- throw new IllegalStateException("The connection to the LDAP server is not alive");
- }
- LOGGER.info("Connected to LDAP.");
- }
-
-
- /**
- * Extracts meaningful values from the search result.
- *
- * @param groupResponses the result entries returned by the search
- * @param ambariLdapConfiguration holds the keys of the meaningful attributes
- * @return a set with the group names the test user belongs to
- */
- private Set<String> processGroupResults(Set<Response> groupResponses, AmbariLdapConfiguration ambariLdapConfiguration) {
- Set<String> groupStrSet = Sets.newHashSet();
- for (Response response : groupResponses) {
- Entry entry = ((SearchResultEntryDecorator) response).getEntry();
- groupStrSet.add(entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString());
- }
-
- LOGGER.debug("Extracted group names from group search responses: {}", groupStrSet);
- return groupStrSet;
- }
-
- private void closeResources(LdapConnection connection, SearchCursor searchCursor) {
- LOGGER.debug("Housekeeping: closing the connection and the search cursor ...");
-
- if (null != searchCursor) {
- // this method is idempotent
- searchCursor.close();
- }
-
- if (null != connection) {
- try {
- connection.close();
- } catch (IOException e) {
- LOGGER.error("Exception occurred while closing the connection", e);
- }
- }
- }
-
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
deleted file mode 100644
index 25dc1f2..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
+++ /dev/null
@@ -1,63 +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.ldap.service.ad;
-
-import javax.inject.Singleton;
-
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@Singleton
-public class DefaultLdapConnectionService implements LdapConnectionService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConnectionService.class);
-
- @Override
- public LdapNetworkConnection createLdapConnection(AmbariLdapConfiguration ambariLdapConfiguration) {
- LOGGER.debug("Creating ldap connection instance from: {}", ambariLdapConfiguration);
- return new LdapNetworkConnection(getLdapConnectionConfig(ambariLdapConfiguration));
- }
-
- private LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration ambariAmbariLdapConfiguration) {
- LOGGER.debug("Creating a configuration instance based on the ambari configuration: {}", ambariAmbariLdapConfiguration);
-
- LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
- ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.ldapServerHost());
- ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
- ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
-
- // todo set the other values as required
- return ldapConnectionConfig;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java
new file mode 100644
index 0000000..040983a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java
@@ -0,0 +1,243 @@
+/*
+ * 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.service.ads;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Implementation of the validation logic using the Apache Directory API.
+ */
+@Singleton
+public class DefaultLdapConfigurationValidatorService implements LdapConfigurationValidatorService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
+
+ @Inject
+ private LdapConnectionService ldapConnectionService;
+
+ /**
+ * Facilitating the instantiation
+ */
+ @Inject
+ public DefaultLdapConfigurationValidatorService() {
+ }
+
+ @Override
+ public void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ try {
+ bind(ambariLdapConfiguration, ldapConnection);
+ } catch (LdapException e) {
+ LOGGER.error("Could not connect to the LDAP server", e);
+ throw new AmbariLdapException(e);
+ }
+ }
+
+
+ /**
+ * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
+ * Attributes are considered correct if there is at least one entry found.
+ *
+ * Invalid attributes are signaled by throwing an exception.
+ *
+ * @param testUserName the test username
+ * @param testPassword the test password
+ * @param ambariLdapConfiguration configuration instance holding ldap configuration details
+ * @return the DN of the test user
+ * @throws AmbariException if the attributes are not valid or any errors occurs
+ */
+ @Override
+ public String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ SearchCursor searchCursor = null;
+ String userDn = null;
+ try {
+ LOGGER.info("Checking user attributes for user {} r ...", testUserName);
+
+ // bind anonimously or with manager data
+ bind(ambariLdapConfiguration, ldapConnection);
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), testUserName))
+ .toString();
+
+ LOGGER.info("Searching for the user: {} using the search filter: {}", testUserName, filter);
+ EntryCursor entryCursor = ldapConnection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
+
+ // collecting search result entries
+ List<Entry> users = Lists.newArrayList();
+ for (Entry entry : entryCursor) {
+ users.add(entry);
+ userDn = entry.getDn().getNormName();
+ }
+
+ // there should be at least one user found
+ if (users.isEmpty()) {
+ String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
+ LOGGER.error(msg);
+ throw new Exception(msg);
+ }
+
+ LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
+
+ } catch (Exception e) {
+
+ LOGGER.error("User attributes validation failed.", e);
+ throw new AmbariLdapException(e.getMessage(), e);
+
+ } finally {
+ closeResources(ldapConnection, searchCursor);
+ }
+ return userDn;
+ }
+
+
+ @Override
+ public Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ SearchCursor searchCursor = null;
+ Set<Response> groupResponses = Sets.newHashSet();
+
+ try {
+ LOGGER.info("Checking group attributes for user dn {} ...", userDn);
+
+ bind(ambariLdapConfiguration, ldapConnection);
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.groupObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.groupMemberAttribute(), userDn)
+ ).toString();
+
+ LOGGER.info("Searching for the groups the user dn: {} is member of using the search filter: {}", userDn, filter);
+
+ // assemble a search request
+ SearchRequest searchRequest = new SearchRequestImpl();
+ searchRequest.setFilter(filter);
+ searchRequest.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
+ searchRequest.setScope(SearchScope.SUBTREE);
+ searchRequest.addAttributes(ambariLdapConfiguration.groupMemberAttribute(), ambariLdapConfiguration.groupNameAttribute());
+
+ // perform the search
+ searchCursor = ldapConnection.search(searchRequest);
+
+ for (Response response : searchCursor) {
+ groupResponses.add(response);
+ }
+
+ } catch (Exception e) {
+
+ LOGGER.error("User attributes validation failed.", e);
+ throw new AmbariLdapException(e.getMessage(), e);
+
+ } finally {
+ closeResources(ldapConnection, searchCursor);
+ }
+
+ return processGroupResults(groupResponses, ambariLdapConfiguration);
+ }
+
+ /**
+ * Binds to the LDAP server (anonimously or wit manager credentials)
+ *
+ * @param ambariLdapConfiguration configuration instance
+ * @param connection connection instance
+ * @throws LdapException if the bind operation fails
+ */
+ private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
+ LOGGER.info("Connecting to LDAP ....");
+ if (!ambariLdapConfiguration.bindAnonimously()) {
+ LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
+ connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
+ } else {
+ LOGGER.debug("Binding anonimously ...");
+ connection.bind();
+ }
+
+ if (!connection.isConnected()) {
+ LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
+ throw new IllegalStateException("The connection to the LDAP server is not alive");
+ }
+ LOGGER.info("Connected to LDAP.");
+ }
+
+
+ /**
+ * Extracts meaningful values from the search result.
+ *
+ * @param groupResponses the result entries returned by the search
+ * @param ambariLdapConfiguration holds the keys of the meaningful attributes
+ * @return a set with the group names the test user belongs to
+ */
+ private Set<String> processGroupResults(Set<Response> groupResponses, AmbariLdapConfiguration ambariLdapConfiguration) {
+ Set<String> groupStrSet = Sets.newHashSet();
+ for (Response response : groupResponses) {
+ Entry entry = ((SearchResultEntryDecorator) response).getEntry();
+ groupStrSet.add(entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString());
+ }
+
+ LOGGER.debug("Extracted group names from group search responses: {}", groupStrSet);
+ return groupStrSet;
+ }
+
+ private void closeResources(LdapConnection connection, SearchCursor searchCursor) {
+ LOGGER.debug("Housekeeping: closing the connection and the search cursor ...");
+
+ if (null != searchCursor) {
+ // this method is idempotent
+ searchCursor.close();
+ }
+
+ if (null != connection) {
+ try {
+ connection.close();
+ } catch (IOException e) {
+ LOGGER.error("Exception occurred while closing the connection", e);
+ }
+ }
+ }
+
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
new file mode 100644
index 0000000..ced52fc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ldap.service.ads;
+
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class DefaultLdapConnectionService implements LdapConnectionService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConnectionService.class);
+
+ @Override
+ public LdapNetworkConnection createLdapConnection(AmbariLdapConfiguration ambariLdapConfiguration) {
+ LOGGER.debug("Creating ldap connection instance from: {}", ambariLdapConfiguration);
+ return new LdapNetworkConnection(getLdapConnectionConfig(ambariLdapConfiguration));
+ }
+
+ private LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration ambariAmbariLdapConfiguration) {
+ LOGGER.debug("Creating a configuration instance based on the ambari configuration: {}", ambariAmbariLdapConfiguration);
+
+ LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
+ ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.ldapServerHost());
+ ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
+ ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
+
+ // todo set the other values as required
+ return ldapConnectionConfig;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
deleted file mode 100644
index 663ea12..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
+++ /dev/null
@@ -1,113 +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.service.ad;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.util.Map;
-
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.apache.directory.shared.ldap.constants.SchemaConstants;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-public class DefaultLdapConfigurationValidatorServiceTest {
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
- private static final String TEST_USER = "einstein";
-
- LdapConfigurationValidatorService ldapConfigurationValidatorService = new DefaultLdapConfigurationValidatorService();
-
-
- @Test
- public void testCheckAttributes() throws Exception {
-
- // WHEN
- LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost("localhost");
- config.setLdapPort(389);
- LdapConnection connection = new LdapNetworkConnection(config);
-
- // THEN
- connection.anonymousBind();
-
-
- EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
-
- for (Entry entry : cursor) {
- assertNotNull(entry);
- System.out.println(entry);
- }
-
- cursor.close();
-
- }
-
- @Test
- public void testCheckUserAttributes() throws Exception {
- // GIVEN
- Map<String, Object> ldapPropsMap = Maps.newHashMap();
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_SEARCH_BASE.propertyName(), "dc=example,dc=com");
-
-
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
- LdapConnectionService connectionService = new DefaultLdapConnectionService();
- LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
- ldapConfigurationValidatorService.checkUserAttributes(ldapConnection, "einstein", "", ambariLdapConfiguration);
- }
-
- @Test
- public void testRetrieveGorupsForuser() throws Exception {
- // GIVEN
- Map<String, Object> ldapPropsMap = Maps.newHashMap();
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
-
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_SEARCH_BASE.propertyName(), "dc=example,dc=com");
-
-
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
- LdapConnectionService connectionService = new DefaultLdapConnectionService();
- LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
- ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, "uid=einstein,dc=example,dc=com", ambariLdapConfiguration);
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/c87043c9/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java
new file mode 100644
index 0000000..1c7f75d
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.service.ads;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class DefaultLdapConfigurationValidatorServiceTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
+ private static final String TEST_USER = "einstein";
+
+ LdapConfigurationValidatorService ldapConfigurationValidatorService = new DefaultLdapConfigurationValidatorService();
+
+
+ @Test
+ public void testCheckAttributes() throws Exception {
+
+ // WHEN
+ LdapConnectionConfig config = new LdapConnectionConfig();
+ config.setLdapHost("localhost");
+ config.setLdapPort(389);
+ LdapConnection connection = new LdapNetworkConnection(config);
+
+ // THEN
+ connection.anonymousBind();
+
+
+ EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
+
+ for (Entry entry : cursor) {
+ assertNotNull(entry);
+ System.out.println(entry);
+ }
+
+ cursor.close();
+
+ }
+
+ @Test
+ public void testCheckUserAttributes() throws Exception {
+ // GIVEN
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ ldapConfigurationValidatorService.checkUserAttributes(ldapConnection, "einstein", "", ambariLdapConfiguration);
+ }
+
+ @Test
+ public void testRetrieveGorupsForuser() throws Exception {
+ // GIVEN
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, "uid=einstein,dc=example,dc=com", ambariLdapConfiguration);
+ }
+}
\ No newline at end of file
[12/38] ambari git commit: AMBARI-21893 : NameNode Heap Usage (Daily)
metric alert status flips to UNKNOWN intermittently when AMS HTTPS is
enabled. (Addendum patch) (avijayan)
Posted by lp...@apache.org.
AMBARI-21893 : NameNode Heap Usage (Daily) metric alert status flips to UNKNOWN intermittently when AMS HTTPS is enabled. (Addendum patch) (avijayan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4f6ef91f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4f6ef91f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4f6ef91f
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 4f6ef91f33cefeea97629dd4dc45ec993b27b4f6
Parents: a49121b
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Tue Sep 12 19:54:01 2017 -0700
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Tue Sep 12 19:54:01 2017 -0700
----------------------------------------------------------------------
.../AMBARI_METRICS/0.1.0/package/scripts/ams.py | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/4f6ef91f/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
index 51e0756..c72e2f0 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
@@ -515,12 +515,11 @@ def export_ca_certs(dir_path):
truststore_p12 = os.path.join(tmpdir,'truststore.p12')
if (params.metric_truststore_type.lower() == 'jks'):
- if not params.metric_truststore_alias:
- for alias in params.metric_truststore_alias_list:
- # Convert truststore from JKS to PKCS12
- cmd = format("{sudo} {java64_home}/bin/keytool -importkeystore -srckeystore {metric_truststore_path} -destkeystore {truststore_p12} -srcalias " + alias + " -deststoretype PKCS12 -srcstorepass {metric_truststore_password} -deststorepass {metric_truststore_password}")
- Execute(cmd,
- )
+ for alias in params.metric_truststore_alias_list:
+ # Convert truststore from JKS to PKCS12
+ cmd = format("{sudo} {java64_home}/bin/keytool -importkeystore -srckeystore {metric_truststore_path} -destkeystore {truststore_p12} -srcalias " + alias + " -deststoretype PKCS12 -srcstorepass {metric_truststore_password} -deststorepass {metric_truststore_password}")
+ Execute(cmd,
+ )
truststore = truststore_p12
# Export all CA certificates from the truststore to the conf directory
[07/38] ambari git commit: AMBARI-21936. Do not export YARN_CONF_DIR
in "yarn-env.sh" file.(vbrodetskyi)
Posted by lp...@apache.org.
AMBARI-21936. Do not export YARN_CONF_DIR in "yarn-env.sh" file.(vbrodetskyi)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/aaf6f0ae
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/aaf6f0ae
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/aaf6f0ae
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: aaf6f0ae0f69ed80c1f8ec9ffaf81cf3a358900a
Parents: 321f9cf
Author: Vitaly Brodetskyi <vb...@hortonworks.com>
Authored: Tue Sep 12 20:31:56 2017 +0300
Committer: Vitaly Brodetskyi <vb...@hortonworks.com>
Committed: Tue Sep 12 20:31:56 2017 +0300
----------------------------------------------------------------------
.../common-services/YARN/3.0.0.3.0/configuration/yarn-env.xml | 3 ---
1 file changed, 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/aaf6f0ae/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration/yarn-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration/yarn-env.xml b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration/yarn-env.xml
index aaa72d1..4e722ee 100644
--- a/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration/yarn-env.xml
+++ b/ambari-server/src/main/resources/common-services/YARN/3.0.0.3.0/configuration/yarn-env.xml
@@ -179,9 +179,6 @@ fi
# User for YARN daemons
export HADOOP_YARN_USER=${HADOOP_YARN_USER:-yarn}
-# resolve links - $0 may be a softlink
-export YARN_CONF_DIR="${YARN_CONF_DIR:-$HADOOP_YARN_HOME/conf}"
-
# some Java parameters
# export JAVA_HOME=/home/y/libexec/jdk1.6.0/
if [ "$JAVA_HOME" != "" ]; then
[31/38] ambari git commit: AMBARI-21307 LDAP config rest service
implementation extends the ambari config rest implementaiton
Posted by lp...@apache.org.
AMBARI-21307 LDAP config rest service implementation extends the ambari config rest implementaiton
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e459461f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e459461f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e459461f
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: e459461f2c9fc7fe1600f3441d7eab870a278b0b
Parents: c87043c
Author: lpuskas <lp...@apache.org>
Authored: Mon Aug 21 15:53:45 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:31 2017 +0200
----------------------------------------------------------------------
.../services/ldap/LdapConfigurationService.java | 208 +++++++++++++++++++
.../api/services/ldap/LdapRestService.java | 149 -------------
2 files changed, 208 insertions(+), 149 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e459461f/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
new file mode 100644
index 0000000..52244bc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationService.java
@@ -0,0 +1,208 @@
+/*
+ * 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.AmbariConfigurationService;
+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.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationFactory;
+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 AmbariConfigurationService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LdapConfigurationService.class);
+
+ @Inject
+ private static LdapFacade ldapFacade;
+
+ @Inject
+ private static LdapConfigurationFactory ldapConfigurationFactory;
+
+ /**
+ * Actions supported by this endpoint
+ */
+ private enum LdapAction {
+ TEST_CONNECTION("test-connection"),
+ TEST_ATTRIBUTES("test-attributes"),
+ DETECT_ATTRIBUTES("detect-attributes");
+
+ private String actionStr;
+
+ LdapAction(String actionStr) {
+ this.actionStr = actionStr;
+ }
+
+ public static LdapAction fromAction(String action) {
+ for (LdapAction val : LdapAction.values()) {
+ if (val.action().equals(action)) {
+ return val;
+ }
+ }
+ throw new IllegalStateException("Action [ " + action + " ] is not supported");
+ }
+
+ public String action() {
+ return this.actionStr;
+ }
+ }
+
+ @POST
+ @ApiIgnore // until documented
+ @Path("/validate")
+ @Consumes(MediaType.APPLICATION_JSON)
+ @Produces(MediaType.APPLICATION_JSON)
+ public Response validateConfiguration(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+
+ authorize();
+
+ Set<String> groups = Sets.newHashSet();
+
+ Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
+ try {
+
+ validateRequest(ldapCheckConfigurationRequest);
+
+ AmbariLdapConfiguration ambariLdapConfiguration = ldapConfigurationFactory.createLdapConfiguration(
+ ldapCheckConfigurationRequest.getAmbariConfiguration().getData().iterator().next());
+
+ LdapAction action = LdapAction.fromAction(ldapCheckConfigurationRequest.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.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+ setResult(groups, result);
+
+ break;
+ case DETECT_ATTRIBUTES:
+
+ LOGGER.info("Detecting LDAP attributes ...");
+ ldapFacade.detectAttributes(ambariLdapConfiguration);
+
+ break;
+ default:
+ LOGGER.warn("No action provided ...");
+ throw new IllegalArgumentException("No request action provided");
+ }
+
+ } catch (Exception e) {
+ result.setResultStatus(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
+ }
+
+ return Response.status(result.getStatus().getStatusCode()).entity(getResultSerializer().serialize(result)).build();
+ }
+
+ private void setResult(Set<String> groups, Result result) {
+ Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
+ resource.setProperty("groups", groups);
+ result.getResultTree().addChild(resource, "payload");
+ }
+
+ private void validateRequest(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+ String errMsg;
+
+ if (null == ldapCheckConfigurationRequest) {
+ errMsg = "No ldap configuraiton request provided";
+ LOGGER.error(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ if (null == ldapCheckConfigurationRequest.getRequestInfo()) {
+ errMsg = String.format("No request information provided. Request: [%s]", ldapCheckConfigurationRequest);
+ LOGGER.error(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ if (null == ldapCheckConfigurationRequest.getAmbariConfiguration()
+ || ldapCheckConfigurationRequest.getAmbariConfiguration().getData().size() != 1) {
+ errMsg = String.format("No / Invalid configuration data provided. Request: [%s]", ldapCheckConfigurationRequest);
+ 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);
+ }
+
+ }
+
+ Set<RoleAuthorization> requiredAuthorizations() {
+ return Sets.newHashSet(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e459461f/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
deleted file mode 100644
index 4e654dc..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
+++ /dev/null
@@ -1,149 +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.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationFactory;
-import org.apache.ambari.server.ldap.service.LdapFacade;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Sets;
-
-/**
- * Endpoint designated to LDAP specific operations.
- */
-@StaticallyInject
-@Path("/ldap")
-public class LdapRestService extends BaseService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(LdapRestService.class);
-
- @Inject
- private static LdapFacade ldapFacade;
-
- @Inject
- private static LdapConfigurationFactory ldapConfigurationFactory;
-
- @POST
- @ApiIgnore // until documented
- @Path("/validate") // todo this needs to be moved under the resource
- @Consumes(MediaType.APPLICATION_JSON)
- @Produces(MediaType.APPLICATION_JSON)
- public Response validateConfiguration(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
-
- Set<String> groups = Sets.newHashSet();
-
- Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
- try {
-
- validateRequest(ldapCheckConfigurationRequest);
-
- AmbariLdapConfiguration ambariLdapConfiguration = ldapConfigurationFactory.createLdapConfiguration(
- ldapCheckConfigurationRequest.getAmbariConfiguration().getData().iterator().next());
-
- switch (ldapCheckConfigurationRequest.getRequestInfo().getAction()) {
- 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.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
- setResult(groups, result);
-
- break;
- case "detect-attributes":
-
- LOGGER.info("Detecting LDAP attributes ...");
- ldapFacade.detectAttributes(ambariLdapConfiguration);
-
- break;
- default:
- LOGGER.warn("No action provided ...");
- throw new IllegalArgumentException("No request action provided");
- }
-
- } catch (Exception e) {
- result.setResultStatus(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
- }
-
- return Response.status(result.getStatus().getStatusCode()).entity(getResultSerializer().serialize(result)).build();
- }
-
- private void setResult(Set<String> groups, Result result) {
- Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
- resource.setProperty("groups", groups);
- result.getResultTree().addChild(resource, "payload");
- }
-
- private void validateRequest(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
- String errMsg;
-
- if (null == ldapCheckConfigurationRequest) {
- errMsg = "No ldap configuraiton request provided";
- LOGGER.error(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
-
- if (null == ldapCheckConfigurationRequest.getRequestInfo()) {
- errMsg = String.format("No request information provided. Request: [%s]", ldapCheckConfigurationRequest);
- LOGGER.error(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
-
- if (null == ldapCheckConfigurationRequest.getAmbariConfiguration()
- || ldapCheckConfigurationRequest.getAmbariConfiguration().getData().size() != 1) {
- errMsg = String.format("No / Invalid configuration data provided. Request: [%s]", ldapCheckConfigurationRequest);
- LOGGER.error(errMsg);
- throw new IllegalArgumentException(errMsg);
- }
- }
-}
[06/38] ambari git commit: AMBARI-21931 - Use Correct Packages For
Clients Where Stack Tools Support It (jonathanhurley)
Posted by lp...@apache.org.
AMBARI-21931 - Use Correct Packages For Clients Where Stack Tools Support It (jonathanhurley)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/321f9cfe
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/321f9cfe
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/321f9cfe
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 321f9cfeb42006ce309d09dbd7af1e6601c90ba5
Parents: 5113e99
Author: Jonathan Hurley <jh...@hortonworks.com>
Authored: Mon Sep 11 15:41:22 2017 -0400
Committer: Jonathan Hurley <jh...@hortonworks.com>
Committed: Tue Sep 12 12:29:31 2017 -0400
----------------------------------------------------------------------
.../libraries/functions/stack_select.py | 65 ++++++++++++++++++-
.../ambari/server/topology/AmbariContext.java | 2 +-
.../HDP/2.0.6/properties/stack_packages.json | 66 +++++++++++++------
.../HDP/3.0/properties/stack_packages.json | 48 ++++++++------
.../src/test/python/TestStackSelect.py | 67 ++++++++++++++++++--
.../src/test/python/stacks/utils/RMFTestCase.py | 30 +++++----
6 files changed, 222 insertions(+), 56 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/321f9cfe/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
index 1657c23..e506974 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_select.py
@@ -33,6 +33,7 @@ from resource_management.libraries.functions.get_stack_version import get_stack_
from resource_management.libraries.functions.format import format
from resource_management.libraries.script.script import Script
from resource_management.libraries.functions import stack_tools
+from resource_management.core import shell
from resource_management.core.shell import call
from resource_management.libraries.functions.version import format_stack_version
from resource_management.libraries.functions.version_select_util import get_versions_from_stack_root
@@ -75,6 +76,11 @@ PACKAGE_SCOPE_INSTALL = "INSTALL"
PACKAGE_SCOPE_STANDARD = "STANDARD"
PACKAGE_SCOPE_PATCH = "PATCH"
PACKAGE_SCOPE_STACK_SELECT = "STACK-SELECT-PACKAGE"
+
+# the legacy key is used when a package has changed from one version of the stack select tool to another.
+_PACKAGE_SCOPE_LEGACY = "LEGACY"
+
+# the valid scopes which can be requested
_PACKAGE_SCOPES = (PACKAGE_SCOPE_INSTALL, PACKAGE_SCOPE_STANDARD, PACKAGE_SCOPE_PATCH, PACKAGE_SCOPE_STACK_SELECT)
# the orchestration types which equal to a partial (non-STANDARD) upgrade
@@ -110,6 +116,37 @@ def get_package_name(default_package = None):
raise
+def is_package_supported(package, supported_packages = None):
+ """
+ Gets whether the specified package is supported by the <stack_select> tool.
+ :param package: the package to check
+ :param supported_packages: the list of supported packages pre-fetched
+ :return: True if the package is support, False otherwise
+ """
+ if supported_packages is None:
+ supported_packages = get_supported_packages()
+
+ if package in supported_packages:
+ return True
+
+ return False
+
+
+def get_supported_packages():
+ """
+ Parses the output from <stack-select> packages and returns an array of the various packages.
+ :return: and array of packages support by <stack-select>
+ """
+ stack_selector_path = stack_tools.get_stack_tool_path(stack_tools.STACK_SELECTOR_NAME)
+ command = (STACK_SELECT_PREFIX, stack_selector_path, "packages")
+ code, stdout = shell.call(command, sudo = True, quiet = True)
+
+ if code != 0 or stdout is None:
+ raise Fail("Unable to query for supported packages using {0}".format(stack_selector_path))
+
+ # turn the output into lines, stripping each line
+ return [line.strip() for line in stdout.splitlines()]
+
def get_packages(scope, service_name = None, component_name = None):
"""
@@ -172,7 +209,33 @@ def get_packages(scope, service_name = None, component_name = None):
Logger.info("Skipping stack-select on {0} because it does not exist in the stack-select package structure.".format(component_name))
return None
- return data[component_name][scope]
+ # this one scope is not an array, so transform it into one for now so we can
+ # use the same code below
+ packages = data[component_name][scope]
+ if scope == PACKAGE_SCOPE_STACK_SELECT:
+ packages = [packages]
+
+ # grab the package name from the JSON and validate it against the packages
+ # that the stack-select tool supports - if it doesn't support it, then try to find the legacy
+ # package name if it exists
+ supported_packages = get_supported_packages()
+ for index, package in enumerate(packages):
+ if not is_package_supported(package, supported_packages=supported_packages):
+ if _PACKAGE_SCOPE_LEGACY in data[component_name]:
+ legacy_package = data[component_name][_PACKAGE_SCOPE_LEGACY]
+ Logger.info(
+ "The package {0} is not supported by this version of the stack-select tool, defaulting to the legacy package of {1}".format(package, legacy_package))
+
+ # use the legacy package
+ packages[index] = legacy_package
+ else:
+ raise Fail("The package {0} is not supported by this version of the stack-select tool.".format(package))
+
+ # transform the array bcak to a single element
+ if scope == PACKAGE_SCOPE_STACK_SELECT:
+ packages = packages[0]
+
+ return packages
def select_all(version_to_select):
http://git-wip-us.apache.org/repos/asf/ambari/blob/321f9cfe/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
index 1556b0d..eb39562 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/topology/AmbariContext.java
@@ -206,7 +206,7 @@ public class AmbariContext {
StackId stackId = new StackId(stack.getName(), stack.getVersion());
RepositoryVersionEntity repoVersion = null;
- if (null == repoVersionString && null == repoVersionId) {
+ if (StringUtils.isEmpty(repoVersionString) && null == repoVersionId) {
List<RepositoryVersionEntity> stackRepoVersions = repositoryVersionDAO.findByStack(stackId);
if (stackRepoVersions.isEmpty()) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/321f9cfe/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
index 704fb54..ec35f2b 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/properties/stack_packages.json
@@ -298,12 +298,13 @@
]
},
"HDFS_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hadoop-hdfs-client",
+ "LEGACY": "hadoop-client",
"INSTALL": [
- "hadoop-client"
+ "hadoop-hdfs-client"
],
"PATCH": [
- "INVALID"
+ "hadoop-hdfs-client"
],
"STANDARD": [
"hadoop-client"
@@ -420,12 +421,13 @@
]
},
"HIVE_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hive-client",
+ "LEGACY": "hadoop-client",
"INSTALL": [
- "hadoop-client"
+ "hive-client"
],
"PATCH": [
- "INVALID"
+ "hive-client"
],
"STANDARD": [
"hadoop-client"
@@ -500,12 +502,13 @@
]
},
"MAPREDUCE2_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hadoop-mapreduce-client",
+ "LEGACY": "hadoop-client",
"INSTALL": [
- "hadoop-client"
+ "hadoop-mapreduce-client"
],
"PATCH": [
- "hadoop-mapreduce-INVALID"
+ "hadoop-mapreduce-client"
],
"STANDARD": [
"hadoop-client"
@@ -542,12 +545,13 @@
},
"PIG": {
"PIG": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "pig-client",
+ "LEGACY": "hadoop-client",
"INSTALL": [
- "hadoop-client"
+ "pig-client"
],
"PATCH": [
- "INVALID"
+ "pig-client"
],
"STANDARD": [
"hadoop-client"
@@ -636,6 +640,18 @@
}
},
"SPARK": {
+ "LIVY_CLIENT": {
+ "STACK-SELECT-PACKAGE": "livy-client",
+ "INSTALL": [
+ "livy-client"
+ ],
+ "PATCH": [
+ "livy-client"
+ ],
+ "STANDARD": [
+ "livy-client"
+ ]
+ },
"LIVY_SERVER": {
"STACK-SELECT-PACKAGE": "livy-server",
"INSTALL": [
@@ -686,6 +702,18 @@
}
},
"SPARK2": {
+ "LIVY2_CLIENT": {
+ "STACK-SELECT-PACKAGE": "livy2-client",
+ "INSTALL": [
+ "livy2-client"
+ ],
+ "PATCH": [
+ "livy2-client"
+ ],
+ "STANDARD": [
+ "livy2-client"
+ ]
+ },
"LIVY2_SERVER": {
"STACK-SELECT-PACKAGE": "livy2-server",
"INSTALL": [
@@ -819,12 +847,13 @@
},
"TEZ": {
"TEZ_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "tez-client",
+ "LEGACY": "hadoop-client",
"INSTALL": [
- "hadoop-client"
+ "tez-client"
],
"PATCH": [
- "INVALID"
+ "tez-client"
],
"STANDARD": [
"hadoop-client"
@@ -895,12 +924,13 @@
]
},
"YARN_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hadoop-yarn-client",
+ "LEGACY": "hadoop-client",
"INSTALL": [
- "hadoop-client"
+ "hadoop-yarn-client"
],
"PATCH": [
- "INVALID"
+ "hadoop-yarn-client"
],
"STANDARD": [
"hadoop-client"
http://git-wip-us.apache.org/repos/asf/ambari/blob/321f9cfe/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
index 0ef41a6..9012e92 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/properties/stack_packages.json
@@ -298,12 +298,12 @@
]
},
"HDFS_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hadoop-hdfs-client",
"INSTALL": [
- "hadoop-client"
+ "hadoop-hdfs-client"
],
"PATCH": [
- "INVALID"
+ "hadoop-hdfs-client"
],
"STANDARD": [
"hadoop-client"
@@ -420,12 +420,12 @@
]
},
"HIVE_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hive-client",
"INSTALL": [
- "hadoop-client"
+ "hive-client"
],
"PATCH": [
- "INVALID"
+ "hive-client"
],
"STANDARD": [
"hadoop-client"
@@ -500,12 +500,12 @@
]
},
"MAPREDUCE2_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hadoop-mapreduce-client",
"INSTALL": [
- "hadoop-client"
+ "hadoop-mapreduce-client"
],
"PATCH": [
- "hadoop-mapreduce-INVALID"
+ "hadoop-mapreduce-client"
],
"STANDARD": [
"hadoop-client"
@@ -542,12 +542,12 @@
},
"PIG": {
"PIG": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "pig-client",
"INSTALL": [
- "hadoop-client"
+ "pig-client"
],
"PATCH": [
- "INVALID"
+ "pig-client"
],
"STANDARD": [
"hadoop-client"
@@ -622,6 +622,18 @@
}
},
"SPARK": {
+ "LIVY_CLIENT": {
+ "STACK-SELECT-PACKAGE": "livy2-client",
+ "INSTALL": [
+ "livy2-client"
+ ],
+ "PATCH": [
+ "livy2-client"
+ ],
+ "STANDARD": [
+ "livy2-client"
+ ]
+ },
"LIVY_SERVER": {
"STACK-SELECT-PACKAGE": "livy2-server",
"INSTALL": [
@@ -741,12 +753,12 @@
},
"TEZ": {
"TEZ_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "tez-client",
"INSTALL": [
- "hadoop-client"
+ "tez-client"
],
"PATCH": [
- "INVALID"
+ "tez-client"
],
"STANDARD": [
"hadoop-client"
@@ -791,12 +803,12 @@
]
},
"YARN_CLIENT": {
- "STACK-SELECT-PACKAGE": "hadoop-client",
+ "STACK-SELECT-PACKAGE": "hadoop-yarn-client",
"INSTALL": [
- "hadoop-client"
+ "hadoop-yarn-client"
],
"PATCH": [
- "INVALID"
+ "hadoop-yarn-client"
],
"STANDARD": [
"hadoop-client"
http://git-wip-us.apache.org/repos/asf/ambari/blob/321f9cfe/ambari-server/src/test/python/TestStackSelect.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/TestStackSelect.py b/ambari-server/src/test/python/TestStackSelect.py
index 3d4e5b6..8cd8f2f 100644
--- a/ambari-server/src/test/python/TestStackSelect.py
+++ b/ambari-server/src/test/python/TestStackSelect.py
@@ -19,6 +19,7 @@ limitations under the License.
'''
from mock.mock import patch
+from mock.mock import MagicMock
from resource_management.core.logger import Logger
from resource_management.core.exceptions import Fail
@@ -43,13 +44,15 @@ class TestStackSelect(TestCase):
self.assertRaises(Fail, stack_select.select_packages, version)
-
+ @patch.object(stack_select, "get_supported_packages")
@patch("resource_management.libraries.functions.stack_select.select")
- def test_select_package_for_standard_orchestration(self, stack_select_select_mock):
+ def test_select_package_for_standard_orchestration(self, stack_select_select_mock, get_supported_packages_mock):
"""
Tests that missing the service & role throws an excpetion
:return:
"""
+ get_supported_packages_mock.return_value = TestStackSelect._get_supported_packages()
+
version = "2.5.9.9-9999"
command_json = TestStackSelect._get_cluster_simple_upgrade_json()
@@ -66,13 +69,15 @@ class TestStackSelect(TestCase):
self.assertEqual(stack_select_select_mock.call_args_list[0][0], ("foo-master", version))
self.assertEqual(stack_select_select_mock.call_args_list[1][0], ("foo-client", version))
-
+ @patch.object(stack_select, "get_supported_packages")
@patch("resource_management.libraries.functions.stack_select.select")
- def test_select_package_for_patch_orchestration(self, stack_select_select_mock):
+ def test_select_package_for_patch_orchestration(self, stack_select_select_mock, get_supported_packages_mock):
"""
Tests that missing the service & role throws an excpetion
:return:
"""
+ get_supported_packages_mock.return_value = TestStackSelect._get_supported_packages()
+
version = "2.5.9.9-9999"
command_json = TestStackSelect._get_cluster_simple_upgrade_json()
@@ -98,6 +103,31 @@ class TestStackSelect(TestCase):
self.assertEqual(stack_select_select_mock.call_args_list[0][0], ("foo-master", version))
+ @patch.object(stack_select, "get_supported_packages")
+ @patch("resource_management.libraries.functions.stack_select.select")
+ def test_legacy_package_fallback(self, stack_select_select_mock, get_supported_packages_mock):
+ """
+ Tests that if the package specified by the JSON isn't support by the stack-select tool,
+ the the fallback legacy value is used.
+ :return:
+ """
+ get_supported_packages_mock.return_value = ["foo-legacy"]
+
+ version = "2.5.9.9-9999"
+
+ command_json = TestStackSelect._get_cluster_simple_upgrade_json()
+
+ Script.config = dict()
+ Script.config.update(command_json)
+ Script.config.update( { "configurations" : { "cluster-env" : {} }, "hostLevelParams": {} } )
+ Script.config["configurations"]["cluster-env"]["stack_packages"] = self._get_stack_packages_with_legacy()
+ Script.config["hostLevelParams"] = { "stack_name" : "HDP" }
+
+ stack_select.select_packages(version)
+
+ self.assertEqual(len(stack_select_select_mock.call_args_list), 1)
+ self.assertEqual(stack_select_select_mock.call_args_list[0][0], ("foo-legacy", version))
+
@staticmethod
def _get_incomplete_cluster_simple_upgrade_json():
"""
@@ -197,3 +227,32 @@ class TestStackSelect(TestCase):
}
}
} )
+
+ @staticmethod
+ def _get_stack_packages_with_legacy():
+ import json
+ return json.dumps( {
+ "HDP": {
+ "stack-select": {
+ "FOO_SERVICE": {
+ "FOO_MASTER": {
+ "LEGACY":"foo-legacy",
+ "STACK-SELECT-PACKAGE": "foo-master",
+ "INSTALL": [
+ "foo-master"
+ ],
+ "PATCH": [
+ "foo-master"
+ ],
+ "STANDARD": [
+ "foo-master"
+ ]
+ }
+ }
+ }
+ }
+ } )
+
+ @staticmethod
+ def _get_supported_packages():
+ return ["foo-master", "foo-client"]
http://git-wip-us.apache.org/repos/asf/ambari/blob/321f9cfe/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/utils/RMFTestCase.py b/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
index 6a0afa2..291f22b 100644
--- a/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
+++ b/ambari-server/src/test/python/stacks/utils/RMFTestCase.py
@@ -139,20 +139,22 @@ class RMFTestCase(TestCase):
if 'status_params' in sys.modules:
del(sys.modules["status_params"])
- with Environment(basedir, test_mode=True) as RMFTestCase.env:
- with patch('resource_management.core.shell.checked_call', side_effect=checked_call_mocks) as mocks_dict['checked_call']:
- with patch('resource_management.core.shell.call', side_effect=call_mocks) as mocks_dict['call']:
- with patch.object(Script, 'get_config', return_value=self.config_dict) as mocks_dict['get_config']: # mocking configurations
- with patch.object(Script, 'get_tmp_dir', return_value="/tmp") as mocks_dict['get_tmp_dir']:
- with patch.object(Script, 'post_start') as mocks_dict['post_start']:
- with patch('resource_management.libraries.functions.get_kinit_path', return_value=kinit_path_local) as mocks_dict['get_kinit_path']:
- with patch.object(platform, 'linux_distribution', return_value=os_type) as mocks_dict['linux_distribution']:
- with patch.object(os, "environ", new=os_env) as mocks_dict['environ']:
- if not try_install:
- with patch.object(Script, 'install_packages') as install_mock_value:
- method(RMFTestCase.env, *command_args)
- else:
- method(RMFTestCase.env, *command_args)
+ with Environment(basedir, test_mode=True) as RMFTestCase.env,\
+ patch('resource_management.core.shell.checked_call', side_effect=checked_call_mocks) as mocks_dict['checked_call'],\
+ patch('resource_management.core.shell.call', side_effect=call_mocks) as mocks_dict['call'],\
+ patch.object(Script, 'get_config', return_value=self.config_dict) as mocks_dict['get_config'],\
+ patch.object(Script, 'get_tmp_dir', return_value="/tmp") as mocks_dict['get_tmp_dir'],\
+ patch.object(Script, 'post_start') as mocks_dict['post_start'],\
+ patch('resource_management.libraries.functions.get_kinit_path', return_value=kinit_path_local) as mocks_dict['get_kinit_path'],\
+ patch.object(platform, 'linux_distribution', return_value=os_type) as mocks_dict['linux_distribution'],\
+ patch('resource_management.libraries.functions.stack_select.is_package_supported', return_value=True),\
+ patch('resource_management.libraries.functions.stack_select.get_supported_packages', return_value=MagicMock()),\
+ patch.object(os, "environ", new=os_env) as mocks_dict['environ']:
+ if not try_install:
+ with patch.object(Script, 'install_packages') as install_mock_value:
+ method(RMFTestCase.env, *command_args)
+ else:
+ method(RMFTestCase.env, *command_args)
sys.path.remove(scriptsdir)
[02/38] ambari git commit: AMBARI-21928 In case if component package
doesn't advertise his version,
Ambari silently failing on deploy stack steps (dgrinenko)
Posted by lp...@apache.org.
AMBARI-21928 In case if component package doesn't advertise his version, Ambari silently failing on deploy stack steps (dgrinenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/001f290b
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/001f290b
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/001f290b
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 001f290be2622375786f27cc054727adb7be8905
Parents: 252e989
Author: Dmytro Grinenko <ha...@apache.org>
Authored: Tue Sep 12 15:12:44 2017 +0300
Committer: Dmytro Grinenko <ha...@apache.org>
Committed: Tue Sep 12 15:12:44 2017 +0300
----------------------------------------------------------------------
.../libraries/functions/stack_tools.py | 12 ++---
.../libraries/functions/version_select_util.py | 57 +++++++++-----------
.../libraries/script/script.py | 2 +
.../scripts/shared_initialization.py | 19 +++----
.../hooks/after-INSTALL/test_after_install.py | 2 +-
5 files changed, 42 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/001f290b/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py b/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py
index fa97fd1..d9233a3 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/stack_tools.py
@@ -32,6 +32,7 @@ from resource_management.core.utils import pad
STACK_SELECTOR_NAME = "stack_selector"
CONF_SELECTOR_NAME = "conf_selector"
+
def get_stack_tool(name):
"""
Give a tool selector name get the stack-specific tool name, tool path, tool package
@@ -43,7 +44,7 @@ def get_stack_tool(name):
stack_name = default("/hostLevelParams/stack_name", None)
if stack_name is None:
Logger.warning("Cannot find the stack name in the command. Stack tools cannot be loaded")
- return (None, None, None)
+ return None, None, None
stack_tools = None
stack_tools_config = default("/configurations/cluster-env/stack_tools", None)
@@ -52,23 +53,22 @@ def get_stack_tool(name):
if stack_tools is None:
Logger.warning("The stack tools could not be found in cluster-env")
- return (None, None, None)
+ return None, None, None
if stack_name not in stack_tools:
Logger.warning("Cannot find stack tools for the stack named {0}".format(stack_name))
- return (None, None, None)
+ return None, None, None
# load the stack tooks keyed by the stack name
stack_tools = stack_tools[stack_name]
if not stack_tools or not name or name.lower() not in stack_tools:
Logger.warning("Cannot find config for {0} stack tool in {1}".format(str(name), str(stack_tools)))
- return (None, None, None)
-
+ return None, None, None
tool_config = stack_tools[name.lower()]
- # Return fixed length (tool_name, tool_path tool_package) tuple
+ # Return fixed length (tool_name, tool_path, tool_package) tuple
return tuple(pad(tool_config[:3], 3))
def get_stack_tool_name(name):
http://git-wip-us.apache.org/repos/asf/ambari/blob/001f290b/ambari-common/src/main/python/resource_management/libraries/functions/version_select_util.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/functions/version_select_util.py b/ambari-common/src/main/python/resource_management/libraries/functions/version_select_util.py
index 79dc874..9fbb42b 100644
--- a/ambari-common/src/main/python/resource_management/libraries/functions/version_select_util.py
+++ b/ambari-common/src/main/python/resource_management/libraries/functions/version_select_util.py
@@ -26,7 +26,6 @@ import tempfile
from resource_management.core.logger import Logger
from resource_management.core import shell
from resource_management.libraries.functions import stack_tools
-import ambari_simplejson as json # simplejson is much faster comparing to Python 2.6 json module and has the same functions set.
def get_component_version(stack_name, component_name):
@@ -39,42 +38,36 @@ def get_component_version(stack_name, component_name):
:return: Returns a string if found, e.g., 2.2.1.0-2175, otherwise, returns None
"""
version = None
- if stack_name is None or component_name is None:
+ if not stack_name or not component_name:
Logger.error("Could not determine component version because of the parameters is empty. " \
"stack_name: %s, component_name: %s" % (str(stack_name), str(component_name)))
return version
- out = None
- code = -1
- if not stack_name:
- Logger.error("Stack name not provided")
- elif not component_name:
- Logger.error("Component name not provided")
+ stack_selector_name, stack_selector_path, stack_selector_package = stack_tools.get_stack_tool(stack_tools.STACK_SELECTOR_NAME)
+ if stack_selector_name and stack_selector_path and os.path.exists(stack_selector_path):
+ tmpfile = tempfile.NamedTemporaryFile(delete=True)
+ out, code = None, -1
+ get_stack_comp_version_cmd = '%s status %s > %s' % (stack_selector_path, component_name, tmpfile.name)
+
+ try:
+ # This is necessary because Ubuntu returns "stdin: is not a tty", see AMBARI-8088
+ # ToDo: original problem looks strange
+ with open(tmpfile.name, 'r') as f:
+ code = shell.call(get_stack_comp_version_cmd, quiet=True)[0]
+ out = f.read()
+
+ if code != 0 or out is None:
+ raise ValueError("Code is nonzero or output is empty")
+
+ Logger.debug("Command: %s\nOutput: %s" % (get_stack_comp_version_cmd, str(out)))
+ matches = re.findall(r"( [\d\.]+(\-\d+)?)", out)
+ version = matches[0][0].strip() if matches and len(matches) > 0 and len(matches[0]) > 0 else None
+ Logger.debug("Version for component %s: %s" % (component_name, str(version)))
+ except Exception, e:
+ Logger.error("Could not determine stack version for component %s by calling '%s'. Return Code: %s, Output: %s." %
+ (component_name, get_stack_comp_version_cmd, str(code), str(out)))
else:
- (stack_selector_name, stack_selector_path, stack_selector_package) = stack_tools.get_stack_tool(stack_tools.STACK_SELECTOR_NAME)
- if stack_selector_name and stack_selector_path and os.path.exists(stack_selector_path):
- tmpfile = tempfile.NamedTemporaryFile()
-
- get_stack_comp_version_cmd = ""
- try:
- # This is necessary because Ubuntu returns "stdin: is not a tty", see AMBARI-8088
- with open(tmpfile.name, 'r') as file:
- get_stack_comp_version_cmd = '%s status %s > %s' % (stack_selector_path, component_name, tmpfile.name)
- code, stdoutdata = shell.call(get_stack_comp_version_cmd, quiet=True)
- out = file.read()
-
- if code != 0 or out is None:
- raise Exception("Code is nonzero or output is empty")
-
- Logger.debug("Command: %s\nOutput: %s" % (get_stack_comp_version_cmd, str(out)))
- matches = re.findall(r"( [\d\.]+(\-\d+)?)", out)
- version = matches[0][0].strip() if matches and len(matches) > 0 and len(matches[0]) > 0 else None
- Logger.debug("Version for component %s: %s" % (component_name, str(version)))
- except Exception, e:
- Logger.error("Could not determine stack version for component %s by calling '%s'. Return Code: %s, Output: %s." %
- (component_name, get_stack_comp_version_cmd, str(code), str(out)))
- else:
- Logger.error("Could not find stack selector for stack: %s" % str(stack_name))
+ Logger.error("Could not find stack selector for stack: %s" % str(stack_name))
return version
http://git-wip-us.apache.org/repos/asf/ambari/blob/001f290b/ambari-common/src/main/python/resource_management/libraries/script/script.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/libraries/script/script.py b/ambari-common/src/main/python/resource_management/libraries/script/script.py
index fcfac2b..0e352d1 100644
--- a/ambari-common/src/main/python/resource_management/libraries/script/script.py
+++ b/ambari-common/src/main/python/resource_management/libraries/script/script.py
@@ -228,6 +228,8 @@ class Script(object):
repo_version_id = default("/hostLevelParams/repository_version_id", None)
if repo_version_id:
self.put_structured_out({"repository_version_id": repo_version_id})
+ else:
+ Logger.error("Component '{0}' did not advertise a version. This may indicate a problem with the component packaging.".format(stack_select_package_name))
def should_expose_component_version(self, command_name):
http://git-wip-us.apache.org/repos/asf/ambari/blob/001f290b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/shared_initialization.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/shared_initialization.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/shared_initialization.py
index daaffd8..67c3ba8 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/shared_initialization.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/after-INSTALL/scripts/shared_initialization.py
@@ -46,7 +46,7 @@ def setup_stack_symlinks(struct_out_file):
return
if params.host_sys_prepped:
- Logger.warning("Skipping running stack-selector-tool becase this is a sys_prepped host. This may cause symlink pointers not to be created for HDP componets installed later on top of an already sys_prepped host.")
+ Logger.warning("Skipping running stack-selector-tool because this is a sys_prepped host. This may cause symlink pointers not to be created for HDP components installed later on top of an already sys_prepped host")
return
# get the packages which the stack-select tool should be used on
@@ -105,17 +105,14 @@ def load_version(struct_out_file):
"""
Load version from file. Made a separate method for testing
"""
- json_version = None
try:
- if os.path.exists(struct_out_file):
- with open(struct_out_file, 'r') as fp:
- json_info = json.load(fp)
- json_version = json_info['version']
- except:
- pass
-
- return json_version
-
+ with open(struct_out_file, 'r') as fp:
+ json_info = json.load(fp)
+
+ return json_info['version']
+ except (IOError, KeyError, TypeError):
+ return None
+
def link_configs(struct_out_file):
"""
http://git-wip-us.apache.org/repos/asf/ambari/blob/001f290b/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py b/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
index d6740cb..f905cf9 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/hooks/after-INSTALL/test_after_install.py
@@ -344,4 +344,4 @@ class TestHookAfterInstall(RMFTestCase):
config_dict = json_content,
config_overrides = self.CONFIG_OVERRIDES)
- logger_warning_mock.assert_any_call('Skipping running stack-selector-tool becase this is a sys_prepped host. This may cause symlink pointers not to be created for HDP componets installed later on top of an already sys_prepped host.')
+ logger_warning_mock.assert_any_call('Skipping running stack-selector-tool because this is a sys_prepped host. This may cause symlink pointers not to be created for HDP components installed later on top of an already sys_prepped host')
[32/38] ambari git commit: AMBARI-21307 refactoring - renamed,
moved classes, variables
Posted by lp...@apache.org.
AMBARI-21307 refactoring - renamed, moved classes, variables
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fa7d7ec3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fa7d7ec3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fa7d7ec3
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: fa7d7ec34b676fe2a2f9158fba1076f32f60baa9
Parents: e459461
Author: lpuskas <lp...@apache.org>
Authored: Tue Aug 22 10:03:24 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:31 2017 +0200
----------------------------------------------------------------------
.../api/services/ldap/AmbariConfiguration.java | 87 +++++++
.../services/ldap/AmbariConfigurationDTO.java | 67 -----
.../ldap/LdapCheckConfigurationRequest.java | 47 ----
.../api/services/ldap/LdapConfigOperation.java | 43 ++++
.../services/ldap/LdapConfigurationRequest.java | 49 ++++
.../services/ldap/LdapConfigurationService.java | 53 +---
.../api/services/ldap/LdapOperationRequest.java | 18 --
.../server/ldap/LdapConfigurationService.java | 60 +++++
.../ldap/LdapConfigurationValidatorService.java | 60 -----
.../apache/ambari/server/ldap/LdapModule.java | 4 +-
.../server/ldap/service/AmbariLdapFacade.java | 10 +-
.../ads/DefaultLdapConfigurationService.java | 243 +++++++++++++++++++
...efaultLdapConfigurationValidatorService.java | 243 -------------------
.../api/services/ldap/LDAPServiceTest.java | 6 +-
.../DefaultLdapConfigurationServiceTest.java | 113 +++++++++
...ltLdapConfigurationValidatorServiceTest.java | 113 ---------
16 files changed, 618 insertions(+), 598 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/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
new file mode 100644
index 0000000..b5cc921
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfiguration.java
@@ -0,0 +1,87 @@
+/*
+ * 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.Collections;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Domain POJO representing generic ambari configuration data.
+ */
+public class AmbariConfiguration {
+
+ /**
+ * The type of the configuration, eg.: ldap-configuration
+ */
+ private String type;
+
+ /**
+ * Version tag
+ */
+ private String versionTag;
+
+ /**
+ * Version number
+ */
+ private Integer version;
+
+ /**
+ * Created timestamp
+ */
+ private long createdTs;
+
+ private Set<Map<String, Object>> data = Collections.emptySet();
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Set<Map<String, Object>> getData() {
+ return data;
+ }
+
+ public void setData(Set<Map<String, Object>> data) {
+ this.data = data;
+ }
+
+ public String getVersionTag() {
+ return versionTag;
+ }
+
+ public void setVersionTag(String versionTag) {
+ this.versionTag = versionTag;
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+
+ public long getCreatedTs() {
+ return createdTs;
+ }
+
+ public void setCreatedTs(long createdTs) {
+ this.createdTs = createdTs;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java
deleted file mode 100644
index 1b134fe..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java
+++ /dev/null
@@ -1,67 +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.Collections;
-import java.util.Map;
-import java.util.Set;
-
-public class AmbariConfigurationDTO {
- private String type;
- private Set<Map<String, Object>> data = Collections.emptySet();
- private String versionTag;
- private Integer version;
- private long createdTs;
-
- public String getType() {
- return type;
- }
-
- public void setType(String type) {
- this.type = type;
- }
-
- public Set<Map<String, Object>> getData() {
- return data;
- }
-
- public void setData(Set<Map<String, Object>> data) {
- this.data = data;
- }
-
- public String getVersionTag() {
- return versionTag;
- }
-
- public void setVersionTag(String versionTag) {
- this.versionTag = versionTag;
- }
-
- public Integer getVersion() {
- return version;
- }
-
- public void setVersion(Integer version) {
- this.version = version;
- }
-
- public long getCreatedTs() {
- return createdTs;
- }
-
- public void setCreatedTs(long createdTs) {
- this.createdTs = createdTs;
- }
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java
deleted file mode 100644
index 188f1b9..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java
+++ /dev/null
@@ -1,47 +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;
-
-public class LdapCheckConfigurationRequest implements LdapOperationRequest {
-
- @SerializedName("AmbariConfiguration")
- private AmbariConfigurationDTO ambariConfiguration;
-
- @SerializedName("RequestInfo")
- private LdapRequestInfo requestInfo;
-
- public LdapCheckConfigurationRequest() {
- }
-
-
- public AmbariConfigurationDTO getAmbariConfiguration() {
- return ambariConfiguration;
- }
-
- public void setAmbariConfiguration(AmbariConfigurationDTO 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/fa7d7ec3/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
new file mode 100644
index 0000000..478d4ff
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigOperation.java
@@ -0,0 +1,43 @@
+/*
+ * 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/fa7d7ec3/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
new file mode 100644
index 0000000..2e478c4
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapConfigurationRequest.java
@@ -0,0 +1,49 @@
+/*
+ * 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("AmbariConfiguration")
+ 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/fa7d7ec3/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
index 52244bc..fc6bd41 100644
--- 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
@@ -74,40 +74,13 @@ public class LdapConfigurationService extends AmbariConfigurationService {
@Inject
private static LdapConfigurationFactory ldapConfigurationFactory;
- /**
- * Actions supported by this endpoint
- */
- private enum LdapAction {
- TEST_CONNECTION("test-connection"),
- TEST_ATTRIBUTES("test-attributes"),
- DETECT_ATTRIBUTES("detect-attributes");
-
- private String actionStr;
-
- LdapAction(String actionStr) {
- this.actionStr = actionStr;
- }
-
- public static LdapAction fromAction(String action) {
- for (LdapAction val : LdapAction.values()) {
- if (val.action().equals(action)) {
- return val;
- }
- }
- throw new IllegalStateException("Action [ " + action + " ] is not supported");
- }
-
- public String action() {
- return this.actionStr;
- }
- }
@POST
@ApiIgnore // until documented
@Path("/validate")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
- public Response validateConfiguration(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+ public Response validateConfiguration(LdapConfigurationRequest ldapConfigurationRequest) {
authorize();
@@ -116,12 +89,12 @@ public class LdapConfigurationService extends AmbariConfigurationService {
Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
try {
- validateRequest(ldapCheckConfigurationRequest);
+ validateRequest(ldapConfigurationRequest);
AmbariLdapConfiguration ambariLdapConfiguration = ldapConfigurationFactory.createLdapConfiguration(
- ldapCheckConfigurationRequest.getAmbariConfiguration().getData().iterator().next());
+ ldapConfigurationRequest.getAmbariConfiguration().getData().iterator().next());
- LdapAction action = LdapAction.fromAction(ldapCheckConfigurationRequest.getRequestInfo().getAction());
+ LdapConfigOperation action = LdapConfigOperation.fromAction(ldapConfigurationRequest.getRequestInfo().getAction());
switch (action) {
case TEST_CONNECTION:
@@ -133,7 +106,7 @@ public class LdapConfigurationService extends AmbariConfigurationService {
case TEST_ATTRIBUTES:
LOGGER.info("Testing LDAP attributes ....");
- groups = ldapFacade.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+ groups = ldapFacade.checkLdapAttibutes(ldapConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
setResult(groups, result);
break;
@@ -161,24 +134,24 @@ public class LdapConfigurationService extends AmbariConfigurationService {
result.getResultTree().addChild(resource, "payload");
}
- private void validateRequest(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+ private void validateRequest(LdapConfigurationRequest ldapConfigurationRequest) {
String errMsg;
- if (null == ldapCheckConfigurationRequest) {
+ if (null == ldapConfigurationRequest) {
errMsg = "No ldap configuraiton request provided";
LOGGER.error(errMsg);
throw new IllegalArgumentException(errMsg);
}
- if (null == ldapCheckConfigurationRequest.getRequestInfo()) {
- errMsg = String.format("No request information provided. Request: [%s]", ldapCheckConfigurationRequest);
+ if (null == ldapConfigurationRequest.getRequestInfo()) {
+ errMsg = String.format("No request information provided. Request: [%s]", ldapConfigurationRequest);
LOGGER.error(errMsg);
throw new IllegalArgumentException(errMsg);
}
- if (null == ldapCheckConfigurationRequest.getAmbariConfiguration()
- || ldapCheckConfigurationRequest.getAmbariConfiguration().getData().size() != 1) {
- errMsg = String.format("No / Invalid configuration data provided. Request: [%s]", ldapCheckConfigurationRequest);
+ if (null == ldapConfigurationRequest.getAmbariConfiguration()
+ || ldapConfigurationRequest.getAmbariConfiguration().getData().size() != 1) {
+ errMsg = String.format("No / Invalid configuration data provided. Request: [%s]", ldapConfigurationRequest);
LOGGER.error(errMsg);
throw new IllegalArgumentException(errMsg);
}
@@ -202,7 +175,7 @@ public class LdapConfigurationService extends AmbariConfigurationService {
}
- Set<RoleAuthorization> requiredAuthorizations() {
+ private Set<RoleAuthorization> requiredAuthorizations() {
return Sets.newHashSet(RoleAuthorization.AMBARI_MANAGE_CONFIGURATION);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java
deleted file mode 100644
index 06f6c40..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java
+++ /dev/null
@@ -1,18 +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;
-
-public interface LdapOperationRequest {
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationService.java
new file mode 100644
index 0000000..69a641f
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationService.java
@@ -0,0 +1,60 @@
+/*
+ * 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;
+
+import java.util.Set;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+
+/**
+ * Collection of operations for validating ldap configuration.
+ * It's intended to decouple implementations using different libraries.
+ */
+public interface LdapConfigurationService {
+
+ /**
+ * Tests the connection based on the provided configuration.
+ *
+ * @param ldapConnection connection instance
+ * @param configuration the ambari ldap configuration instance
+ * @throws AmbariLdapException if the connection is not possible
+ */
+ void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration configuration) throws AmbariLdapException;
+
+
+ /**
+ * Implements LDAP user related configuration settings validation logic.
+ * Implementers communicate with the LDAP server (search, bind) to validate attributes in the provided configuration
+ * instance
+ *
+ * @param ldapConnection connection instance used to connect to the LDAP server
+ * @param testUserName the test username
+ * @param testPassword the test password
+ * @param configuration the available ldap configuration
+ * @return The DN of the found user entry
+ * @throws AmbariException if the connection couldn't be estabilisheds
+ */
+ String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration configuration) throws AmbariLdapException;
+
+ /**
+ * Checks whether the group related LDAP attributes in the configuration are correct.
+ *
+ * @throws AmbariException if the attributes are not valid
+ */
+ Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
deleted file mode 100644
index 7efa3b7..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
+++ /dev/null
@@ -1,60 +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;
-
-import java.util.Set;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ldap.service.AmbariLdapException;
-import org.apache.directory.ldap.client.api.LdapConnection;
-
-/**
- * Collection of operations for validating ldap configuration.
- * It's intended to decouple implementations using different libraries.
- */
-public interface LdapConfigurationValidatorService {
-
- /**
- * Tests the connection based on the provided configuration.
- *
- * @param ldapConnection connection instance
- * @param configuration the ambari ldap configuration instance
- * @throws AmbariLdapException if the connection is not possible
- */
- void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration configuration) throws AmbariLdapException;
-
-
- /**
- * Implements LDAP user related configuration settings validation logic.
- * Implementers communicate with the LDAP server (search, bind) to validate attributes in the provided configuration
- * instance
- *
- * @param ldapConnection connection instance used to connect to the LDAP server
- * @param testUserName the test username
- * @param testPassword the test password
- * @param configuration the available ldap configuration
- * @return The DN of the found user entry
- * @throws AmbariException if the connection couldn't be estabilisheds
- */
- String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration configuration) throws AmbariLdapException;
-
- /**
- * Checks whether the group related LDAP attributes in the configuration are correct.
- *
- * @throws AmbariException if the attributes are not valid
- */
- Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/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 a4ad2ee..3ae4587 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
@@ -18,7 +18,7 @@ package org.apache.ambari.server.ldap;
import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
import org.apache.ambari.server.ldap.service.LdapConnectionService;
import org.apache.ambari.server.ldap.service.LdapFacade;
-import org.apache.ambari.server.ldap.service.ads.DefaultLdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.ads.DefaultLdapConfigurationService;
import org.apache.ambari.server.ldap.service.ads.DefaultLdapConnectionService;
import com.google.inject.AbstractModule;
@@ -32,7 +32,7 @@ public class LdapModule extends AbstractModule {
@Override
protected void configure() {
bind(LdapFacade.class).to(AmbariLdapFacade.class);
- bind(LdapConfigurationValidatorService.class).to(DefaultLdapConfigurationValidatorService.class);
+ bind(LdapConfigurationService.class).to(DefaultLdapConfigurationService.class);
bind(LdapConnectionService.class).to(DefaultLdapConnectionService.class);
install(new FactoryModuleBuilder().build(LdapConfigurationFactory.class));
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index eec47ce..683ed43 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -22,7 +22,7 @@ import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.LdapConfigurationService;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -49,7 +49,7 @@ public class AmbariLdapFacade implements LdapFacade {
}
@Inject
- private LdapConfigurationValidatorService ldapConfigurationValidatorService;
+ private LdapConfigurationService ldapConfigurationService;
@Inject
private LdapConnectionService ldapConnectionService;
@@ -63,7 +63,7 @@ public class AmbariLdapFacade implements LdapFacade {
try {
LOGGER.info("Validating LDAP connection related configuration based on: {}", ambariLdapConfiguration);
LdapConnection connection = ldapConnectionService.createLdapConnection(ambariLdapConfiguration);
- ldapConfigurationValidatorService.checkConnection(connection, ambariLdapConfiguration);
+ ldapConfigurationService.checkConnection(connection, ambariLdapConfiguration);
} catch (AmbariLdapException e) {
LOGGER.error("Validating LDAP connection configuration failed", e);
throw e;
@@ -90,10 +90,10 @@ public class AmbariLdapFacade implements LdapFacade {
LdapConnection ldapConnection = ldapConnectionService.createLdapConnection(ldapConfiguration);
LOGGER.info("Testing LDAP user attributes with test user: {}", userName);
- String userDn = ldapConfigurationValidatorService.checkUserAttributes(ldapConnection, userName, testUserPass, ldapConfiguration);
+ String userDn = ldapConfigurationService.checkUserAttributes(ldapConnection, userName, testUserPass, ldapConfiguration);
LOGGER.info("Testing LDAP group attributes with test user dn: {}", userDn);
- Set<String> groups = ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, userDn, ldapConfiguration);
+ Set<String> groups = ldapConfigurationService.checkGroupAttributes(ldapConnection, userDn, ldapConfiguration);
return groups;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
new file mode 100644
index 0000000..abc9201
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
@@ -0,0 +1,243 @@
+/*
+ * 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.service.ads;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationService;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Implementation of the validation logic using the Apache Directory API.
+ */
+@Singleton
+public class DefaultLdapConfigurationService implements LdapConfigurationService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationService.class);
+
+ @Inject
+ private LdapConnectionService ldapConnectionService;
+
+ /**
+ * Facilitating the instantiation
+ */
+ @Inject
+ public DefaultLdapConfigurationService() {
+ }
+
+ @Override
+ public void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ try {
+ bind(ambariLdapConfiguration, ldapConnection);
+ } catch (LdapException e) {
+ LOGGER.error("Could not connect to the LDAP server", e);
+ throw new AmbariLdapException(e);
+ }
+ }
+
+
+ /**
+ * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
+ * Attributes are considered correct if there is at least one entry found.
+ *
+ * Invalid attributes are signaled by throwing an exception.
+ *
+ * @param testUserName the test username
+ * @param testPassword the test password
+ * @param ambariLdapConfiguration configuration instance holding ldap configuration details
+ * @return the DN of the test user
+ * @throws AmbariException if the attributes are not valid or any errors occurs
+ */
+ @Override
+ public String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ SearchCursor searchCursor = null;
+ String userDn = null;
+ try {
+ LOGGER.info("Checking user attributes for user {} r ...", testUserName);
+
+ // bind anonimously or with manager data
+ bind(ambariLdapConfiguration, ldapConnection);
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), testUserName))
+ .toString();
+
+ LOGGER.info("Searching for the user: {} using the search filter: {}", testUserName, filter);
+ EntryCursor entryCursor = ldapConnection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
+
+ // collecting search result entries
+ List<Entry> users = Lists.newArrayList();
+ for (Entry entry : entryCursor) {
+ users.add(entry);
+ userDn = entry.getDn().getNormName();
+ }
+
+ // there should be at least one user found
+ if (users.isEmpty()) {
+ String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
+ LOGGER.error(msg);
+ throw new Exception(msg);
+ }
+
+ LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
+
+ } catch (Exception e) {
+
+ LOGGER.error("User attributes validation failed.", e);
+ throw new AmbariLdapException(e.getMessage(), e);
+
+ } finally {
+ closeResources(ldapConnection, searchCursor);
+ }
+ return userDn;
+ }
+
+
+ @Override
+ public Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ SearchCursor searchCursor = null;
+ Set<Response> groupResponses = Sets.newHashSet();
+
+ try {
+ LOGGER.info("Checking group attributes for user dn {} ...", userDn);
+
+ bind(ambariLdapConfiguration, ldapConnection);
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.groupObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.groupMemberAttribute(), userDn)
+ ).toString();
+
+ LOGGER.info("Searching for the groups the user dn: {} is member of using the search filter: {}", userDn, filter);
+
+ // assemble a search request
+ SearchRequest searchRequest = new SearchRequestImpl();
+ searchRequest.setFilter(filter);
+ searchRequest.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
+ searchRequest.setScope(SearchScope.SUBTREE);
+ searchRequest.addAttributes(ambariLdapConfiguration.groupMemberAttribute(), ambariLdapConfiguration.groupNameAttribute());
+
+ // perform the search
+ searchCursor = ldapConnection.search(searchRequest);
+
+ for (Response response : searchCursor) {
+ groupResponses.add(response);
+ }
+
+ } catch (Exception e) {
+
+ LOGGER.error("User attributes validation failed.", e);
+ throw new AmbariLdapException(e.getMessage(), e);
+
+ } finally {
+ closeResources(ldapConnection, searchCursor);
+ }
+
+ return processGroupResults(groupResponses, ambariLdapConfiguration);
+ }
+
+ /**
+ * Binds to the LDAP server (anonimously or wit manager credentials)
+ *
+ * @param ambariLdapConfiguration configuration instance
+ * @param connection connection instance
+ * @throws LdapException if the bind operation fails
+ */
+ private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
+ LOGGER.info("Connecting to LDAP ....");
+ if (!ambariLdapConfiguration.bindAnonimously()) {
+ LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
+ connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
+ } else {
+ LOGGER.debug("Binding anonimously ...");
+ connection.bind();
+ }
+
+ if (!connection.isConnected()) {
+ LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
+ throw new IllegalStateException("The connection to the LDAP server is not alive");
+ }
+ LOGGER.info("Connected to LDAP.");
+ }
+
+
+ /**
+ * Extracts meaningful values from the search result.
+ *
+ * @param groupResponses the result entries returned by the search
+ * @param ambariLdapConfiguration holds the keys of the meaningful attributes
+ * @return a set with the group names the test user belongs to
+ */
+ private Set<String> processGroupResults(Set<Response> groupResponses, AmbariLdapConfiguration ambariLdapConfiguration) {
+ Set<String> groupStrSet = Sets.newHashSet();
+ for (Response response : groupResponses) {
+ Entry entry = ((SearchResultEntryDecorator) response).getEntry();
+ groupStrSet.add(entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString());
+ }
+
+ LOGGER.debug("Extracted group names from group search responses: {}", groupStrSet);
+ return groupStrSet;
+ }
+
+ private void closeResources(LdapConnection connection, SearchCursor searchCursor) {
+ LOGGER.debug("Housekeeping: closing the connection and the search cursor ...");
+
+ if (null != searchCursor) {
+ // this method is idempotent
+ searchCursor.close();
+ }
+
+ if (null != connection) {
+ try {
+ connection.close();
+ } catch (IOException e) {
+ LOGGER.error("Exception occurred while closing the connection", e);
+ }
+ }
+ }
+
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java
deleted file mode 100644
index 040983a..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorService.java
+++ /dev/null
@@ -1,243 +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.service.ads;
-
-import java.io.IOException;
-import java.util.List;
-import java.util.Set;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
-import org.apache.ambari.server.ldap.service.AmbariLdapException;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
-import org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
-import org.apache.directory.api.ldap.model.constants.SchemaConstants;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.exception.LdapException;
-import org.apache.directory.api.ldap.model.message.Response;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.search.FilterBuilder;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
-
-/**
- * Implementation of the validation logic using the Apache Directory API.
- */
-@Singleton
-public class DefaultLdapConfigurationValidatorService implements LdapConfigurationValidatorService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
-
- @Inject
- private LdapConnectionService ldapConnectionService;
-
- /**
- * Facilitating the instantiation
- */
- @Inject
- public DefaultLdapConfigurationValidatorService() {
- }
-
- @Override
- public void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- try {
- bind(ambariLdapConfiguration, ldapConnection);
- } catch (LdapException e) {
- LOGGER.error("Could not connect to the LDAP server", e);
- throw new AmbariLdapException(e);
- }
- }
-
-
- /**
- * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
- * Attributes are considered correct if there is at least one entry found.
- *
- * Invalid attributes are signaled by throwing an exception.
- *
- * @param testUserName the test username
- * @param testPassword the test password
- * @param ambariLdapConfiguration configuration instance holding ldap configuration details
- * @return the DN of the test user
- * @throws AmbariException if the attributes are not valid or any errors occurs
- */
- @Override
- public String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- SearchCursor searchCursor = null;
- String userDn = null;
- try {
- LOGGER.info("Checking user attributes for user {} r ...", testUserName);
-
- // bind anonimously or with manager data
- bind(ambariLdapConfiguration, ldapConnection);
-
- // set up a filter based on the provided attributes
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), testUserName))
- .toString();
-
- LOGGER.info("Searching for the user: {} using the search filter: {}", testUserName, filter);
- EntryCursor entryCursor = ldapConnection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
-
- // collecting search result entries
- List<Entry> users = Lists.newArrayList();
- for (Entry entry : entryCursor) {
- users.add(entry);
- userDn = entry.getDn().getNormName();
- }
-
- // there should be at least one user found
- if (users.isEmpty()) {
- String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
- LOGGER.error(msg);
- throw new Exception(msg);
- }
-
- LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
-
- } catch (Exception e) {
-
- LOGGER.error("User attributes validation failed.", e);
- throw new AmbariLdapException(e.getMessage(), e);
-
- } finally {
- closeResources(ldapConnection, searchCursor);
- }
- return userDn;
- }
-
-
- @Override
- public Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- SearchCursor searchCursor = null;
- Set<Response> groupResponses = Sets.newHashSet();
-
- try {
- LOGGER.info("Checking group attributes for user dn {} ...", userDn);
-
- bind(ambariLdapConfiguration, ldapConnection);
-
- // set up a filter based on the provided attributes
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.groupObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.groupMemberAttribute(), userDn)
- ).toString();
-
- LOGGER.info("Searching for the groups the user dn: {} is member of using the search filter: {}", userDn, filter);
-
- // assemble a search request
- SearchRequest searchRequest = new SearchRequestImpl();
- searchRequest.setFilter(filter);
- searchRequest.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
- searchRequest.setScope(SearchScope.SUBTREE);
- searchRequest.addAttributes(ambariLdapConfiguration.groupMemberAttribute(), ambariLdapConfiguration.groupNameAttribute());
-
- // perform the search
- searchCursor = ldapConnection.search(searchRequest);
-
- for (Response response : searchCursor) {
- groupResponses.add(response);
- }
-
- } catch (Exception e) {
-
- LOGGER.error("User attributes validation failed.", e);
- throw new AmbariLdapException(e.getMessage(), e);
-
- } finally {
- closeResources(ldapConnection, searchCursor);
- }
-
- return processGroupResults(groupResponses, ambariLdapConfiguration);
- }
-
- /**
- * Binds to the LDAP server (anonimously or wit manager credentials)
- *
- * @param ambariLdapConfiguration configuration instance
- * @param connection connection instance
- * @throws LdapException if the bind operation fails
- */
- private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
- LOGGER.info("Connecting to LDAP ....");
- if (!ambariLdapConfiguration.bindAnonimously()) {
- LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
- connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
- } else {
- LOGGER.debug("Binding anonimously ...");
- connection.bind();
- }
-
- if (!connection.isConnected()) {
- LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
- throw new IllegalStateException("The connection to the LDAP server is not alive");
- }
- LOGGER.info("Connected to LDAP.");
- }
-
-
- /**
- * Extracts meaningful values from the search result.
- *
- * @param groupResponses the result entries returned by the search
- * @param ambariLdapConfiguration holds the keys of the meaningful attributes
- * @return a set with the group names the test user belongs to
- */
- private Set<String> processGroupResults(Set<Response> groupResponses, AmbariLdapConfiguration ambariLdapConfiguration) {
- Set<String> groupStrSet = Sets.newHashSet();
- for (Response response : groupResponses) {
- Entry entry = ((SearchResultEntryDecorator) response).getEntry();
- groupStrSet.add(entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString());
- }
-
- LOGGER.debug("Extracted group names from group search responses: {}", groupStrSet);
- return groupStrSet;
- }
-
- private void closeResources(LdapConnection connection, SearchCursor searchCursor) {
- LOGGER.debug("Housekeeping: closing the connection and the search cursor ...");
-
- if (null != searchCursor) {
- // this method is idempotent
- searchCursor.close();
- }
-
- if (null != connection) {
- try {
- connection.close();
- } catch (IOException e) {
- LOGGER.error("Exception occurred while closing the connection", e);
- }
- }
- }
-
-}
-
-
-
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
index f20cd1f..5e8eac6 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
@@ -46,11 +46,11 @@ public class LDAPServiceTest {
// WHEN
- LdapCheckConfigurationRequest ldapCheckConfigurationRequest = gsonJsonProvider.fromJson(JSON_STRING, LdapCheckConfigurationRequest.class);
- // LdapCheckConfigurationRequest ldapCheckConfigurationRequest = objectMapper.readValue(JSON_STRING, LdapCheckConfigurationRequest.class);
+ LdapConfigurationRequest ldapConfigurationRequest = gsonJsonProvider.fromJson(JSON_STRING, LdapConfigurationRequest.class);
+ // LdapConfigurationRequest ldapConfigurationRequest = objectMapper.readValue(JSON_STRING, LdapConfigurationRequest.class);
// THEN
- Assert.assertNotNull(ldapCheckConfigurationRequest);
+ Assert.assertNotNull(ldapConfigurationRequest);
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
new file mode 100644
index 0000000..2b7448e
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.service.ads;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationService;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class DefaultLdapConfigurationServiceTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationService.class);
+ private static final String TEST_USER = "einstein";
+
+ LdapConfigurationService ldapConfigurationService = new DefaultLdapConfigurationService();
+
+
+ @Test
+ public void testCheckAttributes() throws Exception {
+
+ // WHEN
+ LdapConnectionConfig config = new LdapConnectionConfig();
+ config.setLdapHost("localhost");
+ config.setLdapPort(389);
+ LdapConnection connection = new LdapNetworkConnection(config);
+
+ // THEN
+ connection.anonymousBind();
+
+
+ EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
+
+ for (Entry entry : cursor) {
+ assertNotNull(entry);
+ System.out.println(entry);
+ }
+
+ cursor.close();
+
+ }
+
+ @Test
+ public void testCheckUserAttributes() throws Exception {
+ // GIVEN
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ ldapConfigurationService.checkUserAttributes(ldapConnection, "einstein", "", ambariLdapConfiguration);
+ }
+
+ @Test
+ public void testRetrieveGorupsForuser() throws Exception {
+ // GIVEN
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ ldapConfigurationService.checkGroupAttributes(ldapConnection, "uid=einstein,dc=example,dc=com", ambariLdapConfiguration);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa7d7ec3/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java
deleted file mode 100644
index 1c7f75d..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationValidatorServiceTest.java
+++ /dev/null
@@ -1,113 +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.service.ads;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.util.Map;
-
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
-import org.apache.ambari.server.ldap.service.LdapConnectionService;
-import org.apache.directory.api.ldap.model.constants.SchemaConstants;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-public class DefaultLdapConfigurationValidatorServiceTest {
- private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
- private static final String TEST_USER = "einstein";
-
- LdapConfigurationValidatorService ldapConfigurationValidatorService = new DefaultLdapConfigurationValidatorService();
-
-
- @Test
- public void testCheckAttributes() throws Exception {
-
- // WHEN
- LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost("localhost");
- config.setLdapPort(389);
- LdapConnection connection = new LdapNetworkConnection(config);
-
- // THEN
- connection.anonymousBind();
-
-
- EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
-
- for (Entry entry : cursor) {
- assertNotNull(entry);
- System.out.println(entry);
- }
-
- cursor.close();
-
- }
-
- @Test
- public void testCheckUserAttributes() throws Exception {
- // GIVEN
- Map<String, Object> ldapPropsMap = Maps.newHashMap();
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_SEARCH_BASE.propertyName(), "dc=example,dc=com");
-
-
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
- LdapConnectionService connectionService = new DefaultLdapConnectionService();
- LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
- ldapConfigurationValidatorService.checkUserAttributes(ldapConnection, "einstein", "", ambariLdapConfiguration);
- }
-
- @Test
- public void testRetrieveGorupsForuser() throws Exception {
- // GIVEN
- Map<String, Object> ldapPropsMap = Maps.newHashMap();
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
-
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_SEARCH_BASE.propertyName(), "dc=example,dc=com");
-
-
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
- LdapConnectionService connectionService = new DefaultLdapConnectionService();
- LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
- ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, "uid=einstein,dc=example,dc=com", ambariLdapConfiguration);
- }
-}
\ No newline at end of file
[38/38] ambari git commit: Â AMBARI-21307 Implemented more detectors. Organized the code
Posted by lp...@apache.org.
 AMBARI-21307 Implemented more detectors. Organized the code
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/ac71c44c
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/ac71c44c
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/ac71c44c
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: ac71c44c53f9170fdc3f94342a381a27bf42d5d6
Parents: 7b91bc5
Author: lpuskas <lp...@apache.org>
Authored: Tue Sep 12 11:58:45 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:32 2017 +0200
----------------------------------------------------------------------
.../server/ldap/AmbariLdapConfiguration.java | 1 +
.../ads/DefaultAttributeDetectionService.java | 134 ++++++++++++++-----
.../ldap/service/ads/ObjectClassDetector.java | 81 -----------
.../ads/OccurranceAndWeightBasedDetector.java | 81 -----------
.../service/ads/UserNameAttributeDetector.java | 75 -----------
.../ads/detectors/GroupMemberAttrDetector.java | 56 ++++++++
.../ads/detectors/GroupNameAttrDetector.java | 61 +++++++++
.../ads/detectors/GroupObjectClassDetector.java | 64 +++++++++
.../OccurranceAndWeightBasedDetector.java | 103 ++++++++++++++
.../detectors/UserGroupMemberAttrDetector.java | 56 ++++++++
.../ads/detectors/UserNameAttrDetector.java | 60 +++++++++
.../ads/detectors/UserObjectClassDetector.java | 64 +++++++++
.../DefaultAttributeDetectionServiceTest.java | 10 +-
13 files changed, 571 insertions(+), 275 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index e28c6ed..ebb567d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -56,6 +56,7 @@ public class AmbariLdapConfiguration {
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"),
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
index 710adf1..b3a4fde 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
@@ -14,15 +14,18 @@
package org.apache.ambari.server.ldap.service.ads;
-import java.util.Set;
-
import javax.inject.Inject;
import javax.inject.Singleton;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
import org.apache.ambari.server.ldap.service.AmbariLdapException;
-import org.apache.ambari.server.ldap.service.AttributeDetector;
import org.apache.ambari.server.ldap.service.LdapAttributeDetectionService;
+import org.apache.ambari.server.ldap.service.ads.detectors.GroupMemberAttrDetector;
+import org.apache.ambari.server.ldap.service.ads.detectors.GroupNameAttrDetector;
+import org.apache.ambari.server.ldap.service.ads.detectors.GroupObjectClassDetector;
+import org.apache.ambari.server.ldap.service.ads.detectors.UserGroupMemberAttrDetector;
+import org.apache.ambari.server.ldap.service.ads.detectors.UserNameAttrDetector;
+import org.apache.ambari.server.ldap.service.ads.detectors.UserObjectClassDetector;
import org.apache.directory.api.ldap.model.cursor.SearchCursor;
import org.apache.directory.api.ldap.model.entry.Entry;
import org.apache.directory.api.ldap.model.message.Response;
@@ -37,24 +40,29 @@ import org.apache.directory.ldap.client.api.search.FilterBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.collect.Sets;
-
@Singleton
public class DefaultAttributeDetectionService implements LdapAttributeDetectionService<LdapConnection> {
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAttributeDetectionService.class);
private static final int SAMPLE_RESULT_SIZE = 50;
- // ordered list of possible username attribute values (the most significant valus should be first)
- private static final Set<String> USER_OBJECT_CLASS_VALUES = Sets.newHashSet("person", "posixAccount");
- private static final Set<String> USER_GROUP_MEMBER_ATTR_VALUES = Sets.newHashSet("memberOf", "ismemberOf");
+ @Inject
+ private UserNameAttrDetector userNameAttrDetector = new UserNameAttrDetector(); // todo remove instantition
+
+ @Inject
+ private UserObjectClassDetector userObjectClassDetector = new UserObjectClassDetector(); // todo remove instantition
@Inject
- private UserNameAttributeDetector userNameAttrDetector = new UserNameAttributeDetector(); // todo remove instantition
+ private UserGroupMemberAttrDetector userGroupMemberAttrDetector = new UserGroupMemberAttrDetector(); // todo remove instantition
@Inject
- private ObjectClassDetector objectClassDetector = new ObjectClassDetector(); // todo remove instantition
+ private GroupNameAttrDetector groupNameAttrDetector = new GroupNameAttrDetector(); // todo remove instantition
+
+ @Inject
+ private GroupObjectClassDetector groupObjectClassDetector = new GroupObjectClassDetector(); // todo remove instantition
+
+ private GroupMemberAttrDetector groupMemberAttrDetector = new GroupMemberAttrDetector(); // todo remove instantition
@Inject
public DefaultAttributeDetectionService() {
@@ -76,7 +84,7 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
// todo should the bind operation be done in the facade?
connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
- SearchRequest searchRequest = assembleSearchRequest(ambariLdapConfiguration);
+ SearchRequest searchRequest = assembleUserSearchRequest(ambariLdapConfiguration);
// do the search
searchCursor = connection.search(searchRequest);
@@ -95,15 +103,19 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
if (response instanceof SearchResultEntry) {
Entry resultEntry = ((SearchResultEntry) response).getEntry();
- LOGGER.info("Processing sample entry: [{}]", resultEntry.getDn());
+ LOGGER.info("Processing sample entry with dn: [{}]", resultEntry.getDn());
+
userNameAttrDetector.collect(resultEntry);
- objectClassDetector.collect(resultEntry);
+ userObjectClassDetector.collect(resultEntry);
+ userGroupMemberAttrDetector.collect(resultEntry);
+
processedUserCnt++;
}
}
ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE, userNameAttrDetector.detect());
- ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, objectClassDetector.detect());
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, userObjectClassDetector.detect());
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_GROUP_MEMBER_ATTRIBUTE, userGroupMemberAttrDetector.detect());
LOGGER.info("Decorated ambari ldap config : [{}]", ambariLdapConfiguration);
@@ -120,25 +132,72 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
return ambariLdapConfiguration;
}
- private void detectUserAttributes(Entry resultEntry, AttributeDetector attributeDetector) {
- attributeDetector.collect(resultEntry);
+ @Override
+ public AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection connection, AmbariLdapConfiguration ambariLdapConfiguration) {
+ LOGGER.info("Detecting LDAP group attributes ...");
-// Set<String> objectClasses = detectUserObjectClass(resultEntry);
-// if (!objectClasses.isEmpty()) {
-// ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS, StringUtils.join(objectClasses, ","));
-// }
+ // perform a search using the user search base
+ if (Strings.isEmpty(ambariLdapConfiguration.groupSearchBase())) {
+ LOGGER.warn("No group search base provided");
+ return ambariLdapConfiguration;
+ }
+ SearchCursor searchCursor = null;
- }
+ try {
+ // todo should the bind operation be done in the facade?
+ connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
- @Override
- public AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection connection, AmbariLdapConfiguration ambariLdapConfiguration) {
- LOGGER.info("Detecting LDAP group attributes ...");
- return null;
+ SearchRequest searchRequest = assembleGroupSearchRequest(ambariLdapConfiguration);
+
+ // do the search
+ searchCursor = connection.search(searchRequest);
+
+ int processedGroupCnt = 0;
+
+ while (searchCursor.next()) {
+
+ if (processedGroupCnt >= SAMPLE_RESULT_SIZE) {
+ LOGGER.debug("The maximum number of results for attribute detection has exceeded. Quit detection.");
+ break;
+ }
+
+ Response response = searchCursor.get();
+ // process the SearchResultEntry
+
+ if (response instanceof SearchResultEntry) {
+ Entry resultEntry = ((SearchResultEntry) response).getEntry();
+ LOGGER.info("Processing sample entry with dn: [{}]", resultEntry.getDn());
+
+ groupNameAttrDetector.collect(resultEntry);
+ groupObjectClassDetector.collect(resultEntry);
+ groupMemberAttrDetector.collect(resultEntry);
+
+ processedGroupCnt++;
+ }
+ }
+
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.GROUP_NAME_ATTRIBUTE, groupNameAttrDetector.detect());
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.GROUP_OBJECT_CLASS, groupObjectClassDetector.detect());
+ ambariLdapConfiguration.setValueFor(AmbariLdapConfiguration.AmbariLdapConfig.GROUP_MEMBER_ATTRIBUTE, groupMemberAttrDetector.detect());
+
+ LOGGER.info("Decorated ambari ldap config : [{}]", ambariLdapConfiguration);
+
+ } catch (Exception e) {
+
+ LOGGER.error("Ldap operation failed", e);
+ } finally {
+ // housekeeping
+ if (null != searchCursor) {
+ searchCursor.close();
+ }
+ }
+
+ return ambariLdapConfiguration;
}
- private SearchRequest assembleSearchRequest(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ private SearchRequest assembleUserSearchRequest(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
try {
SearchRequest req = new SearchRequestImpl();
@@ -157,18 +216,23 @@ public class DefaultAttributeDetectionService implements LdapAttributeDetectionS
}
}
+ private SearchRequest assembleGroupSearchRequest(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ try {
- private Set<String> detectUserObjectClass(Entry entry) {
- LOGGER.info("Detecting user object class. Attributes: {}", entry.getAttributes());
- throw new UnsupportedOperationException("Not yet implemented");
- }
+ SearchRequest req = new SearchRequestImpl();
+ req.setScope(SearchScope.SUBTREE);
+ req.addAttributes("*");
+ req.setTimeLimit(0);
+ req.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
+ // the filter must be set!
+ req.setFilter(FilterBuilder.present(ambariLdapConfiguration.dnAttribute()).toString());
- private String detectGroupNameAttribute(Entry entry) {
- throw new UnsupportedOperationException("Not yet implemented");
- }
+ return req;
- private Set<String> detectGroupObjectClass(Entry entry) {
- throw new UnsupportedOperationException("Not yet implemented");
+ } catch (Exception e) {
+ LOGGER.error("Could not assemble ldap search request", e);
+ throw new AmbariLdapException(e);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
deleted file mode 100644
index 2613517..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/ObjectClassDetector.java
+++ /dev/null
@@ -1,81 +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.service.ads;
-
-import java.util.Map;
-
-import javax.inject.Inject;
-
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-public class ObjectClassDetector extends OccurranceAndWeightBasedDetector {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(ObjectClassDetector.class);
- private Map<String, Integer> occurranceMap = Maps.newHashMap();
- private Map<String, Integer> weightsMap = Maps.newHashMap();
-
-
- private enum ObjectClassValue {
- PERSON("person", 1),
- POSIX_ACCOUNT("posixAccount", 1);
-
- private String ocVal;
- private Integer weight;
-
- ObjectClassValue(String attr, Integer weght) {
- this.ocVal = attr;
- this.weight = weght;
- }
-
- Integer weight() {
- return this.weight;
- }
-
- String ocVal() {
- return this.ocVal;
- }
-
- }
-
- @Inject
- public ObjectClassDetector() {
- for (ObjectClassValue ocVal : ObjectClassValue.values()) {
- occurranceMap.put(ocVal.ocVal(), 0);
- weightsMap.put(ocVal.ocVal(), ocVal.weight());
- }
-
- }
-
- @Override
- protected Map<String, Integer> occurranceMap() {
- return occurranceMap;
- }
-
- @Override
- protected Map<String, Integer> weightsMap() {
- return weightsMap;
- }
-
- @Override
- protected boolean applies(Entry entry, String value) {
- LOGGER.info("Checking for object class [{}] in entry [{}]", value, entry.getDn());
- return entry.hasObjectClass(value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
deleted file mode 100644
index 32dc238..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/OccurranceAndWeightBasedDetector.java
+++ /dev/null
@@ -1,81 +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.service.ads;
-
-import java.util.Map;
-
-import org.apache.ambari.server.ldap.service.AttributeDetector;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public abstract class OccurranceAndWeightBasedDetector implements AttributeDetector<Entry> {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(OccurranceAndWeightBasedDetector.class);
-
- protected abstract Map<String, Integer> occurranceMap();
-
- protected abstract Map<String, Integer> weightsMap();
-
- protected abstract boolean applies(Entry entry, String value);
-
- @Override
- public String detect() {
- Map.Entry<String, Integer> selectedEntry = null;
-
- for (Map.Entry<String, Integer> entry : occurranceMap().entrySet()) {
- if (selectedEntry == null) {
-
- selectedEntry = entry;
- LOGGER.info("Initial name attribute: {}", selectedEntry);
- continue;
-
- }
-
- if (selectedEntry.getValue() < entry.getValue()) {
-
- LOGGER.info("Changing potential name attribute from : [{}] to: [{}]", selectedEntry, entry);
- selectedEntry = entry;
-
- }
- }
- return selectedEntry.getKey();
- }
-
- @Override
- public void collect(Entry entry) {
- LOGGER.info("Detecting ldap attributes/values ...");
-
- for (String attributeValue : occurranceMap().keySet()) {
- if (applies(entry, attributeValue)) {
-
- Integer cnt = occurranceMap().get(attributeValue).intValue();
- if (weightsMap().containsKey(attributeValue)) {
- cnt = cnt + weightsMap().get(attributeValue);
- } else {
- cnt = cnt + 1;
- }
- occurranceMap().put(attributeValue, cnt);
-
- LOGGER.info("Collected potential name attr: {}, count: {}", attributeValue, cnt);
-
- } else {
- LOGGER.info("The result entry doesn't contain the attribute: [{}]", attributeValue);
- }
- }
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
deleted file mode 100644
index bbb4b43..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/UserNameAttributeDetector.java
+++ /dev/null
@@ -1,75 +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.service.ads;
-
-import java.util.Map;
-
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-public class UserNameAttributeDetector extends OccurranceAndWeightBasedDetector {
- private static final Logger LOGGER = LoggerFactory.getLogger(UserNameAttributeDetector.class);
-
- private Map<String, Integer> occurranceMap = Maps.newHashMap();
- private Map<String, Integer> weightsMap = Maps.newHashMap();
-
- private enum NameAttrs {
- SAM_ACCOUNT_NAME("sAMAccountName", 5),
- UID("uid", 3),
- CN("cn", 1);
-
- private String attrName;
- private Integer weight;
-
- NameAttrs(String attr, Integer weght) {
- this.attrName = attr;
- this.weight = weght;
- }
-
- Integer weight() {
- return this.weight;
- }
-
- String attrName() {
- return this.attrName;
- }
-
- }
-
- public UserNameAttributeDetector() {
- for (NameAttrs nameAttr : NameAttrs.values()) {
- occurranceMap.put(nameAttr.attrName(), 0);
- weightsMap.put(nameAttr.attrName(), nameAttr.weight());
- }
- }
-
- protected Map<String, Integer> occurranceMap() {
- return occurranceMap;
- }
-
- protected Map<String, Integer> weightsMap() {
- return weightsMap;
- }
-
- @Override
- protected boolean applies(Entry entry, String value) {
- LOGGER.info("Checking for attribute [{}] in entry [{}]", value, entry.getDn());
- return entry.containsAttribute(value);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
new file mode 100644
index 0000000..6931736
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupMemberAttrDetector.java
@@ -0,0 +1,56 @@
+/*
+ * 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.service.ads.detectors;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+
+public class GroupMemberAttrDetector extends OccurranceAndWeightBasedDetector {
+
+ private enum GroupMemberAttr {
+
+ MEMBER("member", 1),
+ MEMBER_UID("memberUid", 1),
+ UNIQUE_MEMBER("uniqueMember", 1);
+
+ private String attrName;
+ private Integer weight;
+
+ GroupMemberAttr(String attr, Integer weght) {
+ this.attrName = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String attrName() {
+ return this.attrName;
+ }
+
+ }
+
+ public GroupMemberAttrDetector() {
+ for (GroupMemberAttr groupMemberAttr : GroupMemberAttr.values()) {
+ occurranceMap().put(groupMemberAttr.attrName(), 0);
+ weightsMap().put(groupMemberAttr.attrName(), groupMemberAttr.weight());
+ }
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ return entry.containsAttribute(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
new file mode 100644
index 0000000..f868383
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupNameAttrDetector.java
@@ -0,0 +1,61 @@
+/*
+ * 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.service.ads.detectors;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupNameAttrDetector extends OccurranceAndWeightBasedDetector {
+ private static final Logger LOGGER = LoggerFactory.getLogger(UserNameAttrDetector.class);
+
+ private enum GroupNameAttr {
+
+ DISTINGUISHED_NAME("distinguishedName", 1),
+
+ CN("cn", 1);
+
+ private String attrName;
+ private Integer weight;
+
+ GroupNameAttr(String attr, Integer weght) {
+ this.attrName = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String attrName() {
+ return this.attrName;
+ }
+
+ }
+
+ public GroupNameAttrDetector() {
+
+ for (GroupNameAttr groupNameAttr : GroupNameAttr.values()) {
+ occurranceMap().put(groupNameAttr.attrName(), 0);
+ weightsMap().put(groupNameAttr.attrName(), groupNameAttr.weight());
+ }
+ }
+
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ return entry.containsAttribute(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
new file mode 100644
index 0000000..fddc5a5
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/GroupObjectClassDetector.java
@@ -0,0 +1,64 @@
+/*
+ * 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.service.ads.detectors;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class GroupObjectClassDetector extends OccurranceAndWeightBasedDetector {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(GroupObjectClassDetector.class);
+
+ private enum ObjectClassValue {
+
+ GROUP("group", 1),
+
+ GROUP_OF_NAMES("groupOfNames", 1),
+
+ POSIX_GROUP("posixGroup", 1),
+
+ GROUP_OF_UNIQUE_NAMES("groupOfUniqueNames", 1);
+
+ private String ocVal;
+ private Integer weight;
+
+ ObjectClassValue(String attr, Integer weght) {
+ this.ocVal = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String ocVal() {
+ return this.ocVal;
+ }
+
+ }
+
+ public GroupObjectClassDetector() {
+ for (ObjectClassValue ocVal : ObjectClassValue.values()) {
+ occurranceMap().put(ocVal.ocVal(), 0);
+ weightsMap().put(ocVal.ocVal(), ocVal.weight());
+ }
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ return entry.hasObjectClass(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
new file mode 100644
index 0000000..8aaf6c1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/OccurranceAndWeightBasedDetector.java
@@ -0,0 +1,103 @@
+/*
+ * 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.service.ads.detectors;
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.service.AttributeDetector;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public abstract class OccurranceAndWeightBasedDetector implements AttributeDetector<Entry> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(OccurranceAndWeightBasedDetector.class);
+
+ private Map<String, Integer> occurranceMap = Maps.newHashMap();
+ private Map<String, Integer> weightsMap = Maps.newHashMap();
+
+ protected Map<String, Integer> occurranceMap() {
+ return occurranceMap;
+ }
+
+ protected Map<String, Integer> weightsMap() {
+ return weightsMap;
+ }
+
+
+ protected abstract boolean applies(Entry entry, String value);
+
+ @Override
+ public String detect() {
+ LOGGER.info("Calculating the most probable attribute/value ...");
+ Map.Entry<String, Integer> selectedEntry = null;
+
+ for (Map.Entry<String, Integer> entry : occurranceMap().entrySet()) {
+ if (selectedEntry == null) {
+
+ selectedEntry = entry;
+ LOGGER.debug("Initial attribute / value entry: {}", selectedEntry);
+ continue;
+
+ }
+
+ if (selectedEntry.getValue() < entry.getValue()) {
+
+ LOGGER.info("Changing potential attribute / value entry from : [{}] to: [{}]", selectedEntry, entry);
+ selectedEntry = entry;
+
+ }
+ }
+
+ // check whether the selected entry is valid (has occured in the sample result set)
+ String detectedVal = "N/A";
+
+ if (selectedEntry.getValue() > 0) {
+ detectedVal = selectedEntry.getKey();
+ } else {
+ LOGGER.warn("Unable to detect attribute or attribute value");
+ }
+
+ LOGGER.info("Detected attribute or value: [{}]", detectedVal);
+ return detectedVal;
+ }
+
+ @Override
+ public void collect(Entry entry) {
+ LOGGER.info("Collecting ldap attributes/values form entry with dn: [{]]", entry.getDn());
+
+ for (String attributeValue : occurranceMap().keySet()) {
+ if (applies(entry, attributeValue)) {
+
+ Integer cnt = occurranceMap().get(attributeValue).intValue();
+ if (weightsMap().containsKey(attributeValue)) {
+ cnt = cnt + weightsMap().get(attributeValue);
+ } else {
+ cnt = cnt + 1;
+ }
+ occurranceMap().put(attributeValue, cnt);
+
+ LOGGER.info("Collected potential name attr: {}, count: {}", attributeValue, cnt);
+
+ } else {
+ LOGGER.info("The result entry doesn't contain the attribute: [{}]", attributeValue);
+ }
+ }
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
new file mode 100644
index 0000000..c3f2ab4
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserGroupMemberAttrDetector.java
@@ -0,0 +1,56 @@
+/*
+ * 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.service.ads.detectors;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+
+public class UserGroupMemberAttrDetector extends OccurranceAndWeightBasedDetector {
+ private static String[] userGroupMemAttrValues = {"memberOf", "ismemberOf"};
+
+ private enum UserGroupMemberAttr {
+
+ MEMBER_OF("memberOf", 1),
+ IS_MEMBER_OF("ismemberOf", 1);
+
+ private String attrName;
+ private Integer weight;
+
+ UserGroupMemberAttr(String attr, Integer weght) {
+ this.attrName = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String attrName() {
+ return this.attrName;
+ }
+
+ }
+
+ public UserGroupMemberAttrDetector() {
+ for (UserGroupMemberAttr userGroupMemberAttr : UserGroupMemberAttr.values()) {
+ occurranceMap().put(userGroupMemberAttr.attrName(), 0);
+ weightsMap().put(userGroupMemberAttr.attrName(), userGroupMemberAttr.weight);
+ }
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ return entry.containsAttribute(value);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
new file mode 100644
index 0000000..40bf09b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserNameAttrDetector.java
@@ -0,0 +1,60 @@
+/*
+ * 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.service.ads.detectors;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserNameAttrDetector extends OccurranceAndWeightBasedDetector {
+ private static final Logger LOGGER = LoggerFactory.getLogger(UserNameAttrDetector.class);
+
+ private enum UserNameAttrs {
+ SAM_ACCOUNT_NAME("sAMAccountName", 5),
+ UID("uid", 3),
+ CN("cn", 1);
+
+ private String attrName;
+ private Integer weight;
+
+ UserNameAttrs(String attr, Integer weght) {
+ this.attrName = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String attrName() {
+ return this.attrName;
+ }
+
+ }
+
+ public UserNameAttrDetector() {
+ for (UserNameAttrs nameAttr : UserNameAttrs.values()) {
+ occurranceMap().put(nameAttr.attrName(), 0);
+ weightsMap().put(nameAttr.attrName(), nameAttr.weight());
+ }
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ LOGGER.info("Checking for attribute [{}] in entry [{}]", value, entry.getDn());
+ return entry.containsAttribute(value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
new file mode 100644
index 0000000..97b3c52
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/detectors/UserObjectClassDetector.java
@@ -0,0 +1,64 @@
+/*
+ * 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.service.ads.detectors;
+
+import javax.inject.Inject;
+
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class UserObjectClassDetector extends OccurranceAndWeightBasedDetector {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(UserObjectClassDetector.class);
+
+ private enum ObjectClassValue {
+ PERSON("person", 1),
+ POSIX_ACCOUNT("posixAccount", 1);
+
+ private String ocVal;
+ private Integer weight;
+
+ ObjectClassValue(String attr, Integer weght) {
+ this.ocVal = attr;
+ this.weight = weght;
+ }
+
+ Integer weight() {
+ return this.weight;
+ }
+
+ String ocVal() {
+ return this.ocVal;
+ }
+
+ }
+
+ @Inject
+ public UserObjectClassDetector() {
+ for (ObjectClassValue ocVal : ObjectClassValue.values()) {
+ occurranceMap().put(ocVal.ocVal(), 0);
+ weightsMap().put(ocVal.ocVal(), ocVal.weight());
+ }
+
+ }
+
+ @Override
+ protected boolean applies(Entry entry, String value) {
+ LOGGER.info("Checking for object class [{}] in entry [{}]", value, entry.getDn());
+ return entry.hasObjectClass(value);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/ac71c44c/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
index 5cddf1a..08f2d6c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
@@ -32,6 +32,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
public class DefaultAttributeDetectionServiceTest {
@@ -78,9 +80,12 @@ public class DefaultAttributeDetectionServiceTest {
// WHEN
AmbariLdapConfiguration config = attributeDetectionService.detectLdapUserAttributes(ldapConnection, ambariLdapConfiguration);
+ config = attributeDetectionService.detectLdapGroupAttributes(ldapConnection, ambariLdapConfiguration);
- // THEN
+ Gson gson = new GsonBuilder().create();
+ LOGGER.info(gson.toJson(config));
+ // THEN
ldapConnection.close();
}
@@ -95,9 +100,8 @@ public class DefaultAttributeDetectionServiceTest {
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_PASSWORD.key(), "password");
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.DN_ATTRIBUTE.key(), SchemaConstants.CN_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(), SchemaConstants.UID_AT);
ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_SEARCH_BASE.key(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.GROUP_SEARCH_BASE.key(), "dc=example,dc=com");
return ldapPropsMap;
[15/38] ambari git commit: AMBARI-21947. Ambari updates
database/tables location from intended remote HDFS to local HDFS (aonishuk)
Posted by lp...@apache.org.
AMBARI-21947. Ambari updates database/tables location from intended remote HDFS to local HDFS (aonishuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/18ae06d3
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/18ae06d3
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/18ae06d3
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 18ae06d3e49c98f919b666deca7c42b460ee204f
Parents: fa0ecc4
Author: Andrew Onishuk <ao...@hortonworks.com>
Authored: Wed Sep 13 14:27:24 2017 +0300
Committer: Andrew Onishuk <ao...@hortonworks.com>
Committed: Wed Sep 13 14:27:24 2017 +0300
----------------------------------------------------------------------
.../HIVE/0.12.0.2.0/package/scripts/hive_service.py | 4 ++++
.../HIVE/0.12.0.2.0/package/scripts/params_linux.py | 3 +++
.../resources/stacks/HDP/2.0.6/configuration/cluster-env.xml | 6 ++++++
3 files changed, 13 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/18ae06d3/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
index 1f2b644..2412bf9 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/hive_service.py
@@ -168,6 +168,10 @@ def validate_connection(target_path_to_jdbc, hive_lib_path):
def check_fs_root(conf_dir, execution_path):
import params
+ if not params.manage_hive_fsroot:
+ Logger.info("Skipping fs root check as cluster-env/manage_hive_fsroot is disabled")
+ return
+
if not params.fs_root.startswith("hdfs://"):
Logger.info("Skipping fs root check as fs_root does not start with hdfs://")
return
http://git-wip-us.apache.org/repos/asf/ambari/blob/18ae06d3/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
index 9ba1f99..ceeac79 100644
--- a/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
+++ b/ambari-server/src/main/resources/common-services/HIVE/0.12.0.2.0/package/scripts/params_linux.py
@@ -867,3 +867,6 @@ druid_storage_dir = ""
if 'druid-common' in config['configurations'] \
and 'druid.storage.storageDirectory' in config['configurations']['druid-common']:
druid_storage_dir = config['configurations']['druid-common']['druid.storage.storageDirectory']
+
+
+manage_hive_fsroot = default('/configurations/cluster-env/manage_hive_fsroot', True)
http://git-wip-us.apache.org/repos/asf/ambari/blob/18ae06d3/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
index 45f3b42..55b9cd3 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
@@ -357,4 +357,10 @@ gpgcheck=0</value>
<description>Timeout for safemode exit, during namenode rolling restart</description>
<on-ambari-upgrade add="true"/>
</property>
+ <property>
+ <name>manage_hive_fsroot</name>
+ <value>true</value>
+ <description>If flag is set to true, ambari will manage fsroot for Hive, by setting it to fs.defautlFS of local HDFS</description>
+ <on-ambari-upgrade add="false"/>
+ </property>
</configuration>
[29/38] ambari git commit: AMBARI-21307 Draft implementation of the
group related attributes
Posted by lp...@apache.org.
AMBARI-21307 Draft implementation of the group related attributes
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/3ad545a4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/3ad545a4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/3ad545a4
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 3ad545a4620e1f0f27d109a1dbc5631012c624d9
Parents: 43dbbc9
Author: lpuskas <lp...@apache.org>
Authored: Tue Aug 8 13:54:29 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:30 2017 +0200
----------------------------------------------------------------------
.../server/ldap/AmbariLdapConfiguration.java | 22 +-
.../ldap/LdapConfigurationValidatorService.java | 34 +--
.../apache/ambari/server/ldap/LdapModule.java | 4 +-
.../server/ldap/service/AmbariLdapFacade.java | 25 +-
.../ldap/service/LdapConnectionService.java | 35 +++
.../ambari/server/ldap/service/LdapFacade.java | 9 +-
.../ad/AdLdapConfigurationValidatorService.java | 177 --------------
...efaultLdapConfigurationValidatorService.java | 232 +++++++++++++++++++
.../ad/DefaultLdapConnectionService.java | 63 +++++
.../service/ad/LdapConfigurationConverter.java | 50 ----
...AdLdapConfigurationValidatorServiceTest.java | 129 -----------
...ltLdapConfigurationValidatorServiceTest.java | 156 +++++++++++++
12 files changed, 552 insertions(+), 384 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index 519f400..a6ff80b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -53,7 +53,7 @@ public class AmbariLdapConfiguration {
GROUP_OBJECT_CLASS("ambari.ldap.group.object.class"),
GROUP_NAME_ATTRIBUTE("ambari.ldap.group.name.attribute"),
GROUP_MEMBER_ATTRIBUTE("ambari.ldap.group.member.attribute"),
- GROUP_SEARCH_BASE("ambari.ldap.group.member.attribute"),
+ GROUP_SEARCH_BASE("ambari.ldap.group.search.base"),
DN_ATTRIBUTE("authentication.ldap.dnAttribute");
private String propertyName;
@@ -126,4 +126,24 @@ public class AmbariLdapConfiguration {
return (String) configurationValue(LdapConfigProperty.USER_NAME_ATTRIBUTE);
}
+ public String userSearchBase() {
+ return (String) configurationValue(LdapConfigProperty.USER_SEARCH_BASE);
+ }
+
+ public String groupObjectClass() {
+ return (String) configurationValue(LdapConfigProperty.GROUP_OBJECT_CLASS);
+ }
+
+ public String groupNameAttribute() {
+ return (String) configurationValue(LdapConfigProperty.GROUP_NAME_ATTRIBUTE);
+ }
+
+ public String groupMemberAttribute() {
+ return (String) configurationValue(LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE);
+ }
+
+ public String groupSearchBase() {
+ return (String) configurationValue(LdapConfigProperty.GROUP_SEARCH_BASE);
+ }
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
index 4667721..7efa3b7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
@@ -14,8 +14,11 @@
package org.apache.ambari.server.ldap;
+import java.util.Set;
+
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.directory.ldap.client.api.LdapConnection;
/**
* Collection of operations for validating ldap configuration.
@@ -26,27 +29,32 @@ public interface LdapConfigurationValidatorService {
/**
* Tests the connection based on the provided configuration.
*
- * @param configuration the ambari ldap configuration instance
+ * @param ldapConnection connection instance
+ * @param configuration the ambari ldap configuration instance
* @throws AmbariLdapException if the connection is not possible
*/
- void checkConnection(AmbariLdapConfiguration configuration) throws AmbariLdapException;
+ void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration configuration) throws AmbariLdapException;
+
/**
- * Checks whether the group related LDAP attributes in the configuration are correct.
+ * Implements LDAP user related configuration settings validation logic.
+ * Implementers communicate with the LDAP server (search, bind) to validate attributes in the provided configuration
+ * instance
*
- * @param configuration the configuration instance holding the available properties
- * @throws AmbariException if the attributes are not valid
+ * @param ldapConnection connection instance used to connect to the LDAP server
+ * @param testUserName the test username
+ * @param testPassword the test password
+ * @param configuration the available ldap configuration
+ * @return The DN of the found user entry
+ * @throws AmbariException if the connection couldn't be estabilisheds
*/
- void checkGroupAttributes(AmbariLdapConfiguration configuration) throws AmbariException;
+ String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration configuration) throws AmbariLdapException;
/**
- * Tries to connect to the LDAP server with the given credentials.
- * Primarily used for testing the user before performing other operations (eg. attribute detection)s
+ * Checks whether the group related LDAP attributes in the configuration are correct.
*
- * @param username the username
- * @param password the password
- * @param configuration the available ldap configuration
- * @throws AmbariException if the connection couldn't be estabilished
+ * @throws AmbariException if the attributes are not valid
*/
- void checkUserAttributes(String username, String password, AmbariLdapConfiguration configuration) throws AmbariException;
+ Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/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 625ce8b..545f220 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
@@ -17,7 +17,7 @@ package org.apache.ambari.server.ldap;
import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
import org.apache.ambari.server.ldap.service.LdapFacade;
-import org.apache.ambari.server.ldap.service.ad.AdLdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.ad.DefaultLdapConfigurationValidatorService;
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
@@ -30,7 +30,7 @@ public class LdapModule extends AbstractModule {
@Override
protected void configure() {
bind(LdapFacade.class).to(AmbariLdapFacade.class);
- bind(LdapConfigurationValidatorService.class).to(AdLdapConfigurationValidatorService.class);
+ bind(LdapConfigurationValidatorService.class).to(DefaultLdapConfigurationValidatorService.class);
install(new FactoryModuleBuilder().build(LdapConfigurationFactory.class));
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index abd028a..abb464b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -16,13 +16,14 @@
package org.apache.ambari.server.ldap.service;
import java.util.Map;
+import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
-import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.directory.ldap.client.api.LdapConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -51,17 +52,21 @@ public class AmbariLdapFacade implements LdapFacade {
private LdapConfigurationValidatorService ldapConfigurationValidatorService;
@Inject
+ private LdapConnectionService ldapConnectionService;
+
+ @Inject
public AmbariLdapFacade() {
}
@Override
- public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException {
+ public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
try {
LOGGER.info("Validating LDAP connection related configuration based on: {}", ambariLdapConfiguration);
- ldapConfigurationValidatorService.checkConnection(ambariLdapConfiguration);
+ LdapConnection connection = ldapConnectionService.createLdapConnection(ambariLdapConfiguration);
+ ldapConfigurationValidatorService.checkConnection(connection, ambariLdapConfiguration);
} catch (AmbariLdapException e) {
LOGGER.error("Validating LDAP connection configuration failed", e);
- throw new AmbariException("Validating LDAP connection configuration failed", e);
+ throw e;
}
LOGGER.info("Validating LDAP connection related configuration: SUCCESS");
}
@@ -74,7 +79,7 @@ public class AmbariLdapFacade implements LdapFacade {
}
@Override
- public void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariException {
+ public void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
String userName = getTestUserNameFromParameters(parameters);
String testUserPass = getTestUserPasswordFromParameters(parameters);
@@ -82,8 +87,14 @@ public class AmbariLdapFacade implements LdapFacade {
throw new IllegalArgumentException("No test user available for testing LDAP attributes");
}
- LOGGER.info("Testing LDAP attributes with test user: {}", userName);
- ldapConfigurationValidatorService.checkUserAttributes(userName, testUserPass, ldapConfiguration);
+ LdapConnection ldapConnection = ldapConnectionService.createLdapConnection(ldapConfiguration);
+
+ LOGGER.info("Testing LDAP user attributes with test user: {}", userName);
+ String userDn = ldapConfigurationValidatorService.checkUserAttributes(ldapConnection, userName, testUserPass, ldapConfiguration);
+
+ LOGGER.info("Testing LDAP group attributes with test user dn: {}", userDn);
+ Set<String> groups = ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, userDn, ldapConfiguration);
+
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
new file mode 100644
index 0000000..50ee8ed
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapConnectionService.java
@@ -0,0 +1,35 @@
+/*
+ * 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.service;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+
+/**
+ * Contract defining factory methods for creating LDAP connection instances.
+ * Implementers contain the logic of creating different connection instances and the afferent boilerplate code.
+ */
+public interface LdapConnectionService {
+
+ /**
+ * Creates an LdapConnection instance based on the provided configuration
+ *
+ * @param ambariLdapConfiguration configuration instance with information for creating the connection instance
+ * @return a set up LdapConnection instance
+ */
+ LdapNetworkConnection createLdapConnection(AmbariLdapConfiguration ambariLdapConfiguration);
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
index 38553f0..7bb1198 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -16,7 +16,6 @@ package org.apache.ambari.server.ldap.service;
import java.util.Map;
-import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
/**
@@ -29,9 +28,9 @@ public interface LdapFacade {
* Tests the connection to the LDAP server based on the provided configuration.
*
* @param ambariLdapConfiguration the available ldap related configuration
- * @throws AmbariException if the connection fails or other problems occur during the operation
+ * @throws AmbariLdapException if the connection fails or other problems occur during the operation
*/
- void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException;
+ void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
/**
@@ -46,7 +45,7 @@ public interface LdapFacade {
*
* @param parameters a map of property name and value pairs holding information to facilitate checking the attributes
* @param ambariLdapConfiguration configutration instance with available attributes
- * @throws AmbariException if the attribute checking fails
+ * @throws AmbariLdapException if the attribute checking fails
*/
- void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException;
+ void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java
deleted file mode 100644
index 11e8655..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java
+++ /dev/null
@@ -1,177 +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.service.ad;
-
-import java.io.IOException;
-import java.util.List;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
-import org.apache.ambari.server.ldap.service.AmbariLdapException;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.apache.directory.ldap.client.api.search.FilterBuilder;
-import org.apache.directory.shared.ldap.constants.SchemaConstants;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Lists;
-
-/**
- * Implementation of the validation logic using the Apache Directory API.
- */
-@Singleton
-public class AdLdapConfigurationValidatorService implements LdapConfigurationValidatorService {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(AdLdapConfigurationValidatorService.class);
-
- @Inject
- private LdapConfigurationConverter ldapConfigurationConverter;
-
- /**
- * Facilitating the instantiation
- */
- @Inject
- public AdLdapConfigurationValidatorService() {
- }
-
- @Override
- public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- try {
- LOGGER.info("Testing the connection based on the configuration: {}", ambariLdapConfiguration);
-
- LdapConnectionConfig connectionConfig = ldapConfigurationConverter.getLdapConnectionConfig(ambariLdapConfiguration);
- LdapNetworkConnection connection = new LdapNetworkConnection(connectionConfig);
-
- if (ambariLdapConfiguration.bindAnonimously()) {
- LOGGER.debug("Binding anonimously ...");
- connection.bind();
- } else {
- LOGGER.debug("Binding with manager DN and manager password ...");
- connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
- }
-
- if (connection.isConnected()) {
- LOGGER.info("Successfully connected to the LDAP server.");
- }
-
- connection.close();
-
- } catch (Exception e) {
- LOGGER.warn("Could not bind to the LDAP server base don the provided configuration ...");
- throw new AmbariLdapException(e);
- }
- }
-
-
- /**
- * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
- * Attributes are considered correct if there is at least one entry found.
- *
- * Invalid attributes are signaled by throwing an exception.
- *
- * @param username the username
- * @param password the password
- * @param ambariLdapConfiguration configuration instance holding ldap configuration details
- * @throws AmbariException if the attributes are not valid or any errors occurs
- */
- @Override
- public void checkUserAttributes(String username, String password, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException {
- LdapNetworkConnection connection = null;
- SearchCursor searchCursor = null;
- try {
- LOGGER.info("Checking user attributes for user {} r ...", username);
-
- LdapConnectionConfig connectionConfig = ldapConfigurationConverter.getLdapConnectionConfig(ambariLdapConfiguration);
- connection = new LdapNetworkConnection(connectionConfig);
-
-
- if (!ambariLdapConfiguration.bindAnonimously()) {
- LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
- connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
- } else {
- LOGGER.debug("Binding anonimously ...");
- connection.bind();
- }
-
- if (!connection.isConnected()) {
- LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
- throw new IllegalStateException("The connection to the LDAP server is not alive");
- }
-
- // set up a filter based on the provided attributes
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), username))
- .toString();
-
- LOGGER.info("Searching for the user: {} using the search filter: {}", username, filter);
- EntryCursor entryCursor = connection.search(new Dn(ambariLdapConfiguration.baseDn()), filter, SearchScope.SUBTREE);
-
- // collecting search result entries
- List<Entry> users = Lists.newArrayList();
- for (Entry entry : entryCursor) {
- users.add(entry);
- }
-
- // there should be at least one user found
- if (users.isEmpty()) {
- String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
- LOGGER.error(msg);
- throw new Exception(msg);
- }
-
- LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
-
- } catch (Exception e) {
-
- LOGGER.error("Error while checking user attributes.");
- throw new AmbariException("Error while checking user attributes", e);
-
- } finally {
-
- LOGGER.debug("Closing the connection and searchresult ...");
-
- if (null != searchCursor) {
- searchCursor.close();
- }
-
- if (null != connection) {
- try {
- connection.close();
- } catch (IOException e) {
- LOGGER.error("Exception occurred while closing the connection", e);
- }
- }
-
- }
- }
-
- @Override
- public void checkGroupAttributes(AmbariLdapConfiguration configuration) throws AmbariException {
-
- }
-
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
new file mode 100644
index 0000000..838ef4c
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
@@ -0,0 +1,232 @@
+/*
+ * 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.service.ad;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.codec.decorators.SearchResultEntryDecorator;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+
+/**
+ * Implementation of the validation logic using the Apache Directory API.
+ */
+@Singleton
+public class DefaultLdapConfigurationValidatorService implements LdapConfigurationValidatorService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
+
+ @Inject
+ private LdapConnectionService ldapConnectionService;
+
+ /**
+ * Facilitating the instantiation
+ */
+ @Inject
+ public DefaultLdapConfigurationValidatorService() {
+ }
+
+ @Override
+ public void checkConnection(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ try {
+ bind(ambariLdapConfiguration, ldapConnection);
+ } catch (LdapException e) {
+ LOGGER.error("Could not connect to the LDAP server", e);
+ throw new AmbariLdapException(e);
+ }
+ }
+
+
+ /**
+ * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
+ * Attributes are considered correct if there is at least one entry found.
+ *
+ * Invalid attributes are signaled by throwing an exception.
+ *
+ * @param testUserName the test username
+ * @param testPassword the test password
+ * @param ambariLdapConfiguration configuration instance holding ldap configuration details
+ * @throws AmbariException if the attributes are not valid or any errors occurs
+ */
+ @Override
+ public String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ LdapNetworkConnection connection = null;
+ SearchCursor searchCursor = null;
+ String userDn = null;
+ try {
+ LOGGER.info("Checking user attributes for user {} r ...", testUserName);
+
+ // bind anonimously or with manager data
+ bind(ambariLdapConfiguration, connection);
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), testUserName))
+ .toString();
+
+ LOGGER.info("Searching for the user: {} using the search filter: {}", testUserName, filter);
+ EntryCursor entryCursor = connection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
+
+ // collecting search result entries
+ List<Entry> users = Lists.newArrayList();
+ for (Entry entry : entryCursor) {
+ users.add(entry);
+ userDn = entry.getDn().getNormName();
+ }
+
+ // there should be at least one user found
+ if (users.isEmpty()) {
+ String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
+ LOGGER.error(msg);
+ throw new Exception(msg);
+ }
+
+ LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
+
+ } catch (Exception e) {
+
+ LOGGER.error("User attributes validation failed.", e);
+ throw new AmbariLdapException(e.getMessage(), e);
+
+ } finally {
+ closeResources(connection, searchCursor);
+ }
+ return userDn;
+ }
+
+
+ @Override
+ public Set<String> checkGroupAttributes(LdapConnection ldapConnection, String userDn, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ SearchCursor searchCursor = null;
+ Set<Response> groupResponses = Sets.newHashSet();
+
+ try {
+ LOGGER.info("Checking group attributes for user dn {} ...", userDn);
+
+ bind(ambariLdapConfiguration, ldapConnection);
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.groupObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.groupMemberAttribute(), userDn)
+ ).toString();
+
+ LOGGER.info("Searching for the groups the user dn: {} is member of using the search filter: {}", userDn, filter);
+
+ // assemble a search request
+ SearchRequest searchRequest = new SearchRequestImpl();
+ searchRequest.setFilter(filter);
+ searchRequest.setBase(new Dn(ambariLdapConfiguration.groupSearchBase()));
+ searchRequest.setScope(SearchScope.SUBTREE);
+ searchRequest.addAttributes(ambariLdapConfiguration.groupMemberAttribute(), ambariLdapConfiguration.groupNameAttribute());
+
+ // perform the search
+ searchCursor = ldapConnection.search(searchRequest);
+
+ for (Response response : searchCursor) {
+ groupResponses.add(response);
+ }
+
+ } catch (Exception e) {
+
+ LOGGER.error("User attributes validation failed.", e);
+ throw new AmbariLdapException(e.getMessage(), e);
+
+ } finally {
+
+ closeResources(ldapConnection, searchCursor);
+
+ }
+
+ return processGroupResults(groupResponses, ambariLdapConfiguration);
+ }
+
+ private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
+ LOGGER.info("Connecting to LDAP ....");
+ if (!ambariLdapConfiguration.bindAnonimously()) {
+ LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
+ connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
+ } else {
+ LOGGER.debug("Binding anonimously ...");
+ connection.bind();
+ }
+
+ if (!connection.isConnected()) {
+ LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
+ throw new IllegalStateException("The connection to the LDAP server is not alive");
+ }
+ LOGGER.info("Connected to LDAP.");
+ }
+
+
+ private Set<String> processGroupResults(Set<Response> groupResponses, AmbariLdapConfiguration ambariLdapConfiguration) {
+ Set<String> groupStrSet = Sets.newHashSet();
+ for (Response response : groupResponses) {
+ Entry entry = ((SearchResultEntryDecorator) response).getEntry();
+ groupStrSet.add(entry.get(ambariLdapConfiguration.groupNameAttribute()).get().getString());
+ }
+
+ LOGGER.debug("Extracted group names from group search responses: {}", groupStrSet);
+ return groupStrSet;
+ }
+
+ private void closeResources(LdapConnection connection, SearchCursor searchCursor) {
+ LOGGER.debug("Housekeeping: closing the connection and the search cursor ...");
+
+ if (null != searchCursor) {
+ // this method is idempotent
+ searchCursor.close();
+ }
+
+ if (null != connection) {
+ try {
+ connection.close();
+ } catch (IOException e) {
+ LOGGER.error("Exception occurred while closing the connection", e);
+ }
+ }
+ }
+
+}
+
+
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
new file mode 100644
index 0000000..b5559d9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
@@ -0,0 +1,63 @@
+/*
+ * 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.ldap.service.ad;
+
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class DefaultLdapConnectionService implements LdapConnectionService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConnectionService.class);
+
+ @Override
+ public LdapNetworkConnection createLdapConnection(AmbariLdapConfiguration ambariLdapConfiguration) {
+ LOGGER.debug("Creating ldap connection instance from: {}", ambariLdapConfiguration);
+ return new LdapNetworkConnection(getLdapConnectionConfig(ambariLdapConfiguration));
+ }
+
+ private LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration ambariAmbariLdapConfiguration) {
+ LOGGER.debug("Creating a configuration instance based on the ambari configuration: {}", ambariAmbariLdapConfiguration);
+
+ LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
+ ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.ldapServerHost());
+ ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
+ ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
+
+ //todo set the other values as required
+ return ldapConnectionConfig;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java
deleted file mode 100644
index a8839f1..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java
+++ /dev/null
@@ -1,50 +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.service.ad;
-
-import javax.inject.Singleton;
-
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Converts between ambari specific ldap types and the 3rd party ldap library
- */
-@Singleton
-public class LdapConfigurationConverter {
-
- private static final Logger LOGGER = LoggerFactory.getLogger(LdapConfigurationConverter.class);
-
- /**
- * Creates a {@link LdapConnectionConfig} instance based on the provided ambari specific configurations
- *
- * @param ambariAmbariLdapConfiguration
- * @return
- */
- public LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration ambariAmbariLdapConfiguration) {
- LOGGER.debug("Creating a configuration instance based on the ambari configuration: {}", ambariAmbariLdapConfiguration);
-
- LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
- ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.ldapServerHost());
- ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
- ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
-
- //todo set the other values as required
- return ldapConnectionConfig;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java
deleted file mode 100644
index 0f57099..0000000
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java
+++ /dev/null
@@ -1,129 +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.service.ad;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.util.Map;
-
-import org.apache.ambari.server.AmbariException;
-import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
-import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
-import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
-import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.Response;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchResultEntry;
-import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
-import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapConnectionConfig;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.apache.directory.ldap.client.api.search.FilterBuilder;
-import org.apache.directory.shared.ldap.constants.SchemaConstants;
-import org.junit.Test;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.collect.Maps;
-
-public class AdLdapConfigurationValidatorServiceTest {
- private static final Logger LOGGER = LoggerFactory.getLogger(AdLdapConfigurationValidatorService.class);
- private static final String TEST_USER = "Jocika10";
-
- LdapConfigurationValidatorService ldapConfigurationValidatorService = new AdLdapConfigurationValidatorService();
-
-
- @Test
- public void testCheckAttributes() throws Exception {
-
- // WHEN
- LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost("localhost");
- config.setLdapPort(389);
- LdapConnection connection = new LdapNetworkConnection(config);
-
- // THEN
- connection.anonymousBind();
-
-
- EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
-
- for (Entry entry : cursor) {
- assertNotNull(entry);
- System.out.println(entry);
- }
-
- cursor.close();
-
- }
-
- @Test
- public void testCheckUserAttributes() throws Exception {
- Map<String, Object> ldapPropsMap = Maps.newHashMap();
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), true);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "localhost");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=dev,dc=local");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
-
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
-
-
- try {
- LOGGER.info("Authenticating user {} against the LDAP server ...", TEST_USER);
- LdapConfigurationConverter ldapConfigurationConverter = new LdapConfigurationConverter();
-
- LdapConnectionConfig connectionConfig = ldapConfigurationConverter.getLdapConnectionConfig(ambariLdapConfiguration);
- LdapNetworkConnection connection = new LdapNetworkConnection(connectionConfig);
-
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), TEST_USER))
- .toString();
-
- SearchRequest searchRequest = new SearchRequestImpl();
- searchRequest.setBase(new Dn(ambariLdapConfiguration.baseDn()));
- searchRequest.setFilter(filter);
- searchRequest.setScope(SearchScope.SUBTREE);
-
- LOGGER.info("loking up user: {} based on the filtr: {}", TEST_USER, filter);
-
- connection.bind();
- SearchCursor searchCursor = connection.search(searchRequest);
-
- while (searchCursor.next()) {
- Response response = searchCursor.get();
-
- // process the SearchResultEntry
- if (response instanceof SearchResultEntry) {
- Entry resultEntry = ((SearchResultEntry) response).getEntry();
- System.out.println(resultEntry);
- }
- }
-
- searchCursor.close();
-
- } catch (Exception e) {
- throw new AmbariException("Error during user authentication check", e);
- }
-
- }
-
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/3ad545a4/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
new file mode 100644
index 0000000..5c9d304
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
@@ -0,0 +1,156 @@
+/*
+ * 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.service.ad;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchResultEntry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class DefaultLdapConfigurationValidatorServiceTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultLdapConfigurationValidatorService.class);
+ private static final String TEST_USER = "einstein";
+
+ LdapConfigurationValidatorService ldapConfigurationValidatorService = new DefaultLdapConfigurationValidatorService();
+
+
+ @Test
+ public void testCheckAttributes() throws Exception {
+
+ // WHEN
+ LdapConnectionConfig config = new LdapConnectionConfig();
+ config.setLdapHost("localhost");
+ config.setLdapPort(389);
+ LdapConnection connection = new LdapNetworkConnection(config);
+
+ // THEN
+ connection.anonymousBind();
+
+
+ EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
+
+ for (Entry entry : cursor) {
+ assertNotNull(entry);
+ System.out.println(entry);
+ }
+
+ cursor.close();
+
+ }
+
+ @Test
+ public void testCheckUserAttributes() throws Exception {
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), false);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+
+
+ try {
+ LOGGER.info("Authenticating user {} against the LDAP server ...", TEST_USER);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection connection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), TEST_USER))
+ .toString();
+
+ SearchRequest searchRequest = new SearchRequestImpl();
+ searchRequest.setBase(new Dn(ambariLdapConfiguration.baseDn()));
+ searchRequest.setFilter(filter);
+ searchRequest.setScope(SearchScope.SUBTREE);
+
+ LOGGER.info("loking up user: {} based on the filtr: {}", TEST_USER, filter);
+
+ connection.bind();
+ SearchCursor searchCursor = connection.search(searchRequest);
+
+ while (searchCursor.next()) {
+ Response response = searchCursor.get();
+
+ // process the SearchResultEntry
+ if (response instanceof SearchResultEntry) {
+ Entry resultEntry = ((SearchResultEntry) response).getEntry();
+ System.out.println(resultEntry);
+ }
+ }
+
+ searchCursor.close();
+
+ } catch (Exception e) {
+ throw new AmbariException("Error during user authentication check", e);
+ }
+
+ }
+
+ @Test
+ public void testRetrieveGorupsForuser() throws Exception {
+ // GIVEN
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+ ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, "uid=einstein,dc=example,dc=com", ambariLdapConfiguration);
+ }
+}
\ No newline at end of file
[19/38] ambari git commit: AMBARI-21941. Stack selection page does
not load the HDP stacks [Intermittent] (ncole)
Posted by lp...@apache.org.
AMBARI-21941. Stack selection page does not load the HDP stacks [Intermittent] (ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/16cc3a6e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/16cc3a6e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/16cc3a6e
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 16cc3a6ed6c5bd07c613433309322835e378d559
Parents: 2c10dc9
Author: Nate Cole <nc...@hortonworks.com>
Authored: Wed Sep 13 12:25:28 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Sep 13 12:25:50 2017 -0400
----------------------------------------------------------------------
.../ambari/server/stack/StackContext.java | 109 ++++++++--
.../apache/ambari/server/stack/StackModule.java | 48 +++-
.../apache/ambari/server/state/StackInfo.java | 1 -
.../server/state/stack/RepoUrlInfoCallable.java | 217 +++++++++++++++++++
.../server/state/stack/RepoVdfCallable.java | 161 ++++++++++++++
.../ComponentVersionCheckActionTest.java | 14 --
6 files changed, 510 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/16cc3a6e/ambari-server/src/main/java/org/apache/ambari/server/stack/StackContext.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackContext.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackContext.java
index db9d178..d430bb7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackContext.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackContext.java
@@ -18,18 +18,28 @@
package org.apache.ambari.server.stack;
-import java.io.File;
+import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
import org.apache.ambari.server.metadata.ActionMetadata;
import org.apache.ambari.server.orm.dao.MetainfoDAO;
-import org.apache.ambari.server.state.stack.LatestRepoCallable;
import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.ambari.server.state.stack.RepoUrlInfoCallable;
+import org.apache.ambari.server.state.stack.RepoUrlInfoCallable.RepoUrlInfoResult;
+import org.apache.ambari.server.state.stack.RepoVdfCallable;
+import org.apache.commons.collections.MapUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/**
* Provides external functionality to the Stack framework.
@@ -46,15 +56,12 @@ public class StackContext {
private ActionMetadata actionMetaData;
/**
- * Operating System families
- */
- private OsFamily osFamily;
-
- /**
* Executor used to get latest repo url's
*/
- private LatestRepoQueryExecutor repoUpdateExecutor = new LatestRepoQueryExecutor();
+ private LatestRepoQueryExecutor repoUpdateExecutor;
+ private final static Logger LOG = LoggerFactory.getLogger(StackContext.class);
+ private static final int THREAD_COUNT = 5;
/**
@@ -67,7 +74,7 @@ public class StackContext {
public StackContext(MetainfoDAO metaInfoDAO, ActionMetadata actionMetaData, OsFamily osFamily) {
this.metaInfoDAO = metaInfoDAO;
this.actionMetaData = actionMetaData;
- this.osFamily = osFamily;
+ repoUpdateExecutor = new LatestRepoQueryExecutor(osFamily);
}
/**
@@ -85,9 +92,8 @@ public class StackContext {
* @param url external repo information URL
* @param stack stack module
*/
- public void registerRepoUpdateTask(String url, StackModule stack) {
- repoUpdateExecutor.addTask(new LatestRepoCallable(url,
- new File(stack.getStackDirectory().getRepoDir()), stack.getModuleInfo(), osFamily));
+ public void registerRepoUpdateTask(URI uri, StackModule stack) {
+ repoUpdateExecutor.addTask(uri, stack);
}
/**
@@ -115,16 +121,16 @@ public class StackContext {
/**
* Registered tasks
*/
- private Collection<LatestRepoCallable> tasks = new ArrayList<>();
+ private Map<URI, RepoUrlInfoCallable> tasks = new HashMap<>();
/**
* Task futures
*/
- Collection<Future<Void>> futures = new ArrayList<>();
+ Collection<Future<?>> futures = new ArrayList<>();
/**
* Underlying executor
*/
- private ExecutorService executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+ private ExecutorService executor = Executors.newFixedThreadPool(THREAD_COUNT, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Stack Version Loading Thread");
@@ -132,22 +138,79 @@ public class StackContext {
});
+ private OsFamily m_family;
+
+ private LatestRepoQueryExecutor(OsFamily family) {
+ m_family = family;
+ }
+
/**
- * Add a task.
- *
- * @param task task to be added
+ * @param uri
+ * uri to load
+ * @param stackModule
+ * the stack module
*/
- public void addTask(LatestRepoCallable task) {
- tasks.add(task);
+ public void addTask(URI uri, StackModule stackModule) {
+ RepoUrlInfoCallable callable = null;
+ if (tasks.containsKey(uri)) {
+ callable = tasks.get(uri);
+ } else {
+ callable = new RepoUrlInfoCallable(uri);
+ tasks.put(uri, callable);
+ }
+
+ callable.addStack(stackModule);
}
/**
* Execute all tasks.
*/
public void execute() {
- for (LatestRepoCallable task : tasks) {
- futures.add(executor.submit(task));
+
+ long l = System.nanoTime();
+ List<Future<Map<StackModule, RepoUrlInfoResult>>> results = new ArrayList<>();
+
+ // !!! first, load the *_urlinfo.json files and block for completion
+ try {
+ results = executor.invokeAll(tasks.values(), 2, TimeUnit.MINUTES);
+ } catch (InterruptedException e) {
+ LOG.warn("Could not load urlinfo as the executor was interrupted", e);
+ return;
+ } finally {
+ LOG.info("Loaded urlinfo in " + TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - l) + "ms");
+ }
+
+ List<Map<StackModule, RepoUrlInfoResult>> urlInfoResults = new ArrayList<>();
+ // !!! now load all the VDF _by version_ in a new thread.
+ for (Future<Map<StackModule, RepoUrlInfoResult>> future : results) {
+ try {
+ urlInfoResults.add(future.get());
+ } catch (Exception e) {
+ LOG.error("Could not load repo results", e.getCause());
+ }
}
+
+ for (Map<StackModule, RepoUrlInfoResult> urlInfoResult : urlInfoResults) {
+ for (Entry<StackModule, RepoUrlInfoResult> entry : urlInfoResult.entrySet()) {
+ StackModule stackModule = entry.getKey();
+ RepoUrlInfoResult result = entry.getValue();
+
+ if (null != result) {
+ if (MapUtils.isNotEmpty(result.getManifest())) {
+ for (Entry<String, Map<String, URI>> manifestEntry : result.getManifest().entrySet()) {
+ futures.add(executor.submit(new RepoVdfCallable(stackModule, manifestEntry.getKey(),
+ manifestEntry.getValue(), m_family)));
+ }
+ }
+
+ if (MapUtils.isNotEmpty(result.getLatestVdf())) {
+ futures.add(executor.submit(
+ new RepoVdfCallable(stackModule, result.getLatestVdf(), m_family)));
+ }
+ }
+ }
+ }
+
executor.shutdown();
}
@@ -157,7 +220,7 @@ public class StackContext {
* @return true if all tasks have completed; false otherwise
*/
public boolean hasCompleted() {
- for (Future<Void> f : futures) {
+ for (Future<?> f : futures) {
if (! f.isDone()) {
return false;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16cc3a6e/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
index 3688727..6dc2b93 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/StackModule.java
@@ -19,6 +19,8 @@
package org.apache.ambari.server.stack;
import java.io.File;
+import java.net.URI;
+import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@@ -1143,10 +1145,52 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
stackInfo.getRepositories().addAll(serviceRepos);
if (null != rxml && null != rxml.getLatestURI() && stackRepos.size() > 0) {
- stackContext.registerRepoUpdateTask(rxml.getLatestURI(), this);
+ registerRepoUpdateTask(rxml);
}
}
+ private void registerRepoUpdateTask(RepositoryXml rxml) {
+ String latest = rxml.getLatestURI();
+ if (StringUtils.isBlank(latest)) {
+ return;
+ }
+
+ URI uri = getURI(this, latest);
+
+ if (null == uri) {
+ LOG.warn("Could not determine how to load stack {}-{} latest definition for {}",
+ stackInfo.getName(), stackInfo.getVersion(), latest);
+ return;
+ }
+
+ stackContext.registerRepoUpdateTask(uri, this);
+ }
+
+ /**
+ * @param module
+ * the stack module
+ * @param uriString
+ * the uri string
+ * @return a repo URI, even if it is relative-file based
+ */
+ public static URI getURI(StackModule module, String uriString) {
+
+ URI uri = null;
+ if (uriString.startsWith("http")) {
+ try {
+ uri = new URI(uriString);
+ } catch (URISyntaxException e) {
+ // should be logged later
+ }
+ } else if ('.' == uriString.charAt(0)) {
+ uri = new File(module.getStackDirectory().getRepoDir(), uriString).toURI();
+ } else {
+ uri = new File(uriString).toURI();
+ }
+
+ return uri;
+ }
+
/**
* Gets the service repos with duplicates filtered out. A service repo is considered duplicate if:
* <ul>
@@ -1233,7 +1277,7 @@ public class StackModule extends BaseModule<StackModule, StackInfo> implements V
if (null != serviceRepoXml) {
repos.addAll(serviceRepoXml.getRepositories());
if (null != serviceRepoXml.getLatestURI()) {
- stackContext.registerRepoUpdateTask(serviceRepoXml.getLatestURI(), this);
+ registerRepoUpdateTask(serviceRepoXml);
}
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16cc3a6e/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
index 6184b94..a3886ab 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/StackInfo.java
@@ -33,7 +33,6 @@ import org.apache.ambari.server.controller.StackVersionResponse;
import org.apache.ambari.server.stack.Validable;
import org.apache.ambari.server.state.repository.VersionDefinitionXml;
import org.apache.ambari.server.state.stack.ConfigUpgradePack;
-import org.apache.ambari.server.state.stack.LatestRepoCallable;
import org.apache.ambari.server.state.stack.RepositoryXml;
import org.apache.ambari.server.state.stack.StackRoleCommandOrder;
import org.apache.ambari.server.state.stack.UpgradePack;
http://git-wip-us.apache.org/repos/asf/ambari/blob/16cc3a6e/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoUrlInfoCallable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoUrlInfoCallable.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoUrlInfoCallable.java
new file mode 100644
index 0000000..ec1071e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoUrlInfoCallable.java
@@ -0,0 +1,217 @@
+/**
+ * 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.state.stack;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.ambari.server.controller.internal.URLStreamProvider;
+import org.apache.ambari.server.stack.StackModule;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.stack.RepoUrlInfoCallable.RepoUrlInfoResult;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Collections2;
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+/**
+ * Encapsulates the work to resolve the latest repo information for a stack.
+ * This class must be used AFTER the stack has created its owned repositories.
+ */
+public class RepoUrlInfoCallable implements Callable<Map<StackModule, RepoUrlInfoResult>> {
+ private static final int LOOKUP_CONNECTION_TIMEOUT = 2000;
+ private static final int LOOKUP_READ_TIMEOUT = 3000;
+
+ private final static Logger LOG = LoggerFactory.getLogger(RepoUrlInfoCallable.class);
+
+ private URI m_uri = null;
+ private Set<StackModule> m_stacks = new HashSet<>();
+
+ public RepoUrlInfoCallable(URI uri) {
+ m_uri = uri;
+ }
+
+ public void addStack(StackModule stackModule) {
+ m_stacks.add(stackModule);
+ }
+
+ @Override
+ public Map<StackModule, RepoUrlInfoResult> call() throws Exception {
+
+ Type type = new TypeToken<Map<String, Map<String, Object>>>(){}.getType();
+ Gson gson = new Gson();
+
+ Map<String, Map<String, Object>> latestUrlMap = null;
+
+ Set<String> ids = new HashSet<>();
+ ids.addAll(Collections2.transform(m_stacks, new Function<StackModule, String>() {
+ @Override
+ public String apply(StackModule input) {
+ // TODO Auto-generated method stub
+ return new StackId(input.getModuleInfo()).toString();
+ }
+ }));
+
+ String stackIds = StringUtils.join(ids, ',');
+
+ Long time = System.nanoTime();
+
+ try {
+ if (m_uri.getScheme().startsWith("http")) {
+ URLStreamProvider streamProvider = new URLStreamProvider(
+ LOOKUP_CONNECTION_TIMEOUT, LOOKUP_READ_TIMEOUT,
+ null, null, null);
+
+ LOG.info("Loading latest URL info from {} for stacks {}", m_uri, stackIds);
+
+ latestUrlMap = gson.fromJson(new InputStreamReader(
+ streamProvider.readFrom(m_uri.toString())), type);
+ } else {
+ File jsonFile = new File(m_uri);
+
+ if (jsonFile.exists()) {
+ LOG.info("Loading latest URL info from file {} for stacks {}", m_uri, stackIds);
+ latestUrlMap = gson.fromJson(new FileReader(jsonFile), type);
+ }
+ }
+ } catch (Exception e) {
+ LOG.info("Could not load the URI from {}, stack defaults will be used", m_uri);
+ throw e;
+ } finally {
+ LOG.info("Loaded URI {} for stacks {} in {}ms", m_uri, stackIds,
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - time));
+ }
+
+ Map<StackModule, RepoUrlInfoResult> result = new HashMap<>();
+
+ if (null == latestUrlMap) {
+ LOG.error("Could not load latest data for URI {} and stacks {}", m_uri, stackIds);
+ return result;
+ }
+
+ for (StackModule stackModule : m_stacks) {
+ StackId stackId = new StackId(stackModule.getModuleInfo());
+
+ Map<String, Object> map = latestUrlMap.get(stackId.toString());
+
+ if (null == map) {
+ continue;
+ }
+
+ RepoUrlInfoResult res = new RepoUrlInfoResult();
+
+ if (map.containsKey("manifests")) {
+ // versionMap is laid out like [version -> [os -> VDF uri]]
+ @SuppressWarnings("unchecked")
+ Map<String, Map<String, String>> versionMap = (Map<String, Map<String, String>>) map.get("manifests");
+
+ for (Entry<String, Map<String, String>> versionEntry : versionMap.entrySet()) {
+ String version = versionEntry.getKey();
+ Map<String, URI> resolvedOsMap = resolveOsMap(stackModule, versionEntry.getValue());
+
+ res.addVersion(version, resolvedOsMap);
+ }
+ }
+
+
+ if (map.containsKey("latest-vdf")) {
+ @SuppressWarnings("unchecked")
+ Map<String, String> osMap = (Map<String, String>) map.get("latest-vdf");
+
+ Map<String, URI> resolvedOsMap = resolveOsMap(stackModule, osMap);
+
+ res.setLatest(resolvedOsMap);
+ }
+
+ result.put(stackModule, res);
+ }
+
+
+ return result;
+
+ }
+
+ private Map<String, URI> resolveOsMap(StackModule stackModule, Map<String, String> osMap) {
+
+ Map<String, URI> resolved = new HashMap<>();
+
+ for (Entry<String, String> osEntry : osMap.entrySet()) {
+
+ String uriString = osEntry.getValue();
+
+ URI uri = StackModule.getURI(stackModule, uriString);
+
+ if (null == uri) {
+ LOG.warn("Could not resolve URI {}", uriString);
+ } else {
+ resolved.put(osEntry.getKey(), uri);
+ }
+ }
+
+ return resolved;
+ }
+
+
+ /**
+ * Stores the results saved per StackModule
+ */
+ public static class RepoUrlInfoResult {
+
+ private Map<String, Map<String, URI>> versions = new HashMap<>();
+ private Map<String, URI> latestVdf = new HashMap<>();
+
+ private void addVersion(String version, Map<String, URI> vdfMap) {
+ versions.put(version, vdfMap);
+ }
+
+ private void setLatest(Map<String, URI> latestMap) {
+ latestVdf = latestMap;
+ }
+
+ /**
+ * Each version entry here should be loaded in it's entirety in a new thread
+ */
+ public Map<String, Map<String, URI>> getManifest() {
+
+ return versions;
+ }
+
+ /**
+ * @return the latest vdf map
+ */
+ public Map<String, URI> getLatestVdf() {
+
+ return latestVdf;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16cc3a6e/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoVdfCallable.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoVdfCallable.java b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoVdfCallable.java
new file mode 100644
index 0000000..81657a7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/stack/RepoVdfCallable.java
@@ -0,0 +1,161 @@
+/**
+ * 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.state.stack;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.Callable;
+
+import org.apache.ambari.server.stack.StackModule;
+import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.repository.VersionDefinitionXml;
+import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Encapsulates the work to resolve the latest repo information for a stack.
+ * This class must be used AFTER the stack has created its owned repositories.
+ */
+public class RepoVdfCallable implements Callable<Void> {
+
+ private final static Logger LOG = LoggerFactory.getLogger(RepoVdfCallable.class);
+
+ // !!! these are required for this callable to work
+ private final StackInfo m_stack;
+ private final OsFamily m_family;
+ private final Map<String, URI> m_vdfMap;
+
+ // !!! determines if this is for manifests or latest-vdf
+ private String m_version;
+
+ public RepoVdfCallable(StackModule stackModule,
+ String version, Map<String, URI> vdfOsMap, OsFamily os_family) {
+ m_stack = stackModule.getModuleInfo();
+ m_family = os_family;
+ m_version = version;
+ m_vdfMap = vdfOsMap;
+ }
+
+ public RepoVdfCallable(StackModule stackModule,
+ Map<String, URI> vdfOsMap, OsFamily os_family) {
+ m_stack = stackModule.getModuleInfo();
+ m_family = os_family;
+ m_version = null;
+ m_vdfMap = vdfOsMap;
+ }
+
+ @Override
+ public Void call() throws Exception {
+ if (MapUtils.isEmpty(m_vdfMap)) {
+ return null;
+ }
+
+ boolean forLatest = (null == m_version);
+
+ StackId stackId = new StackId(m_stack);
+
+ VersionDefinitionXml xml = mergeDefinitions(stackId, m_version, m_vdfMap);
+
+ if (null == xml) {
+ return null;
+ }
+
+ if (forLatest) {
+ xml.setStackDefault(true);
+ m_stack.setLatestVersionDefinition(xml);
+ } else {
+ m_stack.addVersionDefinition(m_version, xml);
+ }
+
+ return null;
+ }
+
+ /**
+ * Merges definitions loaded from the common file
+ * @param stackId the stack id
+ * @param version the version string
+ * @param osMap the map containing all the VDF for an OS
+ * @return the merged version definition
+ * @throws Exception
+ */
+ private VersionDefinitionXml mergeDefinitions(StackId stackId, String version,
+ Map<String, URI> osMap) throws Exception {
+
+ Set<String> oses = new HashSet<>();
+ for (RepositoryInfo ri : m_stack.getRepositories()) {
+ if (null != m_family.find(ri.getOsType())) {
+ oses.add(m_family.find(ri.getOsType()));
+ }
+ }
+
+ VersionDefinitionXml.Merger merger = new VersionDefinitionXml.Merger();
+
+ for (Entry<String, URI> versionEntry : osMap.entrySet()) {
+
+ String osFamily = m_family.find(versionEntry.getKey());
+ URI uri = versionEntry.getValue();
+
+ // !!! check for aliases. Moving this to OsFamily could result in incorrect behavior
+ if (null == osFamily) {
+ String alias = m_family.getAliases().get(versionEntry.getKey());
+ if (null != alias) {
+ osFamily = m_family.find(alias);
+ }
+ }
+
+ // !!! if the family is not known OR not part of the stack, skip
+ if (null == osFamily || !oses.contains(osFamily)) {
+ LOG.info("Stack {} cannot resolve OS {} to the supported ones: {}. Family: {}",
+ stackId, versionEntry.getKey(), StringUtils.join(oses, ','), osFamily);
+ continue;
+ }
+
+ try {
+ VersionDefinitionXml xml = timedVDFLoad(uri);
+
+ version = (null == version) ? xml.release.version : version;
+ merger.add(version, xml);
+
+ } catch (Exception e) {
+ LOG.warn("Could not load version definition for {} identified by {}. {}",
+ stackId, uri.toString(), e.getMessage(), e);
+ }
+ }
+
+ return merger.merge();
+ }
+
+ private VersionDefinitionXml timedVDFLoad(URI uri) throws Exception {
+ long time = System.currentTimeMillis();
+
+ try {
+ return VersionDefinitionXml.load(uri.toURL());
+ } finally {
+ LOG.debug("Loaded VDF {} in {}ms", uri, System.currentTimeMillis() - time);
+ }
+
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/16cc3a6e/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckActionTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckActionTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckActionTest.java
index d07ac15..9f87312 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckActionTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/ComponentVersionCheckActionTest.java
@@ -36,7 +36,6 @@ import org.apache.ambari.server.actionmanager.HostRoleCommandFactory;
import org.apache.ambari.server.actionmanager.HostRoleStatus;
import org.apache.ambari.server.agent.CommandReport;
import org.apache.ambari.server.agent.ExecutionCommand;
-import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.OrmTestHelper;
@@ -56,7 +55,6 @@ import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.ConfigFactory;
import org.apache.ambari.server.state.Host;
-import org.apache.ambari.server.state.RepositoryInfo;
import org.apache.ambari.server.state.RepositoryVersionState;
import org.apache.ambari.server.state.Service;
import org.apache.ambari.server.state.ServiceComponent;
@@ -308,12 +306,6 @@ public class ComponentVersionCheckActionTest {
makeUpgradeCluster(sourceStack, sourceRepo, targetStack, targetRepo);
- // Verify the repo before calling Finalize
- AmbariMetaInfo metaInfo = m_injector.getInstance(AmbariMetaInfo.class);
-
- RepositoryInfo repo = metaInfo.getRepository(sourceStack.getStackName(), sourceStack.getStackVersion(), "redhat6", sourceStack.getStackId());
- assertEquals(HDP_211_CENTOS6_REPO_URL, repo.getBaseUrl());
-
// Finalize the upgrade
Map<String, String> commandParams = new HashMap<>();
ExecutionCommand executionCommand = new ExecutionCommand();
@@ -470,12 +462,6 @@ public class ComponentVersionCheckActionTest {
sch = createNewServiceComponentHost(cluster, "ZOOKEEPER", "ZOOKEEPER_SERVER", "h1");
sch.setVersion(HDP_2_1_1_1);
- // Verify the repo before calling Finalize
- AmbariMetaInfo metaInfo = m_injector.getInstance(AmbariMetaInfo.class);
-
- RepositoryInfo repo = metaInfo.getRepository(sourceStack.getStackName(), sourceStack.getStackVersion(), "redhat6", sourceStack.getStackId());
- assertEquals(HDP_211_CENTOS6_REPO_URL, repo.getBaseUrl());
-
// Finalize the upgrade
Map<String, String> commandParams = new HashMap<>();
ExecutionCommand executionCommand = new ExecutionCommand();
[18/38] ambari git commit: AMBARI-21949. Stacks And Versions Page
Displays Wrong Version For Service (alexantonenko)
Posted by lp...@apache.org.
AMBARI-21949. Stacks And Versions Page Displays Wrong Version For Service (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2c10dc92
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2c10dc92
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2c10dc92
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 2c10dc92047017771e6fca8d9d76d6d6b00df372
Parents: 153d0da
Author: Alex Antonenko <aa...@hortonworks.com>
Authored: Wed Sep 13 18:40:22 2017 +0300
Committer: Alex Antonenko <aa...@hortonworks.com>
Committed: Wed Sep 13 18:40:22 2017 +0300
----------------------------------------------------------------------
.../app/controllers/global/update_controller.js | 2 +-
ambari-web/app/mappers/service_mapper.js | 6 +++--
.../app/mappers/service_metrics_mapper.js | 3 ++-
ambari-web/app/models/service.js | 1 +
ambari-web/app/styles/stack_versions.less | 9 -------
.../upgrade_version_column_view.js | 13 +++-------
.../upgrade_version_column_view_test.js | 27 +++++++++++++++++---
7 files changed, 35 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/app/controllers/global/update_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/global/update_controller.js b/ambari-web/app/controllers/global/update_controller.js
index 8a3f984..d33c5f1 100644
--- a/ambari-web/app/controllers/global/update_controller.js
+++ b/ambari-web/app/controllers/global/update_controller.js
@@ -520,7 +520,7 @@ App.UpdateController = Em.Controller.extend({
updateServices: function (callback) {
var testUrl = '/data/services/HDP2/services.json';
- var componentConfigUrl = this.getUrl(testUrl, '/services?fields=ServiceInfo/state,ServiceInfo/maintenance_state,components/ServiceComponentInfo/component_name&minimal_response=true');
+ var componentConfigUrl = this.getUrl(testUrl, '/services?fields=ServiceInfo/state,ServiceInfo/maintenance_state,ServiceInfo/desired_repository_version_id,components/ServiceComponentInfo/component_name&minimal_response=true');
App.HttpClient.get(componentConfigUrl, App.serviceMapper, {
complete: callback
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/app/mappers/service_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_mapper.js b/ambari-web/app/mappers/service_mapper.js
index 3523379..24130dd 100644
--- a/ambari-web/app/mappers/service_mapper.js
+++ b/ambari-web/app/mappers/service_mapper.js
@@ -23,7 +23,8 @@ App.serviceMapper = App.QuickDataMapper.create({
config: {
id: 'ServiceInfo.service_name',
service_name: 'ServiceInfo.service_name',
- work_status: 'ServiceInfo.state'
+ work_status: 'ServiceInfo.state',
+ desired_repository_version_id: 'ServiceInfo.desired_repository_version_id'
},
initialAppLoad: false,
passiveStateMap: {},
@@ -41,7 +42,8 @@ App.serviceMapper = App.QuickDataMapper.create({
var serviceData = {
ServiceInfo: {
service_name: service.ServiceInfo.service_name,
- state: service.ServiceInfo.state
+ state: service.ServiceInfo.state,
+ desired_repository_version_id: service.ServiceInfo.desired_repository_version_id
},
host_components: [],
components: []
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/app/mappers/service_metrics_mapper.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/mappers/service_metrics_mapper.js b/ambari-web/app/mappers/service_metrics_mapper.js
index 87b6149..9f79905 100644
--- a/ambari-web/app/mappers/service_metrics_mapper.js
+++ b/ambari-web/app/mappers/service_metrics_mapper.js
@@ -36,7 +36,8 @@ App.serviceMetricsMapper = App.QuickDataMapper.create({
installed_clients: 'installed_clients',
client_components: 'client_components',
slave_components: 'slave_components',
- master_components: 'master_components'
+ master_components: 'master_components',
+ desired_repository_version_id: 'ServiceInfo.desired_repository_version_id'
},
hdfsConfig: {
version: 'nameNodeComponent.host_components[0].metrics.dfs.namenode.Version',
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/app/models/service.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js
index 70ae917..563add8 100644
--- a/ambari-web/app/models/service.js
+++ b/ambari-web/app/models/service.js
@@ -30,6 +30,7 @@ App.Service = DS.Model.extend({
quickLinks: DS.hasMany('App.QuickLinks'), // mapped in app/mappers/service_metrics_mapper.js method - mapQuickLinks
hostComponents: DS.hasMany('App.HostComponent'),
serviceConfigsTemplate: App.config.get('preDefinedServiceConfigs'),
+ desiredRepositoryVersionId: DS.attr('number'),
/**
* used by services("OOZIE", "ZOOKEEPER", "HIVE", "MAPREDUCE2", "TEZ", "SQOOP", "PIG","FALCON")
* that have only client components
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/app/styles/stack_versions.less
----------------------------------------------------------------------
diff --git a/ambari-web/app/styles/stack_versions.less b/ambari-web/app/styles/stack_versions.less
index e8afaf4..804bb4d 100644
--- a/ambari-web/app/styles/stack_versions.less
+++ b/ambari-web/app/styles/stack_versions.less
@@ -358,15 +358,6 @@
}
}
}
- div.current-version-box.version-column {
- .services-section{
- .service-version-info {
- span.label {
- background-color: #468847;
- }
- }
- }
- }
div.version-column {
.not-upgradable {
padding-left: 10px;
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_column_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_column_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_column_view.js
index b5933b9..0ae8252 100644
--- a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_column_view.js
+++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_version_column_view.js
@@ -69,24 +69,17 @@ App.UpgradeVersionColumnView = App.UpgradeVersionBoxView.extend({
* @returns {boolean}
*/
isStackServiceAvailable: function(stackService) {
+ var self = this;
if (!stackService) {
return false;
}
if ( this.get('content.isCurrent') ){
- // if version is current, check whether this service is available and the version itself is the newest version of all versions that contain the same service
- var serviceWithHigherVersion = App.RepositoryVersion.find().filterProperty('isCurrent').find(function ( version ) {
- var service = version.get('stackServices').toArray().find( function (service) {
- return service.get('name') === stackService.get('name') && service.get('isAvailable')
- });
- return Boolean(service && stringUtils.compareVersions(version.get('repositoryVersion'), this.get('content.repositoryVersion')) === 1);
- }, this);
- return stackService.get('isAvailable') && !serviceWithHigherVersion;
+ var originalService = App.Service.find(stackService.get('name'));
+ return stackService.get('isAvailable') && originalService.get('desiredRepositoryVersionId') === this.get('content.id');
}
else{
return stackService.get('isAvailable')
}
-
-
},
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/2c10dc92/ambari-web/test/views/main/admin/stack_upgrade/upgrade_version_column_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_version_column_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_version_column_view_test.js
index a7cb395..1c68fa3 100644
--- a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_version_column_view_test.js
+++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_version_column_view_test.js
@@ -22,8 +22,23 @@ require('views/main/admin/stack_upgrade/upgrade_version_column_view');
describe('App.UpgradeVersionColumnView', function () {
var view = App.UpgradeVersionColumnView.create({});
+ var services = [
+ Em.Object.create({
+ id: 'zk',
+ desiredRepositoryVersionId: 1
+ }),
+ Em.Object.create({
+ id: 'storm',
+ desiredRepositoryVersionId: 2
+ }),
+ Em.Object.create({
+ id: 'hdfs',
+ desiredRepositoryVersionId: 1
+ })
+ ];
var versions = [
Em.Object.create({
+ id: 1,
status: "CURRENT",
repositoryVersion: "2.3.1.1",
stackVersionType: 'HDP',
@@ -45,6 +60,7 @@ describe('App.UpgradeVersionColumnView', function () {
]
}),
Em.Object.create({
+ id: 2,
status: "CURRENT",
repositoryVersion: "2.2.0.1",
stackVersionType: 'HDP',
@@ -66,6 +82,7 @@ describe('App.UpgradeVersionColumnView', function () {
]
}),
Em.Object.create({
+ id: 3,
status: "INSTALLED",
repositoryVersion: "2.0.2.1",
stackVersionType: 'HCP',
@@ -92,10 +109,14 @@ describe('App.UpgradeVersionColumnView', function () {
describe("#isStackServiceAvailable", function () {
beforeEach(function() {
- sinon.stub(App.RepositoryVersion, 'find').returns(versions);
+ sinon.stub(App.Service, 'find', function (id) {
+ return services.find(function (service) {
+ return id === service.get('id');
+ })
+ })
});
afterEach(function() {
- App.RepositoryVersion.find.restore();
+ App.Service.find.restore();
});
it('Current upgrade with invalid service', function () {
view.set('content', versions[0]);
@@ -122,4 +143,4 @@ describe('App.UpgradeVersionColumnView', function () {
expect(view.isStackServiceAvailable(versions[1].get('stackServices')[1])).to.be.true;
});
});
-});
\ No newline at end of file
+});
[33/38] ambari git commit: AMBARI-21307 AddedLDAP configuration
provider for loading and maintaining the LDAP configuration in the
application
Posted by lp...@apache.org.
AMBARI-21307 AddedLDAP configuration provider for loading and maintaining the LDAP configuration in the application
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/37f90058
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/37f90058
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/37f90058
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 37f9005829f1d18c6dc99a0dc04829f4c1946bdd
Parents: fa7d7ec
Author: lpuskas <lp...@apache.org>
Authored: Tue Aug 29 14:55:09 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:31 2017 +0200
----------------------------------------------------------------------
.../services/ldap/LdapConfigurationService.java | 1 +
.../AmbariConfigurationResourceProvider.java | 35 +++++-
.../ambari/server/events/AmbariEvent.java | 11 +-
.../events/AmbariLdapConfigChangedEvent.java | 37 ++++++
.../server/ldap/LdapConfigurationFactory.java | 2 +-
.../apache/ambari/server/ldap/LdapModule.java | 3 +
.../AmbariLdapConfigurationProvider.java | 114 +++++++++++++++++++
.../server/ldap/service/AmbariLdapFacade.java | 7 +-
.../server/orm/dao/AmbariConfigurationDAO.java | 48 ++++++++
.../orm/entities/AmbariConfigurationEntity.java | 4 +-
.../DefaultLdapConfigurationServiceTest.java | 10 +-
11 files changed, 260 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/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
index fc6bd41..1b8427b 100644
--- 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
@@ -82,6 +82,7 @@ public class LdapConfigurationService extends AmbariConfigurationService {
@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();
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/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 2302d8b..4f4cc70 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
@@ -35,6 +35,9 @@ 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.events.AmbariEvent;
+import org.apache.ambari.server.events.AmbariLdapConfigChangedEvent;
+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.orm.entities.ConfigurationBaseEntity;
@@ -113,6 +116,10 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
@Inject
private AmbariConfigurationDAO ambariConfigurationDAO;
+ @Inject
+ private AmbariEventPublisher publisher;
+
+
private Gson gson;
@AssistedInject
@@ -142,7 +149,18 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
}
LOGGER.info("Persisting new ambari configuration: {} ", ambariConfigurationEntity);
- ambariConfigurationDAO.create(ambariConfigurationEntity);
+
+ try {
+ ambariConfigurationDAO.create(ambariConfigurationEntity);
+ } catch (Exception e) {
+ LOGGER.error("Failed to create resource", e);
+ throw new ResourceAlreadyExistsException(e.getMessage());
+ }
+
+ // todo filter by configuration type
+ // notify subscribers about the configuration changes
+ publisher.publish(new AmbariLdapConfigChangedEvent(AmbariEvent.AmbariEventType.LDAP_CONFIG_CHANGED,
+ ambariConfigurationEntity.getId()));
return getRequestStatus(null);
}
@@ -183,6 +201,10 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
}
+ // notify subscribers about the configuration changes
+ publisher.publish(new AmbariLdapConfigChangedEvent(AmbariEvent.AmbariEventType.LDAP_CONFIG_CHANGED, idFromRequest));
+
+
return getRequestStatus(null);
}
@@ -209,11 +231,15 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
persistedEntity.getConfigurationBaseEntity().setConfigurationAttributes(entityFromRequest.getConfigurationBaseEntity().getConfigurationAttributes());
- ambariConfigurationDAO.create(persistedEntity);
+ ambariConfigurationDAO.update(persistedEntity);
} catch (AmbariException e) {
throw new NoSuchParentResourceException(e.getMessage());
}
+ publisher.publish(new AmbariLdapConfigChangedEvent(AmbariEvent.AmbariEventType.LDAP_CONFIG_CHANGED,
+ persistedEntity.getId()));
+
+
return getRequestStatus(null);
}
@@ -251,6 +277,11 @@ public class AmbariConfigurationResourceProvider extends AbstractAuthorizedResou
throw new AmbariException("There must be only one resource specified in the request");
}
+ // the configuration type must be set
+ if (getValueFromResourceProperties(ResourcePropertyId.TYPE, resourcePropertiesSet.iterator().next()) == null) {
+ throw new AmbariException("The configuration type must be set");
+ }
+
for (ResourcePropertyId resourcePropertyId : ResourcePropertyId.values()) {
Object requestValue = getValueFromResourceProperties(resourcePropertyId, resourcePropertiesSet.iterator().next());
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
index 9a5ee79..0f9ff52 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariEvent.java
@@ -140,7 +140,13 @@ public abstract class AmbariEvent {
/**
* Local user has been created.
*/
- USER_CREATED;
+ USER_CREATED,
+
+ /**
+ * LDAP config changed event;
+ */
+ LDAP_CONFIG_CHANGED;
+
}
/**
@@ -151,8 +157,7 @@ public abstract class AmbariEvent {
/**
* Constructor.
*
- * @param eventType
- * the type of event (not {@code null}).
+ * @param eventType the type of event (not {@code null}).
*/
public AmbariEvent(AmbariEventType eventType) {
m_eventType = eventType;
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariLdapConfigChangedEvent.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariLdapConfigChangedEvent.java b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariLdapConfigChangedEvent.java
new file mode 100644
index 0000000..48799d7
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/events/AmbariLdapConfigChangedEvent.java
@@ -0,0 +1,37 @@
+/*
+ * 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.events;
+
+/**
+ * Event signaling the creation or changing of an LDAP configuration entry.
+ */
+public class AmbariLdapConfigChangedEvent extends AmbariEvent {
+
+ private Long configurationId;
+
+ /**
+ * Constructor.
+ *
+ * @param eventType the type of event (not {@code null}).
+ */
+ public AmbariLdapConfigChangedEvent(AmbariEventType eventType, Long configurationId) {
+ super(eventType);
+ this.configurationId = configurationId;
+ }
+
+ public Long getConfigurationId() {
+ return configurationId;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
index bcd6e39..57cdf6e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
@@ -18,4 +18,4 @@ import java.util.Map;
public interface LdapConfigurationFactory {
AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> configuration);
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/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 3ae4587..81f2a44 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
@@ -15,6 +15,7 @@
package org.apache.ambari.server.ldap;
+import org.apache.ambari.server.ldap.service.AmbariLdapConfigurationProvider;
import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
import org.apache.ambari.server.ldap.service.LdapConnectionService;
import org.apache.ambari.server.ldap.service.LdapFacade;
@@ -35,6 +36,8 @@ public class LdapModule extends AbstractModule {
bind(LdapConfigurationService.class).to(DefaultLdapConfigurationService.class);
bind(LdapConnectionService.class).to(DefaultLdapConnectionService.class);
+ bind(AmbariLdapConfiguration.class).toProvider(AmbariLdapConfigurationProvider.class);
+
install(new FactoryModuleBuilder().build(LdapConfigurationFactory.class));
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
new file mode 100644
index 0000000..7f3e8a9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
@@ -0,0 +1,114 @@
+/*
+ * 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.service;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.inject.Inject;
+import javax.inject.Provider;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.events.AmbariLdapConfigChangedEvent;
+import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
+import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.eventbus.Subscribe;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+/**
+ * Provider implementation for LDAP configurations. It needs to be registered in the related GUICE module as a provider
+ * It's responsible for managing LDAP configurations in the application.
+ * Whenever requested, this provider returns an AmbariLdapConfiguration which is always in sync with the persisted LDAP
+ * configuration resource.
+ *
+ * The provider receives notifications on CRUD operations related to the persisted resource and reloads the cached
+ * configuration instance accordingly.
+ */
+@Singleton
+public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfiguration> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AmbariLdapAuthenticationProvider.class);
+ private AmbariLdapConfiguration instance;
+
+ @Inject
+ private AmbariEventPublisher publisher;
+
+ @Inject
+ private Provider<AmbariConfigurationDAO> ambariConfigurationDAOProvider;
+
+ private Gson gson = new GsonBuilder().create();
+
+ @Inject
+ public AmbariLdapConfigurationProvider() {
+ }
+
+ @Inject
+ void register() {
+ publisher.register(this);
+ }
+
+ @Override
+ public AmbariLdapConfiguration get() {
+ return instance != null ? instance : loadInstance(null);
+ }
+
+ /**
+ * Loads the AmbariLdapConfiguration from the database.
+ *
+ * @param configurationId the configuration id
+ * @return the AmbariLdapConfiguration instance
+ */
+ private AmbariLdapConfiguration loadInstance(Long configurationId) {
+ AmbariConfigurationEntity configEntity = null;
+
+ LOGGER.info("Loading LDAP configuration ...");
+ if (null != configurationId) {
+
+ LOGGER.debug("Reloading configuration based on the provied id: {}", configurationId);
+ configEntity = ambariConfigurationDAOProvider.get().findByPK(configurationId);
+
+ } else {
+
+ LOGGER.debug("Initial loading of the ldap configuration ...");
+ configEntity = ambariConfigurationDAOProvider.get().getLdapConfiguration();
+
+ }
+
+ if (configEntity != null) {
+ Set propertyMaps = gson.fromJson(configEntity.getConfigurationBaseEntity().getConfigurationData(), Set.class);
+ instance = new AmbariLdapConfiguration((Map<String, Object>) propertyMaps.iterator().next());
+ }
+
+ LOGGER.info("Loaded LDAP configuration instance: [ {} ]", instance);
+
+ return instance;
+ }
+
+ @Subscribe
+ public void ambariLdapConfigChanged(AmbariLdapConfigChangedEvent event) {
+ LOGGER.info("LDAP config changed event received: {}", event);
+ loadInstance(event.getConfigurationId());
+ LOGGER.info("Refreshed LDAP config instance.");
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index 683ed43..90a5ba7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -19,6 +19,7 @@ import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
+import javax.inject.Provider;
import javax.inject.Singleton;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
@@ -54,6 +55,10 @@ public class AmbariLdapFacade implements LdapFacade {
@Inject
private LdapConnectionService ldapConnectionService;
+ //todo remove this, added for testing purposes only
+ @Inject
+ private Provider<AmbariLdapConfiguration> ambariLdapConfigurationProvider;
+
@Inject
public AmbariLdapFacade() {
}
@@ -75,7 +80,7 @@ public class AmbariLdapFacade implements LdapFacade {
@Override
public void detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration) {
LOGGER.info("Detecting LDAP configuration attributes ...");
- throw new UnsupportedOperationException("Not yet implemented");
+ LOGGER.info("LDAP config: {}", ambariLdapConfigurationProvider.get());
}
@Override
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/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 5710a7f..83293ef 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
@@ -16,8 +16,13 @@ package org.apache.ambari.server.orm.dao;
import javax.inject.Inject;
import javax.inject.Singleton;
+import javax.persistence.EntityExistsException;
+import javax.persistence.EntityNotFoundException;
+import javax.persistence.TypedQuery;
import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.google.inject.persist.Transactional;
@@ -29,6 +34,8 @@ import com.google.inject.persist.Transactional;
@Singleton
public class AmbariConfigurationDAO extends CrudDAO<AmbariConfigurationEntity, Long> {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AmbariConfigurationDAO.class);
+
@Inject
public AmbariConfigurationDAO() {
super(AmbariConfigurationEntity.class);
@@ -36,6 +43,47 @@ public class AmbariConfigurationDAO extends CrudDAO<AmbariConfigurationEntity, L
@Transactional
public void create(AmbariConfigurationEntity entity) {
+ // make sure only one LDAP config entry exists
+ if ("ldap-configuration".equals(entity.getConfigurationBaseEntity().getType())) {
+ AmbariConfigurationEntity ldapConfigEntity = getLdapConfiguration();
+ if (ldapConfigEntity != null) {
+ LOGGER.error("Only one LDAP configuration entry can exist!");
+ throw new EntityExistsException("LDAP configuration entity already exists!");
+ }
+ }
super.create(entity);
}
+
+
+ @Transactional
+ public void update(AmbariConfigurationEntity entity) {
+ if (entity.getId() == null || findByPK(entity.getId()) == null) {
+ String msg = String.format("The entity with id [ %s ] is not found", entity.getId());
+ LOGGER.debug(msg);
+ throw new EntityNotFoundException(msg);
+ }
+
+ // updating the existing entity
+ super.merge(entity);
+ entityManagerProvider.get().flush();
+ }
+
+ /**
+ * Returns the LDAP configuration from the database.
+ *
+ * @return the configuration entity
+ */
+ @Transactional
+ public AmbariConfigurationEntity getLdapConfiguration() {
+ LOGGER.info("Looking up the LDAP configuration ....");
+ AmbariConfigurationEntity ldapConfigEntity = null;
+
+ TypedQuery<AmbariConfigurationEntity> query = entityManagerProvider.get().createNamedQuery(
+ "AmbariConfigurationEntity.findByType", AmbariConfigurationEntity.class);
+ query.setParameter("typeName", "ldap-configuration");
+
+ ldapConfigEntity = daoUtils.selectSingle(query);
+ LOGGER.info("Returned entity: {} ", ldapConfigEntity);
+ return ldapConfigEntity;
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/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
index 34fa221..c9f4695 100644
--- 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
@@ -29,8 +29,8 @@ import javax.persistence.Table;
@Table(name = "ambari_configuration")
@NamedQueries({
@NamedQuery(
- name = "AmbariConfigurationEntity.findAll",
- query = "select ace from AmbariConfigurationEntity ace")
+ name = "AmbariConfigurationEntity.findByType",
+ query = "select ace from AmbariConfigurationEntity ace where ace.configurationBaseEntity.type = :typeName")
})
public class AmbariConfigurationEntity {
http://git-wip-us.apache.org/repos/asf/ambari/blob/37f90058/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
index 2b7448e..b5978a5 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
@@ -28,6 +28,7 @@ import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapConnectionConfig;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -46,15 +47,18 @@ public class DefaultLdapConfigurationServiceTest {
// WHEN
LdapConnectionConfig config = new LdapConnectionConfig();
- config.setLdapHost("localhost");
+ config.setLdapHost("172.22.112.167");
config.setLdapPort(389);
LdapConnection connection = new LdapNetworkConnection(config);
// THEN
- connection.anonymousBind();
+ connection.bind("CN=Robert Levas,CN=Users,DC=HWQE,DC=HORTONWORKS,DC=COM", "Hadoop1234");
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, "person"),
+ FilterBuilder.equal("name", "User1 Levas")).toString();
- EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
+ EntryCursor cursor = connection.search("OU=levas,DC=hwqe,DC=hortonworks,DC=com", filter, SearchScope.SUBTREE);
for (Entry entry : cursor) {
assertNotNull(entry);
[10/38] ambari git commit: AMBARI-21893 : NameNode Heap Usage (Daily)
metric alert status flips to UNKNOWN intermittently when AMS HTTPS is
enabled. (avijayan)
Posted by lp...@apache.org.
AMBARI-21893 : NameNode Heap Usage (Daily) metric alert status flips to UNKNOWN intermittently when AMS HTTPS is enabled. (avijayan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7fa7a6c1
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7fa7a6c1
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7fa7a6c1
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 7fa7a6c17607341e8a6888f3dd8b938dce7425ff
Parents: bb4645f
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Tue Sep 12 17:01:51 2017 -0700
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Tue Sep 12 17:01:51 2017 -0700
----------------------------------------------------------------------
.../server/upgrade/UpgradeCatalog260.java | 30 +++++++++
.../0.1.0/configuration/ams-ssl-client.xml | 9 ---
.../AMBARI_METRICS/0.1.0/package/scripts/ams.py | 10 +--
.../0.1.0/package/scripts/params.py | 10 ++-
.../server/upgrade/UpgradeCatalog260Test.java | 70 +++++++++++++++++++-
5 files changed, 110 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7fa7a6c1/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
index d05f39a..2de85fc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
@@ -21,6 +21,7 @@ import static org.apache.ambari.server.view.ViewContextImpl.CORE_SITE;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -29,6 +30,7 @@ import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.dao.ArtifactDAO;
import org.apache.ambari.server.orm.entities.ArtifactEntity;
@@ -122,6 +124,9 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
public static final String HOST_COMPONENT_DESIRED_STATE = "hostcomponentdesiredstate";
public static final String HOST_COMPONENT_STATE = "hostcomponentstate";
+ public static final String AMS_SSL_CLIENT = "ams-ssl-client";
+ public static final String METRIC_TRUSTSTORE_ALIAS = "ssl.client.truststore.alias";
+
/**
* Logger.
*/
@@ -395,6 +400,7 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
removeSupersetFromDruid();
ensureZeppelinProxyUserConfigs();
updateKerberosDescriptorArtifacts();
+ updateAmsConfigs();
}
public int getCurrentVersionID() throws AmbariException, SQLException {
@@ -535,4 +541,28 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
}
}
}
+
+ protected void updateAmsConfigs() throws AmbariException {
+ AmbariManagementController ambariManagementController = injector.getInstance(AmbariManagementController.class);
+ Clusters clusters = ambariManagementController.getClusters();
+ if (clusters != null) {
+ Map<String, Cluster> clusterMap = getCheckedClusterMap(clusters);
+ if (clusterMap != null && !clusterMap.isEmpty()) {
+ for (final Cluster cluster : clusterMap.values()) {
+
+
+ Config amsSslClient = cluster.getDesiredConfigByType(AMS_SSL_CLIENT);
+ if (amsSslClient != null) {
+ Map<String, String> amsSslClientProperties = amsSslClient.getProperties();
+
+ if (amsSslClientProperties.containsKey(METRIC_TRUSTSTORE_ALIAS)) {
+ LOG.info("Removing " + METRIC_TRUSTSTORE_ALIAS + " from " + AMS_SSL_CLIENT);
+ removeConfigurationPropertiesFromCluster(cluster, AMS_SSL_CLIENT, Collections.singleton(METRIC_TRUSTSTORE_ALIAS));
+ }
+
+ }
+ }
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/7fa7a6c1/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-ssl-client.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-ssl-client.xml b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-ssl-client.xml
index cac39de..d75bba2 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-ssl-client.xml
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/configuration/ams-ssl-client.xml
@@ -39,13 +39,4 @@
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
- <property>
- <name>ssl.client.truststore.alias</name>
- <value></value>
- <description>Alias used to create certificate for AMS. (Default is hostname)</description>
- <value-attributes>
- <empty-value-valid>true</empty-value-valid>
- </value-attributes>
- <on-ambari-upgrade add="true"/>
- </property>
</configuration>
http://git-wip-us.apache.org/repos/asf/ambari/blob/7fa7a6c1/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
index 9a31ade..51e0756 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/ams.py
@@ -515,10 +515,12 @@ def export_ca_certs(dir_path):
truststore_p12 = os.path.join(tmpdir,'truststore.p12')
if (params.metric_truststore_type.lower() == 'jks'):
- # Convert truststore from JKS to PKCS12
- cmd = format("{sudo} {java64_home}/bin/keytool -importkeystore -srckeystore {metric_truststore_path} -destkeystore {truststore_p12} -srcalias {metric_truststore_alias} -deststoretype PKCS12 -srcstorepass {metric_truststore_password} -deststorepass {metric_truststore_password}")
- Execute(cmd,
- )
+ if not params.metric_truststore_alias:
+ for alias in params.metric_truststore_alias_list:
+ # Convert truststore from JKS to PKCS12
+ cmd = format("{sudo} {java64_home}/bin/keytool -importkeystore -srckeystore {metric_truststore_path} -destkeystore {truststore_p12} -srcalias " + alias + " -deststoretype PKCS12 -srcstorepass {metric_truststore_password} -deststorepass {metric_truststore_password}")
+ Execute(cmd,
+ )
truststore = truststore_p12
# Export all CA certificates from the truststore to the conf directory
http://git-wip-us.apache.org/repos/asf/ambari/blob/7fa7a6c1/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
index 756da26..0242b73 100644
--- a/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
+++ b/ambari-server/src/main/resources/common-services/AMBARI_METRICS/0.1.0/package/scripts/params.py
@@ -100,11 +100,15 @@ else:
metric_truststore_path= default("/configurations/ams-ssl-client/ssl.client.truststore.location", "")
metric_truststore_type= default("/configurations/ams-ssl-client/ssl.client.truststore.type", "")
metric_truststore_password= default("/configurations/ams-ssl-client/ssl.client.truststore.password", "")
-metric_truststore_alias = default("/configurations/ams-ssl-client/ssl.client.truststore.alias", None)
-if not metric_truststore_alias:
- metric_truststore_alias = metric_collector_host
metric_truststore_ca_certs='ca.pem'
+metric_truststore_alias_list = []
+for host in ams_collector_hosts.split(","):
+ metric_truststore_alias = default("/configurations/ams-ssl-client/{host}.ssl.client.truststore.alias", None)
+ if not metric_truststore_alias:
+ metric_truststore_alias = host
+ metric_truststore_alias_list.append(metric_truststore_alias)
+
agent_cache_dir = config['hostLevelParams']['agentCacheDir']
service_package_folder = config['commandParams']['service_package_folder']
stack_name = default("/hostLevelParams/stack_name", None)
http://git-wip-us.apache.org/repos/asf/ambari/blob/7fa7a6c1/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
index 33c29bc..b70f37b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
@@ -23,6 +23,7 @@ import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.createMockBuilder;
+import static org.easymock.EasyMock.createNiceMock;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.expectLastCall;
@@ -30,6 +31,7 @@ import static org.easymock.EasyMock.newCapture;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertTrue;
import java.io.File;
import java.net.URL;
@@ -40,16 +42,19 @@ import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.EntityManager;
+import com.google.common.collect.Maps;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
+import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
import org.apache.ambari.server.controller.KerberosHelper;
import org.apache.ambari.server.controller.MaintenanceStateHelper;
import org.apache.ambari.server.orm.DBAccessor;
@@ -67,7 +72,9 @@ import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
import org.apache.ambari.server.state.stack.OsFamily;
import org.easymock.Capture;
+import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
+import org.easymock.EasyMockSupport;
import org.easymock.Mock;
import org.easymock.MockType;
import org.junit.After;
@@ -480,8 +487,8 @@ public class UpgradeCatalog260Test {
}
public void verifyGetCurrentVersionID(Capture<String[]> scdcaptureKey, Capture<String[]> scdcaptureValue) {
- Assert.assertTrue(Arrays.equals(scdcaptureKey.getValue(), new String[]{UpgradeCatalog260.STATE_COLUMN}));
- Assert.assertTrue(Arrays.equals(scdcaptureValue.getValue(), new String[]{UpgradeCatalog260.CURRENT}));
+ assertTrue(Arrays.equals(scdcaptureKey.getValue(), new String[]{UpgradeCatalog260.STATE_COLUMN}));
+ assertTrue(Arrays.equals(scdcaptureValue.getValue(), new String[]{UpgradeCatalog260.CURRENT}));
}
public void expectUpdateServiceComponentDesiredStateTable(Capture<DBColumnInfo> scdstadd1, Capture<DBColumnInfo> scdstalter1, Capture<DBColumnInfo> scdstadd2, Capture<DBColumnInfo> scdstalter2) throws SQLException {
@@ -625,7 +632,7 @@ public class UpgradeCatalog260Test {
verify(clusters, cluster, zeppelinEnvConf, coreSiteConf, coreSiteConfNew, controller);
- Assert.assertTrue(captureCoreSiteConfProperties.hasCaptured());
+ assertTrue(captureCoreSiteConfProperties.hasCaptured());
Assert.assertEquals("existing_value", captureCoreSiteConfProperties.getValue().get("hadoop.proxyuser.zeppelin_user.hosts"));
Assert.assertEquals("*", captureCoreSiteConfProperties.getValue().get("hadoop.proxyuser.zeppelin_user.groups"));
}
@@ -673,4 +680,61 @@ public class UpgradeCatalog260Test {
Assert.assertNull(kerberosDescriptorUpdated.getService("RANGER_KMS").getComponent("RANGER_KMS_SERVER").getIdentity("/smokeuser"));
}
+
+ @Test
+ public void testUpdateAmsConfigs() throws Exception{
+
+ Map<String, String> oldProperties = new HashMap<String, String>() {
+ {
+ put("ssl.client.truststore.location", "/some/location");
+ put("ssl.client.truststore.alias", "test_alias");
+ }
+ };
+ Map<String, String> newProperties = new HashMap<String, String>() {
+ {
+ put("ssl.client.truststore.location", "/some/location");
+ }
+ };
+
+ EasyMockSupport easyMockSupport = new EasyMockSupport();
+
+ Clusters clusters = easyMockSupport.createNiceMock(Clusters.class);
+ final Cluster cluster = easyMockSupport.createNiceMock(Cluster.class);
+ Config mockAmsSslClient = easyMockSupport.createNiceMock(Config.class);
+
+ expect(clusters.getClusters()).andReturn(new HashMap<String, Cluster>() {{
+ put("normal", cluster);
+ }}).once();
+ expect(cluster.getDesiredConfigByType("ams-ssl-client")).andReturn(mockAmsSslClient).atLeastOnce();
+ expect(mockAmsSslClient.getProperties()).andReturn(oldProperties).anyTimes();
+
+ Injector injector = easyMockSupport.createNiceMock(Injector.class);
+ expect(injector.getInstance(Gson.class)).andReturn(null).anyTimes();
+ expect(injector.getInstance(MaintenanceStateHelper.class)).andReturn(null).anyTimes();
+
+ replay(injector, clusters, mockAmsSslClient, cluster);
+
+ AmbariManagementControllerImpl controller = createMockBuilder(AmbariManagementControllerImpl.class)
+ .addMockedMethod("createConfiguration")
+ .addMockedMethod("getClusters", new Class[] { })
+ .addMockedMethod("createConfig")
+ .withConstructor(createNiceMock(ActionManager.class), clusters, injector)
+ .createNiceMock();
+
+ Injector injector2 = easyMockSupport.createNiceMock(Injector.class);
+ Capture<Map> propertiesCapture = EasyMock.newCapture();
+
+ expect(injector2.getInstance(AmbariManagementController.class)).andReturn(controller).anyTimes();
+ expect(controller.getClusters()).andReturn(clusters).anyTimes();
+ expect(controller.createConfig(anyObject(Cluster.class), anyObject(StackId.class), anyString(), capture(propertiesCapture), anyString(),
+ anyObject(Map.class))).andReturn(createNiceMock(Config.class)).once();
+
+ replay(controller, injector2);
+ new UpgradeCatalog260(injector2).updateAmsConfigs();
+ easyMockSupport.verifyAll();
+
+ Map<String, String> updatedProperties = propertiesCapture.getValue();
+ assertTrue(Maps.difference(newProperties, updatedProperties).areEqual());
+ }
+
}
[05/38] ambari git commit: AMBARI-21902. Ambari is setting
"atlas.graph.storage.hostname" to hbase hostname,
instead it should set the zookeeper quorum. (Ayub Pathan via stoader)
Posted by lp...@apache.org.
AMBARI-21902. Ambari is setting "atlas.graph.storage.hostname" to hbase hostname, instead it should set the zookeeper quorum. (Ayub Pathan via stoader)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/5113e995
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/5113e995
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/5113e995
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 5113e995f27b4b357ca99650cee5c95a7881c619
Parents: f89dcd7
Author: Toader, Sebastian <st...@hortonworks.com>
Authored: Tue Sep 12 15:29:53 2017 +0200
Committer: Toader, Sebastian <st...@hortonworks.com>
Committed: Tue Sep 12 18:04:40 2017 +0200
----------------------------------------------------------------------
.../BlueprintConfigurationProcessor.java | 2 +-
.../BlueprintConfigurationProcessorTest.java | 29 ++++++++++++--------
2 files changed, 19 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/5113e995/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
index 3538945..5a6e2cc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessor.java
@@ -2730,7 +2730,7 @@ public class BlueprintConfigurationProcessor {
atlasPropsMap.put("atlas.kafka.bootstrap.servers", new MultipleHostTopologyUpdater("KAFKA_BROKER"));
atlasPropsMap.put("atlas.kafka.zookeeper.connect", new MultipleHostTopologyUpdater("ZOOKEEPER_SERVER"));
atlasPropsMap.put("atlas.graph.index.search.solr.zookeeper-url", new MultipleHostTopologyUpdater("ZOOKEEPER_SERVER", ',', false, true, true));
- atlasPropsMap.put("atlas.graph.storage.hostname", new MultipleHostTopologyUpdater("HBASE_MASTER"));
+ atlasPropsMap.put("atlas.graph.storage.hostname", new MultipleHostTopologyUpdater("ZOOKEEPER_SERVER"));
atlasPropsMap.put("atlas.audit.hbase.zookeeper.quorum", new MultipleHostTopologyUpdater("ZOOKEEPER_SERVER"));
// RANGER_ADMIN
http://git-wip-us.apache.org/repos/asf/ambari/blob/5113e995/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
index 734dd7e..68d6349 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/BlueprintConfigurationProcessorTest.java
@@ -4997,6 +4997,7 @@ public class BlueprintConfigurationProcessorTest extends EasyMockSupport {
@Test
public void testAtlas() throws Exception {
final String expectedHostGroupName = "host_group_1";
+ final String zkHostGroupName = "zk_host_group";
final String host1 = "c6401.ambari.apache.org";
final String host2 = "c6402.ambari.apache.org";
final String host3 = "c6403.ambari.apache.org";
@@ -5015,18 +5016,24 @@ public class BlueprintConfigurationProcessorTest extends EasyMockSupport {
Configuration clusterConfig = new Configuration(properties, Collections.emptyMap());
- Collection<String> hgComponents = new HashSet<>();
- hgComponents.add("KAFKA_BROKER");
- hgComponents.add("ZOOKEEPER_SERVER");
- hgComponents.add("HBASE_MASTER");
+ Collection<String> hg1Components = new HashSet<>();
+ hg1Components.add("KAFKA_BROKER");
+ hg1Components.add("HBASE_MASTER");
List<String> hosts = new ArrayList<>();
hosts.add(host1);
hosts.add(host2);
- hosts.add(host3);
- TestHostGroup group1 = new TestHostGroup(expectedHostGroupName, hgComponents, hosts);
+ TestHostGroup group1 = new TestHostGroup(expectedHostGroupName, hg1Components, hosts);
+
+ // Place ZOOKEEPER_SERVER in separate host group/host other
+ // than ATLAS
+ Collection<String> zkHostGroupComponents = new HashSet<>();
+ zkHostGroupComponents.add("ZOOKEEPER_SERVER");
+
+ TestHostGroup group2 = new TestHostGroup(zkHostGroupName, zkHostGroupComponents, Collections.singletonList(host3));
Collection<TestHostGroup> hostGroups = new HashSet<>();
hostGroups.add(group1);
+ hostGroups.add(group2);
ClusterTopology topology = createClusterTopology(bp, clusterConfig, hostGroups);
BlueprintConfigurationProcessor updater = new BlueprintConfigurationProcessor(topology);
@@ -5037,29 +5044,29 @@ public class BlueprintConfigurationProcessorTest extends EasyMockSupport {
List<String> hostArray =
Arrays.asList(atlasProperties.get("atlas.kafka.bootstrap.servers").split(","));
List<String> expected =
- Arrays.asList("c6401.ambari.apache.org:6667", "c6402.ambari.apache.org:6667", "c6403.ambari.apache.org:6667");
+ Arrays.asList("c6401.ambari.apache.org:6667", "c6402.ambari.apache.org:6667");
Assert.assertTrue(hostArray.containsAll(expected) && expected.containsAll(hostArray));
hostArray = Arrays.asList(atlasProperties.get("atlas.kafka.zookeeper.connect").split(","));
expected =
- Arrays.asList("c6401.ambari.apache.org:2181", "c6402.ambari.apache.org:2181", "c6403.ambari.apache.org:2181");
+ Arrays.asList("c6403.ambari.apache.org:2181");
Assert.assertTrue(hostArray.containsAll(expected) && expected.containsAll(hostArray));
hostArray = Arrays.asList(atlasProperties.get("atlas.graph.index.search.solr.zookeeper-url").split(","));
expected =
- Arrays.asList("c6401.ambari.apache.org:2181/ambari-solr", "c6402.ambari.apache.org:2181/ambari-solr", "c6403.ambari.apache.org:2181/ambari-solr");
+ Arrays.asList("c6403.ambari.apache.org:2181/ambari-solr");
Assert.assertTrue(hostArray.containsAll(expected) && expected.containsAll(hostArray));
hostArray = Arrays.asList(atlasProperties.get("atlas.graph.storage.hostname").split(","));
expected =
- Arrays.asList("c6401.ambari.apache.org", "c6402.ambari.apache.org", "c6403.ambari.apache.org");
+ Arrays.asList("c6403.ambari.apache.org");
Assert.assertTrue(hostArray.containsAll(expected) && expected.containsAll(hostArray));
hostArray = Arrays.asList(atlasProperties.get("atlas.audit.hbase.zookeeper.quorum").split(","));
expected =
- Arrays.asList("c6401.ambari.apache.org", "c6402.ambari.apache.org", "c6403.ambari.apache.org");
+ Arrays.asList("c6403.ambari.apache.org");
Assert.assertTrue(hostArray.containsAll(expected) && expected.containsAll(hostArray));
}
[30/38] ambari git commit: AMBARI-21307 Groups for the test user
returned to the caller
Posted by lp...@apache.org.
AMBARI-21307 Groups for the test user returned to the caller
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/faf95340
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/faf95340
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/faf95340
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: faf953409e8b0796569050550c0056df69e1fdc6
Parents: 3ad545a
Author: lpuskas <lp...@apache.org>
Authored: Tue Aug 8 15:50:29 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:30 2017 +0200
----------------------------------------------------------------------
.../api/services/ldap/LdapRestService.java | 16 +++++-
.../server/ldap/AmbariLdapConfiguration.java | 2 +-
.../apache/ambari/server/ldap/LdapModule.java | 3 +
.../server/ldap/service/AmbariLdapFacade.java | 3 +-
.../ambari/server/ldap/service/LdapFacade.java | 3 +-
...efaultLdapConfigurationValidatorService.java | 25 ++++++---
.../ad/DefaultLdapConnectionService.java | 2 +-
...ltLdapConfigurationValidatorServiceTest.java | 59 +++-----------------
8 files changed, 49 insertions(+), 64 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
index 33b10fa..8578204 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
@@ -28,6 +28,8 @@
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;
@@ -41,12 +43,16 @@ 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.AmbariLdapConfiguration;
import org.apache.ambari.server.ldap.LdapConfigurationFactory;
import org.apache.ambari.server.ldap.service.LdapFacade;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.google.common.collect.Sets;
+
/**
* Endpoint designated to LDAP specific operations.
*/
@@ -68,6 +74,8 @@ public class LdapRestService extends BaseService {
@Consumes(MediaType.APPLICATION_JSON)
public Response validateConfiguration(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+ Set<String> groups = Sets.newHashSet();
+
Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
try {
@@ -86,7 +94,11 @@ public class LdapRestService extends BaseService {
case "test-attributes":
LOGGER.info("Testing LDAP attributes ....");
- ldapFacade.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+ groups = ldapFacade.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+ // todo factor out the resource creation, design better the structure in the response
+ Resource resource = new ResourceImpl(Resource.Type.AmbariConfiguration);
+ resource.setProperty("groups", groups);
+ result.getResultTree().addChild(resource, "payload");
break;
case "detect-attributes":
@@ -101,7 +113,7 @@ public class LdapRestService extends BaseService {
}
} catch (Exception e) {
- result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
+ result.setResultStatus(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
}
return Response.status(result.getStatus().getStatusCode()).entity(getResultSerializer().serialize(result)).build();
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index a6ff80b..8ab587b 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -48,7 +48,7 @@ public class AmbariLdapConfiguration {
MANAGER_PASSWORD("ambari.ldap.managerpassword"),
USER_OBJECT_CLASS("ambari.ldap.user.object.class"),
USER_NAME_ATTRIBUTE("ambari.ldap.user.name.attribute"),
- USER_SEARCH_BASE("ambari.ldap.user.search.Base"),
+ USER_SEARCH_BASE("ambari.ldap.user.search.base"),
GROUP_OBJECT_CLASS("ambari.ldap.group.object.class"),
GROUP_NAME_ATTRIBUTE("ambari.ldap.group.name.attribute"),
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/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 545f220..1b49159 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,8 +16,10 @@
package org.apache.ambari.server.ldap;
import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
import org.apache.ambari.server.ldap.service.LdapFacade;
import org.apache.ambari.server.ldap.service.ad.DefaultLdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.ad.DefaultLdapConnectionService;
import com.google.inject.AbstractModule;
import com.google.inject.assistedinject.FactoryModuleBuilder;
@@ -31,6 +33,7 @@ public class LdapModule extends AbstractModule {
protected void configure() {
bind(LdapFacade.class).to(AmbariLdapFacade.class);
bind(LdapConfigurationValidatorService.class).to(DefaultLdapConfigurationValidatorService.class);
+ bind(LdapConnectionService.class).to(DefaultLdapConnectionService.class);
install(new FactoryModuleBuilder().build(LdapConfigurationFactory.class));
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index abb464b..eec47ce 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -79,7 +79,7 @@ public class AmbariLdapFacade implements LdapFacade {
}
@Override
- public void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
+ public Set<String> checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariLdapException {
String userName = getTestUserNameFromParameters(parameters);
String testUserPass = getTestUserPasswordFromParameters(parameters);
@@ -95,6 +95,7 @@ public class AmbariLdapFacade implements LdapFacade {
LOGGER.info("Testing LDAP group attributes with test user dn: {}", userDn);
Set<String> groups = ldapConfigurationValidatorService.checkGroupAttributes(ldapConnection, userDn, ldapConfiguration);
+ return groups;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
index 7bb1198..eadff7d 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -15,6 +15,7 @@
package org.apache.ambari.server.ldap.service;
import java.util.Map;
+import java.util.Set;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
@@ -47,5 +48,5 @@ public interface LdapFacade {
* @param ambariLdapConfiguration configutration instance with available attributes
* @throws AmbariLdapException if the attribute checking fails
*/
- void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
+ Set<String> checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
index 838ef4c..a8503ca 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorService.java
@@ -37,7 +37,6 @@ import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
import org.apache.directory.api.ldap.model.message.SearchScope;
import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.ldap.client.api.LdapConnection;
-import org.apache.directory.ldap.client.api.LdapNetworkConnection;
import org.apache.directory.ldap.client.api.search.FilterBuilder;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.slf4j.Logger;
@@ -84,18 +83,18 @@ public class DefaultLdapConfigurationValidatorService implements LdapConfigurati
* @param testUserName the test username
* @param testPassword the test password
* @param ambariLdapConfiguration configuration instance holding ldap configuration details
+ * @return the DN of the test user
* @throws AmbariException if the attributes are not valid or any errors occurs
*/
@Override
public String checkUserAttributes(LdapConnection ldapConnection, String testUserName, String testPassword, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
- LdapNetworkConnection connection = null;
SearchCursor searchCursor = null;
String userDn = null;
try {
LOGGER.info("Checking user attributes for user {} r ...", testUserName);
// bind anonimously or with manager data
- bind(ambariLdapConfiguration, connection);
+ bind(ambariLdapConfiguration, ldapConnection);
// set up a filter based on the provided attributes
String filter = FilterBuilder.and(
@@ -104,7 +103,7 @@ public class DefaultLdapConfigurationValidatorService implements LdapConfigurati
.toString();
LOGGER.info("Searching for the user: {} using the search filter: {}", testUserName, filter);
- EntryCursor entryCursor = connection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
+ EntryCursor entryCursor = ldapConnection.search(new Dn(ambariLdapConfiguration.userSearchBase()), filter, SearchScope.SUBTREE);
// collecting search result entries
List<Entry> users = Lists.newArrayList();
@@ -128,7 +127,7 @@ public class DefaultLdapConfigurationValidatorService implements LdapConfigurati
throw new AmbariLdapException(e.getMessage(), e);
} finally {
- closeResources(connection, searchCursor);
+ closeResources(ldapConnection, searchCursor);
}
return userDn;
}
@@ -172,14 +171,19 @@ public class DefaultLdapConfigurationValidatorService implements LdapConfigurati
throw new AmbariLdapException(e.getMessage(), e);
} finally {
-
closeResources(ldapConnection, searchCursor);
-
}
return processGroupResults(groupResponses, ambariLdapConfiguration);
}
+ /**
+ * Binds to the LDAP server (anonimously or wit manager credentials)
+ *
+ * @param ambariLdapConfiguration configuration instance
+ * @param connection connection instance
+ * @throws LdapException if the bind operation fails
+ */
private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
LOGGER.info("Connecting to LDAP ....");
if (!ambariLdapConfiguration.bindAnonimously()) {
@@ -198,6 +202,13 @@ public class DefaultLdapConfigurationValidatorService implements LdapConfigurati
}
+ /**
+ * Extracts meaningful values from the search result.
+ *
+ * @param groupResponses the result entries returned by the search
+ * @param ambariLdapConfiguration holds the keys of the meaningful attributes
+ * @return a set with the group names the test user belongs to
+ */
private Set<String> processGroupResults(Set<Response> groupResponses, AmbariLdapConfiguration ambariLdapConfiguration) {
Set<String> groupStrSet = Sets.newHashSet();
for (Response response : groupResponses) {
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
index b5559d9..25dc1f2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConnectionService.java
@@ -56,7 +56,7 @@ public class DefaultLdapConnectionService implements LdapConnectionService {
ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
- //todo set the other values as required
+ // todo set the other values as required
return ldapConnectionConfig;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/faf95340/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
index 5c9d304..663ea12 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/DefaultLdapConfigurationValidatorServiceTest.java
@@ -18,23 +18,15 @@ import static org.junit.Assert.assertNotNull;
import java.util.Map;
-import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
import org.apache.ambari.server.ldap.service.LdapConnectionService;
import org.apache.directory.api.ldap.model.cursor.EntryCursor;
-import org.apache.directory.api.ldap.model.cursor.SearchCursor;
import org.apache.directory.api.ldap.model.entry.Entry;
-import org.apache.directory.api.ldap.model.message.Response;
-import org.apache.directory.api.ldap.model.message.SearchRequest;
-import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
-import org.apache.directory.api.ldap.model.message.SearchResultEntry;
import org.apache.directory.api.ldap.model.message.SearchScope;
-import org.apache.directory.api.ldap.model.name.Dn;
import org.apache.directory.ldap.client.api.LdapConnection;
import org.apache.directory.ldap.client.api.LdapConnectionConfig;
import org.apache.directory.ldap.client.api.LdapNetworkConnection;
-import org.apache.directory.ldap.client.api.search.FilterBuilder;
import org.apache.directory.shared.ldap.constants.SchemaConstants;
import org.junit.Test;
import org.slf4j.Logger;
@@ -75,57 +67,24 @@ public class DefaultLdapConfigurationValidatorServiceTest {
@Test
public void testCheckUserAttributes() throws Exception {
+ // GIVEN
Map<String, Object> ldapPropsMap = Maps.newHashMap();
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), false);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_SEARCH_BASE.propertyName(), "dc=example,dc=com");
- AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
-
-
- try {
- LOGGER.info("Authenticating user {} against the LDAP server ...", TEST_USER);
- LdapConnectionService connectionService = new DefaultLdapConnectionService();
- LdapNetworkConnection connection = connectionService.createLdapConnection(ambariLdapConfiguration);
-
- String filter = FilterBuilder.and(
- FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
- FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), TEST_USER))
- .toString();
-
- SearchRequest searchRequest = new SearchRequestImpl();
- searchRequest.setBase(new Dn(ambariLdapConfiguration.baseDn()));
- searchRequest.setFilter(filter);
- searchRequest.setScope(SearchScope.SUBTREE);
- LOGGER.info("loking up user: {} based on the filtr: {}", TEST_USER, filter);
-
- connection.bind();
- SearchCursor searchCursor = connection.search(searchRequest);
-
- while (searchCursor.next()) {
- Response response = searchCursor.get();
-
- // process the SearchResultEntry
- if (response instanceof SearchResultEntry) {
- Entry resultEntry = ((SearchResultEntry) response).getEntry();
- System.out.println(resultEntry);
- }
- }
-
- searchCursor.close();
-
- } catch (Exception e) {
- throw new AmbariException("Error during user authentication check", e);
- }
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+ ldapConfigurationValidatorService.checkUserAttributes(ldapConnection, "einstein", "", ambariLdapConfiguration);
}
@Test
@@ -138,8 +97,6 @@ public class DefaultLdapConfigurationValidatorServiceTest {
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
[04/38] ambari git commit: AMBARI-21634. Make sure Ambari also
considers NIS users (Aman Poonia via ncole)
Posted by lp...@apache.org.
AMBARI-21634. Make sure Ambari also considers NIS users (Aman Poonia via ncole)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f89dcd7d
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f89dcd7d
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f89dcd7d
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: f89dcd7d03d18a57543f2a86653345ad3ab00095
Parents: 02bea54
Author: Nate Cole <nc...@hortonworks.com>
Authored: Tue Sep 12 10:19:41 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Tue Sep 12 10:19:41 2017 -0400
----------------------------------------------------------------------
.../src/main/python/ambari_agent/HostInfo.py | 29 +++++++++++---------
.../test/python/ambari_agent/TestHostInfo.py | 21 ++++----------
2 files changed, 21 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/f89dcd7d/ambari-agent/src/main/python/ambari_agent/HostInfo.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/HostInfo.py b/ambari-agent/src/main/python/ambari_agent/HostInfo.py
index 5f96df5..b8545cc 100644
--- a/ambari-agent/src/main/python/ambari_agent/HostInfo.py
+++ b/ambari-agent/src/main/python/ambari_agent/HostInfo.py
@@ -21,6 +21,7 @@ limitations under the License.
import glob
import logging
import os
+import pwd
import re
import shlex
import socket
@@ -170,13 +171,13 @@ class HostInfoLinux(HostInfo):
"hue", "yarn", "tez", "storm", "falcon", "kafka", "knox", "ams",
"hadoop", "spark", "accumulo", "atlas", "mahout", "ranger", "kms", "zeppelin"
]
-
+
# Default set of directories that are checked for existence of files and folders
DEFAULT_BASEDIRS = [
"/etc", "/var/run", "/var/log", "/usr/lib", "/var/lib", "/var/tmp", "/tmp", "/var",
"/hadoop", "/usr/hdp"
]
-
+
# Exact directories names which are checked for existance
EXACT_DIRECTORIES = [
"/kafka-logs"
@@ -193,15 +194,17 @@ class HostInfoLinux(HostInfo):
super(HostInfoLinux, self).__init__(config)
def checkUsers(self, users, results):
- f = open('/etc/passwd', 'r')
- for userLine in f:
- fields = userLine.split(":")
- if fields[0] in users:
- result = {}
- result['name'] = fields[0]
- result['homeDir'] = fields[5]
- result['status'] = "Available"
- results.append(result)
+ for user in users:
+ try:
+ pw = pwd.getpwnam(user)
+ result = {}
+ result['name'] = pw.pw_name
+ result['homeDir'] = pw.pw_dir
+ result['status'] = "Available"
+ results.append(result)
+ except Exception as e:
+ #User doesnot exist, so skip it
+ pass
def checkFolders(self, basePaths, projectNames, exactDirectories, existingUsers, dirs):
foldersToIgnore = []
@@ -216,13 +219,13 @@ class HostInfoLinux(HostInfo):
obj['type'] = self.dirType(path)
obj['name'] = path
dirs.append(obj)
-
+
for path in exactDirectories:
if os.path.exists(path):
obj = {}
obj['type'] = self.dirType(path)
obj['name'] = path
- dirs.append(obj)
+ dirs.append(obj)
except:
logger.exception("Checking folders failed")
http://git-wip-us.apache.org/repos/asf/ambari/blob/f89dcd7d/ambari-agent/src/test/python/ambari_agent/TestHostInfo.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/test/python/ambari_agent/TestHostInfo.py b/ambari-agent/src/test/python/ambari_agent/TestHostInfo.py
index cb20f4e..3c46268 100644
--- a/ambari-agent/src/test/python/ambari_agent/TestHostInfo.py
+++ b/ambari-agent/src/test/python/ambari_agent/TestHostInfo.py
@@ -59,26 +59,15 @@ class TestHostInfo(TestCase):
self.assertTrue(item in names)
- @patch('os.path.exists')
- @patch('__builtin__.open')
- def test_checkUsers(self, builtins_open_mock, path_mock):
- builtins_open_mock.return_value = [
- "hdfs:x:493:502:Hadoop HDFS:/usr/lib/hadoop:/bin/bash",
- "zookeeper:x:492:502:ZooKeeper:/var/run/zookeeper:/bin/bash"]
- path_mock.side_effect = [False, True, False]
-
+ def test_checkUsers(self):
hostInfo = HostInfoLinux()
results = []
- hostInfo.checkUsers(["zookeeper", "hdfs"], results)
- self.assertEqual(2, len(results))
+ hostInfo.checkUsers(["root", "zxlmnap12341234"], results)
+ self.assertEqual(1, len(results))
newlist = sorted(results, key=lambda k: k['name'])
- self.assertTrue(newlist[0]['name'], "hdfs")
- self.assertTrue(newlist[1]['name'], "zookeeper")
- self.assertTrue(newlist[0]['homeDir'], "/usr/lib/hadoop")
- self.assertTrue(newlist[1]['homeDir'], "/var/run/zookeeper")
+ self.assertTrue(newlist[0]['name'], "root")
+ self.assertTrue(newlist[0]['homeDir'], "/root")
self.assertTrue(newlist[0]['status'], "Available")
- self.assertTrue(newlist[1]['status'], "Invalid home directory")
- print(path_mock.mock_calls)
@patch.object(OSCheck, "get_os_type")
@patch('os.umask')
[34/38] ambari git commit: AMBARI-21307 Add all known LDAP properties
to AmbariConfigurationEnum (benyoka)
Posted by lp...@apache.org.
AMBARI-21307 Add all known LDAP properties to AmbariConfigurationEnum (benyoka)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2750e627
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2750e627
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2750e627
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 2750e6270c16b9788ad64d72656e5c8320e2e5ba
Parents: 37f9005
Author: Balazs Bence Sari <be...@apache.org>
Authored: Mon Sep 4 12:45:07 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:31 2017 +0200
----------------------------------------------------------------------
.../ambari/server/ldap/AmbariLdapConfiguration.java | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2750e627/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index b1cbced..e913e77 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -40,22 +40,35 @@ public class AmbariLdapConfiguration {
USE_SSL("ambari.ldap.usessl"),
LDAP_SERVER_HOST("ambari.ldap.server.host"),
LDAP_SERVER_PORT("ambari.ldap.server.port"),
+ LDAP_TRUSTSTORE("ambari.ldap.truststore"),
LDAP_TRUSTSTORE_TYPE("ambari.ldap.truststore.type"),
LDAP_TRUSTSTORE_PATH("ambari.ldap.truststore.path"),
+ LDAP_TRUSTSTORE_PASSWORD("ambari.ldap.truststore.password"),
BASE_DN("ambari.ldap.bind.dn"),
+ REFERRAL("ambari.ldap.referral"),
+ PAGINATION_ENABLED("ambari.ldap.pagination.enabled"),
BIND_ANONIMOUSLY("ambari.ldap.bindanonymously"),
MANAGER_DN("ambari.ldap.managerdn"),
MANAGER_PASSWORD("ambari.ldap.managerpassword"),
USER_OBJECT_CLASS("ambari.ldap.user.object.class"),
USER_NAME_ATTRIBUTE("ambari.ldap.user.name.attribute"),
+ USER_NAME_FORCE_LOWERCASE("ambari.ldap.username.force.lowercase"),
USER_SEARCH_BASE("ambari.ldap.user.search.base"),
+ SYNC_USER_MEMBER_REPLACE_PATTERN("ambari.ldap.sync.user.member.replacepattern"),
+ SYNC_USER_MEMBER_FILTER("ambari.ldap.sync.user.member_filter"),
+ ADMIN_GROUP_MAPPING_RULES ("ambari.ldap.admin.group.mappingrules"),
GROUP_OBJECT_CLASS("ambari.ldap.group.object.class"),
GROUP_NAME_ATTRIBUTE("ambari.ldap.group.name.attribute"),
GROUP_MEMBER_ATTRIBUTE("ambari.ldap.group.member.attribute"),
GROUP_SEARCH_BASE("ambari.ldap.group.search.base"),
- DN_ATTRIBUTE("authentication.ldap.dnAttribute");
+ SYNC_GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.sync.group.member.replacepattern"),
+ SYNC_GROUP_MEMBER_FILTER("ambari.ldap.sync.group.member_filter"),
+ DN_ATTRIBUTE("authentication.ldap.dnAttribute"),
+
+ TEST_USER_NAME("ambari.ldap.test.user.name"),
+ TEST_USER_PASSWORD("ambari.ldap.test.user.password");
private String propertyName;
[03/38] ambari git commit: AMBARI-21785. Component restart
instructions in case of OUT_OF_SYNC (alexantonenko)
Posted by lp...@apache.org.
AMBARI-21785. Component restart instructions in case of OUT_OF_SYNC (alexantonenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/02bea547
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/02bea547
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/02bea547
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 02bea547cd71e6aff173f04d0154b25ebe85432a
Parents: 001f290
Author: Alex Antonenko <aa...@hortonworks.com>
Authored: Tue Sep 12 16:26:12 2017 +0300
Committer: Alex Antonenko <aa...@hortonworks.com>
Committed: Tue Sep 12 16:26:12 2017 +0300
----------------------------------------------------------------------
ambari-web/app/messages.js | 2 ++
.../admin/stack_upgrade/stack_upgrade_wizard.hbs | 4 ++++
.../main/admin/stack_upgrade/upgrade_wizard_view.js | 4 +++-
.../admin/stack_upgrade/upgrade_wizard_view_test.js | 16 ++++++++++++++++
4 files changed, 25 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/02bea547/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index bec2ca5..bda8228 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -1852,6 +1852,8 @@ Em.I18n.translations = {
'admin.stackUpgrade.failedHosts.options.first': "<b>Pause Upgrade</b>, delete the unhealthy hosts and return to the Upgrade Wizard to Proceed.",
'admin.stackUpgrade.failedHosts.options.second': "Perform a <b>Downgrade</b>, which will revert all hosts to the previous stack version.",
'admin.stackUpgrade.failedHosts.options.third': "Ignore these failures and <b>Proceed</b> for now (reconcile the failures later).",
+ 'admin.stackUpgrade.failedHosts.isOutOfSync.options.first' : '<b>Pause Upgrade</b> and restart the component',
+ 'admin.stackUpgrade.failedHosts.isOutOfSync.options.second' : '<b>Restart</b> the Ambari Agent',
'admin.stackUpgrade.failedHosts.header': "Failed Hosts",
'admin.stackUpgrade.failedHosts.subHeader': "Upgrade failed on {0} hosts",
'admin.stackUpgrade.failedHosts.details': "Open Details",
http://git-wip-us.apache.org/repos/asf/ambari/blob/02bea547/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs b/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs
index 6d06f91..cfbbb7a 100644
--- a/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs
+++ b/ambari-web/app/templates/main/admin/stack_upgrade/stack_upgrade_wizard.hbs
@@ -180,6 +180,10 @@
<p>
{{t admin.stackUpgrade.failedHosts.options}}
<ul>
+ {{#if view.isOutOfSync}}
+ <li>{{t admin.stackUpgrade.failedHosts.isOutOfSync.options.first}}</li>
+ <li>{{t admin.stackUpgrade.failedHosts.isOutOfSync.options.second}}</li>
+ {{/if}}
<li>{{t admin.stackUpgrade.failedHosts.options.first}}</li>
{{#if view.isDowngradeAvailable}}
<li>{{t admin.stackUpgrade.failedHosts.options.second}}</li>
http://git-wip-us.apache.org/repos/asf/ambari/blob/02bea547/ambari-web/app/views/main/admin/stack_upgrade/upgrade_wizard_view.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_wizard_view.js b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_wizard_view.js
index 10e34ab..a5e7730 100644
--- a/ambari-web/app/views/main/admin/stack_upgrade/upgrade_wizard_view.js
+++ b/ambari-web/app/views/main/admin/stack_upgrade/upgrade_wizard_view.js
@@ -192,7 +192,9 @@ App.upgradeWizardView = Em.View.extend({
*/
isSlaveComponentFailuresItem: function () {
var item = this.get('activeGroup.upgradeItems') && this.get('activeGroup.upgradeItems').findProperty('context', this.get("controller.slaveFailuresContext"));
- return item && ['HOLDING', 'HOLDING_FAILED'].contains(item.get('status'));
+ var status = item && item.get('status');
+ this.set('isOutOfSync', status === 'OUT_OF_SYNC');
+ return ['HOLDING', 'HOLDING_FAILED', 'OUT_OF_SYNC'].contains(status);
}.property('activeGroup.upgradeItems.@each.status', 'activeGroup.upgradeItems.@each.context'),
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/02bea547/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js
----------------------------------------------------------------------
diff --git a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js
index 7ae785c..8ad711e 100644
--- a/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js
+++ b/ambari-web/test/views/main/admin/stack_upgrade/upgrade_wizard_view_test.js
@@ -868,6 +868,22 @@ describe('App.upgradeWizardView', function () {
expect(view.get('controller.areSlaveComponentFailuresHostsLoaded')).to.be.true;
});
});
+ it("isSlaveComponentFailuresItem must be true when status is OUT_OF_SYNC", function () {
+ view.reopen({
+ activeStatuses: ['OUT_OF_SYNC'],
+ upgradeGroups: [Em.Object.create({
+ status: 'OUT_OF_SYNC'
+ })]
+ });
+ view.propertyDidChange('activeGroup');
+ view.set('activeGroup.upgradeItems', [Em.Object.create({
+ context: view.get("controller.slaveFailuresContext"),
+ status: 'OUT_OF_SYNC'
+ })]);
+
+ expect(view.get('isSlaveComponentFailuresItem')).to.be.true;
+ expect(view.get('isOutOfSync')).to.be.true;
+ });
describe("#getServiceCheckItem()", function() {
beforeEach(function () {
[17/38] ambari git commit: AMBARI-21810. Create Utility Script to
support Solr Collection Data Retention/Purging/Archiving (mgergely)
Posted by lp...@apache.org.
AMBARI-21810. Create Utility Script to support Solr Collection Data Retention/Purging/Archiving (mgergely)
Change-Id: Ie25e5187e6e96d5b14267491fb7a9a992529b405
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/153d0da7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/153d0da7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/153d0da7
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 153d0da771d1ad523ad90b487fa185aa2bf0d52d
Parents: 2a6dd58
Author: Miklos Gergely <mg...@hortonworks.com>
Authored: Wed Sep 13 16:46:02 2017 +0200
Committer: Miklos Gergely <mg...@hortonworks.com>
Committed: Wed Sep 13 16:46:02 2017 +0200
----------------------------------------------------------------------
ambari-infra/ambari-infra-solr-client/build.xml | 1 +
ambari-infra/ambari-infra-solr-client/pom.xml | 5 +
.../apache/ambari/infra/solr/S3Uploader.java | 64 ++
.../src/main/python/solrDataManager.py | 715 +++++++++++++++++++
4 files changed, 785 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/153d0da7/ambari-infra/ambari-infra-solr-client/build.xml
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-solr-client/build.xml b/ambari-infra/ambari-infra-solr-client/build.xml
index 9b8b6cc..25ff0cb 100644
--- a/ambari-infra/ambari-infra-solr-client/build.xml
+++ b/ambari-infra/ambari-infra-solr-client/build.xml
@@ -36,6 +36,7 @@
<copy todir="target/package" includeEmptyDirs="no">
<fileset file="src/main/resources/solrCloudCli.sh"/>
<fileset file="src/main/resources/solrIndexHelper.sh"/>
+ <fileset file="src/main/python/solrDataManager.py"/>
</copy>
<copy todir="target/package" includeEmptyDirs="no">
<fileset file="src/main/resources/log4j.properties"/>
http://git-wip-us.apache.org/repos/asf/ambari/blob/153d0da7/ambari-infra/ambari-infra-solr-client/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-solr-client/pom.xml b/ambari-infra/ambari-infra-solr-client/pom.xml
index 3818aba..0d32374 100644
--- a/ambari-infra/ambari-infra-solr-client/pom.xml
+++ b/ambari-infra/ambari-infra-solr-client/pom.xml
@@ -82,6 +82,11 @@
<artifactId>log4j</artifactId>
</dependency>
<dependency>
+ <groupId>com.amazonaws</groupId>
+ <artifactId>aws-java-sdk-s3</artifactId>
+ <version>1.11.5</version>
+ </dependency>
+ <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
http://git-wip-us.apache.org/repos/asf/ambari/blob/153d0da7/ambari-infra/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/S3Uploader.java
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/S3Uploader.java b/ambari-infra/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/S3Uploader.java
new file mode 100644
index 0000000..60b4e0a
--- /dev/null
+++ b/ambari-infra/ambari-infra-solr-client/src/main/java/org/apache/ambari/infra/solr/S3Uploader.java
@@ -0,0 +1,64 @@
+/*
+ * 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.infra.solr;
+
+import java.io.File;
+
+import org.apache.commons.io.FileUtils;
+
+import com.amazonaws.auth.BasicAWSCredentials;
+import com.amazonaws.services.s3.AmazonS3Client;
+
+/**
+ * Uploads a file to S3, meant to be used by solrDataManager.py
+ */
+public class S3Uploader {
+ public static void main(String[] args) {
+ try {
+ String keyFilePath = args[0];
+ String bucketName = args[1];
+ String keyPrefix = args[2];
+ String filePath = args[3];
+
+ String keyFileContent = FileUtils.readFileToString(new File(keyFilePath)).trim();
+ String[] keys = keyFileContent.split(",");
+ String accessKey = keys[0];
+ String secretKey = keys[1];
+
+ BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
+ AmazonS3Client client = new AmazonS3Client(credentials);
+
+ File file = new File(filePath);
+ String key = keyPrefix + file.getName();
+
+ if (client.doesObjectExist(bucketName, key)) {
+ System.out.println("Object '" + key + "' already exists");
+ System.exit(0);
+ }
+
+ client.putObject(bucketName, key, file);
+ } catch (Exception e) {
+ e.printStackTrace(System.err);
+ System.exit(1);
+ }
+
+ System.exit(0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/153d0da7/ambari-infra/ambari-infra-solr-client/src/main/python/solrDataManager.py
----------------------------------------------------------------------
diff --git a/ambari-infra/ambari-infra-solr-client/src/main/python/solrDataManager.py b/ambari-infra/ambari-infra-solr-client/src/main/python/solrDataManager.py
new file mode 100644
index 0000000..d17aec7
--- /dev/null
+++ b/ambari-infra/ambari-infra-solr-client/src/main/python/solrDataManager.py
@@ -0,0 +1,715 @@
+#!/usr/bin/python
+
+'''
+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.
+'''
+
+import hashlib
+import json
+import logging
+import optparse
+import os
+import time
+import signal
+import sys
+
+from datetime import datetime, timedelta
+from subprocess import call, Popen, PIPE
+from urllib import quote, unquote
+from zipfile import ZipFile, ZIP_DEFLATED
+import tarfile
+
+VERSION = "1.0"
+
+logger = logging.getLogger()
+handler = logging.StreamHandler()
+formatter = logging.Formatter("%(asctime)s - %(message)s")
+handler.setFormatter(formatter)
+logger.addHandler(handler)
+verbose = False
+
+def parse_arguments():
+ parser = optparse.OptionParser("usage: %prog [options]", version="Solr Data Manager {0}".format(VERSION))
+
+ parser.add_option("-m", "--mode", dest="mode", type="string", help="delete | save")
+ parser.add_option("-s", "--solr-url", dest="solr_url", type="string", help="the url of the solr server including the port")
+ parser.add_option("-c", "--collection", dest="collection", type="string", help="the name of the solr collection")
+ parser.add_option("-f", "--filter-field", dest="filter_field", type="string", help="the name of the field to filter on")
+ parser.add_option("-r", "--read-block-size", dest="read_block_size", type="int", help="block size to use for reading from solr",
+ default=1000)
+ parser.add_option("-w", "--write-block-size", dest="write_block_size", type="int", help="number of records in the output files",
+ default=100000)
+ parser.add_option("-i", "--id-field", dest="id_field", type="string", help="the name of the id field", default="id")
+
+ end_group = optparse.OptionGroup(parser, "specifying the end of the range")
+ end_group.add_option("-e", "--end", dest="end", type="string", help="end of the range")
+ end_group.add_option("-d", "--days", dest="days", type="int", help="number of days to keep")
+ parser.add_option_group(end_group)
+
+ parser.add_option("-o", "--date-format", dest="date_format", type="string", help="the date format to use for --days",
+ default="%Y-%m-%dT%H:%M:%S.%fZ")
+
+ parser.add_option("-q", "--additional-filter", dest="additional_filter", type="string", help="additional solr filter")
+ parser.add_option("--name", dest="name", type="string", help="name included in result files")
+
+ parser.add_option("-g", "--ignore-unfinished-uploading", dest="ignore_unfinished_uploading", action="store_true", default=False)
+
+ parser.add_option("-j", "--line-delimited", dest="line_delimited", help="line delmited json output", action="store_true", default=False)
+ parser.add_option("-z", "--compression", dest="compression", help="none | tar.gz | tar.bz2 | zip", default="tar.gz")
+
+ parser.add_option("-k", "--solr-keytab", dest="solr_keytab", type="string", help="the keytab for a kerberized solr")
+ parser.add_option("-n", "--solr-principal", dest="solr_principal", type="string", help="the principal for a kerberized solr")
+
+ parser.add_option("-a", "--hdfs-keytab", dest="hdfs_keytab", type="string", help="the keytab for a kerberized hdfs")
+ parser.add_option("-l", "--hdfs-principal", dest="hdfs_principal", type="string", help="the principal for a kerberized hdfs")
+
+ parser.add_option("-u", "--hdfs-user", dest="hdfs_user", type="string", help="the user for accessing hdfs")
+ parser.add_option("-p", "--hdfs-path", dest="hdfs_path", type="string", help="the hdfs path to upload to")
+
+ parser.add_option("-t", "--key-file-path", dest="key_file_path", type="string", help="the file that contains S3 <accessKey>,<secretKey>")
+ parser.add_option("-b", "--bucket", dest="bucket", type="string", help="the bucket name for S3 upload")
+ parser.add_option("-y", "--key-prefix", dest="key_prefix", type="string", help="the key prefix for S3 upload")
+
+ parser.add_option("-x", "--local-path", dest="local_path", type="string", help="the local path to save the files to")
+
+ parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False)
+
+ (options, args) = parser.parse_args()
+
+ for r in ["mode", "solr_url", "collection", "filter_field"]:
+ if options.__dict__[r] is None:
+ print "argument '{0}' is mandatory".format(r)
+ parser.print_help()
+ sys.exit()
+
+ mode_values = ["delete", "save"]
+ if options.mode not in mode_values:
+ print "mode must be one of {0}".format(" | ".join(mode_values))
+ parser.print_help()
+ sys.exit()
+
+ if options.mode == "delete":
+ for r in ["name", "compression", "hdfs_keytab", "hdfs_principal", "hdfs_user", "hdfs_path", "key_file_path", "bucket", "key_prefix", "local_path"]:
+ if options.__dict__[r] is not None:
+ print "argument '{0}' may not be specified in delete mode".format(r)
+ parser.print_help()
+ sys.exit()
+
+ if options.__dict__["end"] is None and options.__dict__["days"] is None or \
+ options.__dict__["end"] is not None and options.__dict__["days"] is not None:
+ print "exactly one of 'end' or 'days' must be specfied"
+ parser.print_help()
+ sys.exit()
+
+ is_any_solr_kerberos_property = options.__dict__["solr_keytab"] is not None or options.__dict__["solr_principal"] is not None
+ is_all_solr_kerberos_property = options.__dict__["solr_keytab"] is not None and options.__dict__["solr_principal"] is not None
+ if is_any_solr_kerberos_property and not is_all_solr_kerberos_property:
+ print "either both 'solr-keytab' and 'solr-principal' must be specfied, or neither of them"
+ parser.print_help()
+ sys.exit()
+
+ compression_values = ["none", "tar.gz", "tar.bz2", "zip"]
+ if options.compression not in compression_values:
+ print "compression must be one of {0}".format(" | ".join(compression_values))
+ parser.print_help()
+ sys.exit()
+
+ is_any_hdfs_kerberos_property = options.__dict__["hdfs_keytab"] is not None or options.__dict__["hdfs_principal"] is not None
+ is_all_hdfs_kerberos_property = options.__dict__["hdfs_keytab"] is not None and options.__dict__["hdfs_principal"] is not None
+ if is_any_hdfs_kerberos_property and not is_all_hdfs_kerberos_property:
+ print "either both 'hdfs_keytab' and 'hdfs_principal' must be specfied, or neither of them"
+ parser.print_help()
+ sys.exit()
+
+ is_any_hdfs_property = options.__dict__["hdfs_user"] is not None or options.__dict__["hdfs_path"] is not None
+ is_all_hdfs_property = options.__dict__["hdfs_user"] is not None and options.__dict__["hdfs_path"] is not None
+ if is_any_hdfs_property and not is_all_hdfs_property:
+ print "either both 'hdfs_user' and 'hdfs_path' must be specfied, or neither of them"
+ parser.print_help()
+ sys.exit()
+
+ is_any_s3_property = options.__dict__["key_file_path"] is not None or options.__dict__["bucket"] is not None or \
+ options.__dict__["key_prefix"] is not None
+ is_all_s3_property = options.__dict__["key_file_path"] is not None and options.__dict__["bucket"] is not None and \
+ options.__dict__["key_prefix"] is not None
+ if is_any_s3_property and not is_all_s3_property:
+ print "either all the S3 arguments ('key_file_path', 'bucket', 'key_prefix') must be specfied, or none of them"
+ parser.print_help()
+ sys.exit()
+
+ if options.mode == "save":
+ count = (1 if is_any_hdfs_property else 0) + (1 if is_any_s3_property else 0) + \
+ (1 if options.__dict__["local_path"] is not None else 0)
+ if count != 1:
+ print "exactly one of the HDFS arguments ('hdfs_user', 'hdfs_path') or the S3 arguments ('key_file_path', 'bucket', 'key_prefix') or the 'local_path' argument must be specified"
+ parser.print_help()
+ sys.exit()
+
+ if options.__dict__["hdfs_keytab"] is not None and options.__dict__["hdfs_user"] is None:
+ print "HDFS kerberos keytab and principal may only be specified if the upload target is HDFS"
+ parser.print_help()
+ sys.exit()
+
+ print("You are running Solr Data Manager {0} with arguments:".format(VERSION))
+ print(" mode: " + options.mode)
+ print(" solr-url: " + options.solr_url)
+ print(" collection: " + options.collection)
+ print(" filter-field: " + options.filter_field)
+ if options.mode == "save":
+ print(" id-field: " + options.id_field)
+ if options.__dict__["end"] is not None:
+ print(" end: " + options.end)
+ else:
+ print(" days: " + str(options.days))
+ print(" date-format: " + options.date_format)
+ if options.__dict__["additional_filter"] is not None:
+ print(" additional-filter: " + str(options.additional_filter))
+ if options.__dict__["name"] is not None:
+ print(" name: " + str(options.name))
+ if options.mode == "save":
+ print(" read-block-size: " + str(options.read_block_size))
+ print(" write-block-size: " + str(options.write_block_size))
+ print(" ignore-unfinished-uploading: " + str(options.ignore_unfinished_uploading))
+ if (options.__dict__["solr_keytab"] is not None):
+ print(" solr-keytab: " + options.solr_keytab)
+ print(" solr-principal: " + options.solr_principal)
+ if options.mode == "save":
+ print(" line-delimited: " + str(options.line_delimited))
+ print(" compression: " + options.compression)
+ if (options.__dict__["hdfs_keytab"] is not None):
+ print(" hdfs-keytab: " + options.hdfs_keytab)
+ print(" hdfs-principal: " + options.hdfs_principal)
+ if (options.__dict__["hdfs_user"] is not None):
+ print(" hdfs-user: " + options.hdfs_user)
+ print(" hdfs-path: " + options.hdfs_path)
+ if (options.__dict__["key_file_path"] is not None):
+ print(" key-file-path: " + options.key_file_path)
+ print(" bucket: " + options.bucket)
+ print(" key-prefix: " + options.key_prefix)
+ if (options.__dict__["local_path"] is not None):
+ print(" local-path: " + options.local_path)
+ print(" verbose: " + str(options.verbose))
+ print
+
+ if options.__dict__["additional_filter"] is not None and options.__dict__["name"] is None:
+ go = False
+ while not go:
+ sys.stdout.write("It is recommended to set --name in case of any additional filter is set.\n")
+ sys.stdout.write("Are you sure that you want to proceed without a name (yes/no)? ")
+ choice = raw_input().lower()
+ if choice in ['yes', 'ye', 'y']:
+ go = True
+ elif choice in ['no', 'n']:
+ sys.exit()
+
+ return options
+
+def set_log_level():
+ if verbose:
+ logger.setLevel(logging.DEBUG)
+ else:
+ logger.setLevel(logging.INFO)
+
+def get_end(options):
+ if options.end:
+ return options.end
+ else:
+ d = datetime.now() - timedelta(days=options.days)
+ end = d.strftime(options.date_format)
+ logger.info("The end date will be: %s", end)
+ return end
+
+def delete(solr_url, collection, filter_field, end, solr_keytab, solr_principal):
+ logger.info("Deleting data where %s <= %s", filter_field, end)
+ solr_kinit_command = None
+ if solr_keytab:
+ solr_kinit_command = "kinit -kt {0} {1}".format(solr_keytab, solr_principal)
+ curl_prefix = "curl -k --negotiate -u : "
+ else:
+ curl_prefix = "curl -k"
+
+ delete_range = "{0}:[*+TO+\"{1}\"]".format(filter_field, end)
+ delete_query = quote("{0}:[*+TO+\"{1}\"]".format(filter_field, end), safe="/+\"*")
+ delete_command = "{0}/{1}/update?stream.body=<delete><query>{2}</query></delete>&commit=true&wt=json" \
+ .format(solr_url, collection, delete_query)
+
+ query_solr(solr_kinit_command, delete_command, "{0} {1}".format(curl_prefix, delete_command), "Deleting")
+
+def save(solr_url, collection, filter_field, id_field, range_end, read_block_size, write_block_size,
+ ignore_unfinished_uploading, additional_filter, name, solr_keytab, solr_principal, line_delimited,
+ compression, hdfs_keytab, hdfs_principal, hdfs_user, hdfs_path, key_file_path, bucket, key_prefix, local_path):
+ solr_kinit_command = None
+ if solr_keytab:
+ solr_kinit_command = "kinit -kt {0} {1}".format(solr_keytab, solr_principal)
+ curl_prefix = "curl -k --negotiate -u : "
+ else:
+ curl_prefix = "curl -k"
+
+ hdfs_kinit_command = None
+ if hdfs_keytab:
+ hdfs_kinit_command = "sudo -u {0} kinit -kt {1} {2}".format(hdfs_user, hdfs_keytab, hdfs_principal)
+
+ if options.hdfs_path:
+ ensure_hdfs_path(hdfs_kinit_command, hdfs_user, hdfs_path)
+
+ working_dir = get_working_dir(solr_url, collection)
+ handle_unfinished_uploading(solr_kinit_command, hdfs_kinit_command, curl_prefix, working_dir, ignore_unfinished_uploading)
+ save_data(solr_kinit_command, hdfs_kinit_command, curl_prefix, solr_url, collection, filter_field, id_field, range_end,
+ read_block_size, write_block_size, working_dir, additional_filter, name, line_delimited, compression,
+ hdfs_user, hdfs_path, key_file_path, bucket, key_prefix, local_path)
+
+def ensure_hdfs_path(hdfs_kinit_command, hdfs_user, hdfs_path):
+ if hdfs_kinit_command:
+ run_kinit(hdfs_kinit_command, "HDFS")
+
+ try:
+ hdfs_create_dir_command = "sudo -u {0} hadoop fs -mkdir -p {1}".format(hdfs_user, hdfs_path)
+ logger.debug("Ensuring that the HDFS path %s exists:\n%s", hdfs_path, hdfs_create_dir_command)
+ result = call(hdfs_create_dir_command.split())
+ except Exception as e:
+ print
+ logger.warn("Could not execute hdfs ensure dir command:\n%s", hdfs_create_dir_command)
+ logger.warn(str(e))
+ sys.exit()
+
+ if result != 0:
+ print
+ logger.warn("Could not ensure HDFS dir command:\n%s", hdfs_create_dir_command)
+ logger.warn(str(err))
+ sys.exit()
+
+def get_working_dir(solr_url, collection):
+ md5 = hashlib.md5()
+ md5.update(solr_url)
+ md5.update(collection)
+ hash = md5.hexdigest()
+ working_dir = "/tmp/solrDataManager/{0}".format(hash)
+
+ if not(os.path.isdir(working_dir)):
+ os.makedirs(working_dir)
+
+ logger.debug("Working directory is %s", working_dir)
+ return working_dir
+
+def handle_unfinished_uploading(solr_kinit_command, hdfs_kinit_command, curl_prefix, working_dir, ignore_unfinished_uploading):
+ command_json_path = "{0}/command.json".format(working_dir)
+ if os.path.isfile(command_json_path):
+ with open(command_json_path) as command_file:
+ command = json.load(command_file)
+
+ if "upload" in command.keys() and ignore_unfinished_uploading:
+ logger.info("Ignoring unfinished uploading left by previous run")
+ os.remove(command_json_path)
+ return
+
+ if "upload" in command.keys():
+ logger.info("Previous run has left unfinished uploading")
+ logger.info("You may try to run the program with '-g' or '--ignore-unfinished-uploading' to ignore it if it keeps on failing")
+
+ if command["upload"]["type"] == "hdfs":
+ upload_file_hdfs(hdfs_kinit_command, command["upload"]["command"], command["upload"]["upload_file_path"],
+ command["upload"]["hdfs_path"], command["upload"]["hdfs_user"])
+ elif command["upload"]["type"] == "s3":
+ upload_file_s3(command["upload"]["command"], command["upload"]["upload_file_path"], command["upload"]["bucket"],
+ command["upload"]["key_prefix"])
+ elif command["upload"]["type"] == "local":
+ upload_file_local(command["upload"]["command"], command["upload"]["upload_file_path"], command["upload"]["local_path"])
+ else:
+ logger.warn("Unknown upload type: %s", command["upload"]["type"])
+ sys.exit()
+
+ if "delete" in command.keys():
+ delete_data(solr_kinit_command, curl_prefix, command["delete"]["command"], command["delete"]["collection"],
+ command["delete"]["filter_field"], command["delete"]["id_field"], command["delete"]["prev_lot_end_value"],
+ command["delete"]["prev_lot_end_id"])
+
+ os.remove(command_json_path)
+
+def save_data(solr_kinit_command, hdfs_kinit_command, curl_prefix, solr_url, collection, filter_field, id_field,
+ range_end, read_block_size, write_block_size, working_dir, additional_filter, name, line_delimited,
+ compression, hdfs_user, hdfs_path, key_file_path, bucket, key_prefix, local_path):
+ logger.info("Starting to save data")
+
+ tmp_file_path = "{0}/tmp.json".format(working_dir)
+ true = True # needed to be able to eval 'true' in the returned json
+
+ prev_lot_end_value = None
+ prev_lot_end_id = None
+
+ if additional_filter:
+ q = quote("{0}+AND+{1}:[*+TO+\"{2}\"]".format(additional_filter, filter_field, range_end), safe="/+\"*")
+ else:
+ q = quote("{0}:[*+TO+\"{1}\"]".format(filter_field, range_end), safe="/+\"*")
+
+ sort = quote("{0}+asc,{1}+asc".format(filter_field, id_field), safe="/+\"*")
+ solr_query_url_prefix = "{0}/{1}/select?q={2}&sort={3}&rows={4}&wt=json".format(solr_url, collection, q, sort, read_block_size)
+
+ done = False
+ total_records = 0
+ while not done:
+ results = create_block(tmp_file_path, solr_kinit_command, curl_prefix, solr_query_url_prefix, filter_field,
+ id_field, range_end, write_block_size, prev_lot_end_value, prev_lot_end_id,
+ line_delimited)
+ done = results[0]
+ records = results[1]
+ prev_lot_end_value = results[2]
+ prev_lot_end_id = results[3]
+
+ if records > 0:
+ upload_block(solr_kinit_command, hdfs_kinit_command, curl_prefix, solr_url, collection, filter_field, id_field,
+ working_dir, tmp_file_path, name, prev_lot_end_value, prev_lot_end_id, hdfs_user, hdfs_path,
+ key_file_path, bucket, key_prefix, local_path, compression)
+ total_records += records
+ logger.info("A total of %d records are saved", total_records)
+
+def create_block(tmp_file_path, solr_kinit_command, curl_prefix, solr_query_url_prefix, filter_field, id_field, range_end,
+ write_block_size, prev_lot_end_value, prev_lot_end_id, line_delimited):
+ if os.path.exists(tmp_file_path):
+ os.remove(tmp_file_path)
+ tmp_file = open(tmp_file_path, 'w')
+ logger.debug("Created tmp file %s", tmp_file_path)
+
+ init_file(tmp_file, line_delimited)
+ records = 0
+ done = False
+ while records < write_block_size:
+ if prev_lot_end_value:
+ fq_prev_end_rest = "({0}:\"{1}\"+AND+{2}:{{\"{3}\"+TO+*])".format(filter_field, prev_lot_end_value, id_field,
+ prev_lot_end_id)
+ fq_new = "{0}:{{\"{1}\"+TO+\"{2}\"]".format(filter_field, prev_lot_end_value, range_end)
+ fq = "{0}+OR+{1}".format(fq_prev_end_rest, fq_new)
+ else:
+ fq = "{0}:[*+TO+\"{1}\"]".format(filter_field, range_end)
+
+ url = "{0}&fq={1}".format(solr_query_url_prefix, quote(fq, safe="/+\"*"))
+ curl_command = "{0} {1}".format(curl_prefix, url)
+
+ rsp = query_solr(solr_kinit_command, url, curl_command, "Obtaining")
+
+ if rsp['response']['numFound'] == 0:
+ done = True
+ break
+
+ for doc in rsp['response']['docs']:
+ last_doc = doc
+ add_line(tmp_file, doc, line_delimited, records)
+ records += 1
+ if records == write_block_size:
+ break
+
+ prev_lot_end_value = last_doc[filter_field]
+ prev_lot_end_id = last_doc[id_field]
+ sys.stdout.write("\r{0} records are written".format(records))
+ sys.stdout.flush()
+ if verbose and records < write_block_size:
+ print
+ logger.debug("Collecting next lot of data")
+
+ finish_file(tmp_file, line_delimited)
+ sys.stdout.write("\n")
+ logger.debug("Finished data collection")
+ return [done, records, prev_lot_end_value, prev_lot_end_id]
+
+def init_file(tmp_file, line_delimited):
+ if not line_delimited:
+ tmp_file.write("{\n")
+
+def add_line(tmp_file, doc, line_delimited, records):
+ if records > 0:
+ if line_delimited:
+ tmp_file.write("\n")
+ else:
+ tmp_file.write(",\n")
+
+ tmp_file.write(json.dumps(doc))
+
+def finish_file(tmp_file, line_delimited):
+ if not line_delimited:
+ tmp_file.write("\n}")
+
+def upload_block(solr_kinit_command, hdfs_kinit_command, curl_prefix, solr_url, collection, filter_field, id_field,
+ working_dir, tmp_file_path, name, prev_lot_end_value, prev_lot_end_id, hdfs_user, hdfs_path,
+ key_file_path, bucket, key_prefix, local_path, compression):
+ if name:
+ file_name = "{0}_-_{1}_-_{2}_-_{3}".format(collection, name, prev_lot_end_value, prev_lot_end_id).replace(':', '_')
+ else:
+ file_name = "{0}_-_{1}_-_{2}".format(collection, prev_lot_end_value, prev_lot_end_id).replace(':', '_')
+
+ upload_file_path = compress_file(working_dir, tmp_file_path, file_name, compression)
+
+ upload_command = create_command_file(True, working_dir, upload_file_path, solr_url, collection, filter_field, id_field,
+ prev_lot_end_value, prev_lot_end_id, hdfs_user, hdfs_path, key_file_path, bucket,
+ key_prefix, local_path)
+ if hdfs_user:
+ upload_file_hdfs(hdfs_kinit_command, upload_command, upload_file_path, hdfs_path, hdfs_user)
+ elif key_file_path:
+ upload_file_s3(upload_command, upload_file_path, bucket, key_prefix)
+ elif local_path:
+ upload_file_local(upload_command, upload_file_path, local_path)
+ else:
+ logger.warn("Unknown upload destination")
+ sys.exit()
+
+ delete_command = create_command_file(False, working_dir, upload_file_path, solr_url, collection, filter_field, id_field,
+ prev_lot_end_value, prev_lot_end_id, None, None, None, None, None, None)
+ delete_data(solr_kinit_command, curl_prefix, delete_command, collection, filter_field, id_field, prev_lot_end_value, prev_lot_end_id)
+
+ os.remove("{0}/command.json".format(working_dir))
+
+def compress_file(working_dir, tmp_file_path, file_name, compression):
+ if compression == "none":
+ upload_file_path = "{0}/{1}.json".format(working_dir, file_name)
+ os.rename(tmp_file_path, upload_file_path)
+ elif compression == "tar.gz":
+ upload_file_path = "{0}/{1}.tar.gz".format(working_dir, file_name)
+ zipped_file_name = "{0}.json".format(file_name)
+ tar = tarfile.open(upload_file_path, mode="w:gz")
+ try:
+ tar.add(tmp_file_path, arcname=zipped_file_name)
+ finally:
+ tar.close()
+ elif compression == "tar.bz2":
+ upload_file_path = "{0}/{1}.tar.bz2".format(working_dir, file_name)
+ zipped_file_name = "{0}.json".format(file_name)
+ tar = tarfile.open(upload_file_path, mode="w:bz2")
+ try:
+ tar.add(tmp_file_path, arcname=zipped_file_name)
+ finally:
+ tar.close()
+ elif compression == "zip":
+ upload_file_path = "{0}/{1}.zip".format(working_dir, file_name)
+ zipped_file_name = "{0}.json".format(file_name)
+ zip = ZipFile(upload_file_path, 'w')
+ zip.write(tmp_file_path, zipped_file_name, ZIP_DEFLATED)
+ logger.info("Created file %s", zipped_file_name)
+ else:
+ logger.warn("Unknown compression type")
+ sys.exit()
+
+ return upload_file_path
+
+def create_command_file(upload, working_dir, upload_file_path, solr_url, collection, filter_field, id_field, prev_lot_end_value,
+ prev_lot_end_id, hdfs_user, hdfs_path, key_file_path, bucket, key_prefix, local_path):
+ commands = {}
+
+ if upload:
+ logger.debug("Creating command file with upload and delete instructions in case of an interruption")
+ else:
+ logger.debug("Creating command file with delete instructions in case of an interruption")
+
+ if upload:
+ if hdfs_path:
+ upload_command = "sudo -u {0} hadoop fs -put {1} {2}".format(hdfs_user, upload_file_path, hdfs_path)
+ upload_command_data = {}
+ upload_command_data["type"] = "hdfs"
+ upload_command_data["command"] = upload_command
+ upload_command_data["upload_file_path"] = upload_file_path
+ upload_command_data["hdfs_path"] = hdfs_path
+ upload_command_data["hdfs_user"] = hdfs_user
+ commands["upload"] = upload_command_data
+ elif key_file_path:
+ upload_command = "java -cp {0}/libs/* org.apache.ambari.infra.solr.S3Uploader {1} {2} {3} {4}".format( \
+ os.path.dirname(os.path.realpath(__file__)), key_file_path, bucket, key_prefix, upload_file_path)
+ upload_command_data = {}
+ upload_command_data["type"] = "s3"
+ upload_command_data["command"] = upload_command
+ upload_command_data["upload_file_path"] = upload_file_path
+ upload_command_data["bucket"] = bucket
+ upload_command_data["key_prefix"] = key_prefix
+ commands["upload"] = upload_command_data
+ elif local_path:
+ upload_command = "mv {0} {1}".format(upload_file_path, local_path)
+ upload_command_data = {}
+ upload_command_data["type"] = "local"
+ upload_command_data["command"] = upload_command
+ upload_command_data["upload_file_path"] = upload_file_path
+ upload_command_data["local_path"] = local_path
+ commands["upload"] = upload_command_data
+ else:
+ logger.warn("Unknown upload destination")
+ sys.exit()
+
+
+ delete_prev = "{0}:[*+TO+\"{1}\"]".format(filter_field, prev_lot_end_value)
+ delete_last = "({0}:\"{1}\"+AND+{2}:[*+TO+\"{3}\"])".format(filter_field, prev_lot_end_value, id_field, prev_lot_end_id)
+ delete_query = quote("{0}+OR+{1}".format(delete_prev, delete_last), safe="/+\"*")
+ delete_command = "{0}/{1}/update?stream.body=<delete><query>{2}</query></delete>&commit=true&wt=json" \
+ .format(solr_url, collection, delete_query)
+ delete_command_data = {}
+ delete_command_data["command"] = delete_command
+ delete_command_data["collection"] = collection
+ delete_command_data["filter_field"] = filter_field
+ delete_command_data["id_field"] = id_field
+ delete_command_data["prev_lot_end_value"] = prev_lot_end_value
+ delete_command_data["prev_lot_end_id"] = prev_lot_end_id
+ commands["delete"] = delete_command_data
+
+ command_file_path = "{0}/command.json".format(working_dir)
+ command_file_path_tmp = "{0}.tmp".format(command_file_path)
+ cft = open(command_file_path_tmp, 'w')
+ cft.write(json.dumps(commands, indent=4))
+ os.rename(command_file_path_tmp, command_file_path)
+
+ logger.debug("Command file %s was created", command_file_path)
+
+ if upload:
+ return upload_command
+ else:
+ return delete_command
+
+def upload_file_hdfs(hdfs_kinit_command, upload_command, upload_file_path, hdfs_path, hdfs_user):
+ if hdfs_kinit_command:
+ run_kinit(hdfs_kinit_command, "HDFS")
+
+ try:
+ hdfs_file_exists_command = "sudo -u {0} hadoop fs -test -e {1}".format(hdfs_user, hdfs_path + os.path.basename(upload_file_path))
+ logger.debug("Checking if file already exists on hdfs:\n%s", hdfs_file_exists_command)
+ hdfs_file_exists = (0 == call(hdfs_file_exists_command.split()))
+ except Exception as e:
+ print
+ logger.warn("Could not execute command to check if file already exists on HDFS:\n%s", hdfs_file_exists_command)
+ logger.warn(str(e))
+ sys.exit()
+
+ if os.path.isfile(upload_file_path) and not hdfs_file_exists:
+ try:
+ logger.debug("Uploading file to hdfs:\n%s", upload_command)
+ result = call(upload_command.split())
+ except Exception as e:
+ print
+ logger.warn("Could not execute command to upload file to HDFS:\n%s", upload_command)
+ logger.warn(str(e))
+ sys.exit()
+
+ if result != 0:
+ logger.warn("Could not upload file to HDFS with command:\n%s", upload_command)
+ sys.exit()
+
+ logger.info("File %s was uploaded to hdfs %s", os.path.basename(upload_file_path), hdfs_path)
+ os.remove(upload_file_path)
+
+def upload_file_s3(upload_command, upload_file_path, bucket, key_prefix):
+ if os.path.isfile(upload_file_path):
+ try:
+ logger.debug("Uploading file to s3:\n%s", upload_command)
+ result = call(upload_command.split())
+ except Exception as e:
+ print
+ logger.warn("Could not execute command to upload file to S3:\n%s", upload_command)
+ logger.warn(str(e))
+ sys.exit()
+
+ if result != 0:
+ logger.warn("Could not upload file to S3 with command:\n%s", upload_command)
+ sys.exit()
+
+ logger.info("File %s was uploaded to s3 bucket '%s', key '%s'", os.path.basename(upload_file_path), bucket,
+ key_prefix + os.path.basename(upload_file_path))
+ os.remove(upload_file_path)
+
+def upload_file_local(upload_command, upload_file_path, local_path):
+ if os.path.exists(local_path) and not os.path.isdir(local_path):
+ logger.warn("Local path %s exists, but not a directory, can not save there", local_path)
+ if not os.path.isdir(local_path):
+ os.mkdir(local_path)
+ logger.debug("Directory %s was created", local_path)
+
+ try:
+ logger.debug("Moving file to local directory %s with command\n%s", local_path, upload_command)
+ call(upload_command.split())
+ logger.info("File %s was moved to local directory %s", os.path.basename(upload_file_path), local_path)
+ except Exception as e:
+ print
+ logger.warn("Could not execute move command command:\n%s", upload_command)
+ logger.warn(str(e))
+ sys.exit()
+
+def delete_data(solr_kinit_command, curl_prefix, delete_command, collection, filter_field, id_field, prev_lot_end_value,
+ prev_lot_end_id):
+ query_solr(solr_kinit_command, delete_command, "{0} {1}".format(curl_prefix, delete_command), "Deleting")
+ logger.info("Deleted data from collection %s where %s,%s < %s,%s", collection, filter_field, id_field, prev_lot_end_value,
+ prev_lot_end_id)
+
+def query_solr(solr_kinit_command, url, curl_command, action):
+ if solr_kinit_command:
+ run_kinit(solr_kinit_command, "Solr")
+
+ try:
+ logger.debug("%s data from solr:\n%s", action, curl_command)
+ process = Popen(curl_command.split(), stdin=PIPE, stdout=PIPE, stderr=PIPE)
+ except Exception as e:
+ print
+ logger.warn("Could not execute curl command:\n%s", curl_command)
+ logger.warn(str(e))
+ sys.exit()
+
+ out, err = process.communicate()
+ if process.returncode != 0:
+ print
+ logger.warn("Could not execute curl command:\n%s", curl_command)
+ logger.warn(str(err))
+ sys.exit()
+
+ rsp = eval(str(out))
+ if rsp["responseHeader"]["status"] != 0:
+ print
+ logger.warn("Could not execute solr query:\n%s", unquote(url))
+ logger.warn(rsp["error"]["msg"])
+ sys.exit()
+
+ return rsp
+
+def run_kinit(kinit_command, program):
+ try:
+ logger.debug("Running kinit for %s:\n%s", program, kinit_command)
+ result = call(kinit_command.split())
+ except Exception as e:
+ print
+ logger.warn("Could not execute %s kinit command:\n%s", program, kinit_command)
+ logger.warn(str(e))
+ sys.exit()
+
+ if result != 0:
+ print
+ logger.warn("%s kinit command was not successful:\n%s", program, kinit_command)
+ sys.exit()
+
+if __name__ == '__main__':
+ try:
+ start_time = time.time()
+
+ options = parse_arguments()
+ verbose = options.verbose
+ set_log_level()
+
+ end = get_end(options)
+
+ if options.mode == "delete":
+ delete(options.solr_url, options.collection, options.filter_field, end, options.solr_keytab, options.solr_principal)
+ elif options.mode == "save":
+ save(options.solr_url, options.collection, options.filter_field, options.id_field, end, options.read_block_size,
+ options.write_block_size, options.ignore_unfinished_uploading, options.additional_filter, options.name,
+ options.solr_keytab, options.solr_principal, options.line_delimited, options.compression,
+ options.hdfs_keytab, options.hdfs_principal, options.hdfs_user, options.hdfs_path, options.key_file_path,
+ options.bucket, options.key_prefix, options.local_path)
+ else:
+ logger.warn("Unknown mode: %s", options.mode)
+
+ print("--- %s seconds ---" % (time.time() - start_time))
+ except KeyboardInterrupt:
+ print
+ sys.exit(128 + signal.SIGINT)
[20/38] ambari git commit: AMBARI-21942. Upgrade to IOP 4.2.5 from
IOP 4.1 failed with combined Solr host names longer than item_text column
size in table upgrade_item. (swagle)
Posted by lp...@apache.org.
AMBARI-21942. Upgrade to IOP 4.2.5 from IOP 4.1 failed with combined Solr host names longer than item_text column size in table upgrade_item. (swagle)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/7a7d2320
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/7a7d2320
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/7a7d2320
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 7a7d2320a1ebf37e44b487dbf04de2a1c16761cd
Parents: 16cc3a6
Author: Siddharth Wagle <sw...@hortonworks.com>
Authored: Wed Sep 13 10:19:10 2017 -0700
Committer: Siddharth Wagle <sw...@hortonworks.com>
Committed: Wed Sep 13 10:19:10 2017 -0700
----------------------------------------------------------------------
.../apache/ambari/server/orm/DBAccessorImpl.java | 6 ++----
.../server/orm/entities/UpgradeItemEntity.java | 2 +-
.../ambari/server/upgrade/UpgradeCatalog260.java | 19 +++++++++++++++++++
.../main/resources/Ambari-DDL-Derby-CREATE.sql | 2 +-
.../main/resources/Ambari-DDL-MySQL-CREATE.sql | 2 +-
.../main/resources/Ambari-DDL-Oracle-CREATE.sql | 2 +-
.../resources/Ambari-DDL-Postgres-CREATE.sql | 2 +-
.../resources/Ambari-DDL-SQLAnywhere-CREATE.sql | 2 +-
.../resources/Ambari-DDL-SQLServer-CREATE.sql | 2 +-
9 files changed, 28 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
index b137705..26670fc 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/DBAccessorImpl.java
@@ -653,12 +653,10 @@ public class DBAccessorImpl implements DBAccessor {
}
@Override
- public void alterColumn(String tableName, DBColumnInfo columnInfo)
- throws SQLException {
+ public void alterColumn(String tableName, DBColumnInfo columnInfo) throws SQLException {
//varchar extension only (derby limitation, but not too much for others),
if (dbmsHelper.supportsColumnTypeChange()) {
- String statement = dbmsHelper.getAlterColumnStatement(tableName,
- columnInfo);
+ String statement = dbmsHelper.getAlterColumnStatement(tableName, columnInfo);
executeQuery(statement);
} else {
//use addColumn: add_tmp-update-drop-rename for Derby
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeItemEntity.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeItemEntity.java b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeItemEntity.java
index 7f0408f..0c254ef 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeItemEntity.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/orm/entities/UpgradeItemEntity.java
@@ -76,7 +76,7 @@ public class UpgradeItemEntity {
private String tasks = null;
@Basic
- @Column(name = "item_text", length = 1024)
+ @Column(name = "item_text")
private String itemText = null;
@Basic
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
index b17569e..79ff9e2 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
@@ -31,6 +31,7 @@ import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.dao.ArtifactDAO;
@@ -45,6 +46,7 @@ import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
import org.apache.ambari.server.state.kerberos.KerberosIdentityDescriptor;
import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
import org.apache.commons.lang.StringUtils;
+import org.eclipse.persistence.internal.databaseaccess.FieldTypeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -107,6 +109,7 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
public static final String FK_UPGRADE_FROM_REPO_ID = "FK_upgrade_from_repo_id";
public static final String FK_UPGRADE_TO_REPO_ID = "FK_upgrade_to_repo_id";
public static final String FK_UPGRADE_REPO_VERSION_ID = "FK_upgrade_repo_version_id";
+ public static final String UPGRADE_ITEM_ITEM_TEXT = "item_text";
public static final String SERVICE_COMPONENT_HISTORY_TABLE = "servicecomponent_history";
public static final String UPGRADE_HISTORY_TABLE = "upgrade_history";
@@ -181,6 +184,22 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
createUpgradeHistoryTable();
updateRepositoryVersionTable();
renameServiceDeletedColumn();
+ expandUpgradeItemItemTextColumn();
+ }
+
+ /**
+ * Expand item_text column of upgrade_item
+ */
+ private void expandUpgradeItemItemTextColumn() throws SQLException {
+ Configuration.DatabaseType databaseType = configuration.getDatabaseType();
+
+ if (Configuration.DatabaseType.MYSQL == databaseType) {
+ dbAccessor.alterColumn(UPGRADE_ITEM_TABLE, new DBAccessor.DBColumnInfo(
+ UPGRADE_ITEM_ITEM_TEXT, new FieldTypeDefinition("TEXT"), null));
+ } else {
+ dbAccessor.changeColumnType(UPGRADE_ITEM_TABLE, UPGRADE_ITEM_ITEM_TEXT,
+ String.class, char[].class);
+ }
}
private void renameServiceDeletedColumn() throws AmbariException, SQLException {
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/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 e7359a7..74fff6c 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Derby-CREATE.sql
@@ -843,7 +843,7 @@ CREATE TABLE upgrade_item (
state VARCHAR(255) DEFAULT 'NONE' NOT NULL,
hosts VARCHAR(3000),
tasks VARCHAR(3000),
- item_text VARCHAR(1024),
+ item_text VARCHAR(3000),
CONSTRAINT PK_upgrade_item PRIMARY KEY (upgrade_item_id),
FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/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 c1e1953..beda848 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-MySQL-CREATE.sql
@@ -860,7 +860,7 @@ CREATE TABLE upgrade_item (
state VARCHAR(255) DEFAULT 'NONE' NOT NULL,
hosts TEXT,
tasks TEXT,
- item_text VARCHAR(1024),
+ item_text TEXT,
CONSTRAINT PK_upgrade_item PRIMARY KEY (upgrade_item_id),
FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/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 c0b2f0c..4f27dfb 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Oracle-CREATE.sql
@@ -839,7 +839,7 @@ CREATE TABLE upgrade_item (
state VARCHAR2(255) DEFAULT 'NONE' NOT NULL,
hosts CLOB,
tasks CLOB,
- item_text VARCHAR2(1024),
+ item_text CLOB,
CONSTRAINT PK_upgrade_item PRIMARY KEY (upgrade_item_id),
FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/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 90cdbfe..355ee80 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-Postgres-CREATE.sql
@@ -841,7 +841,7 @@ CREATE TABLE upgrade_item (
state VARCHAR(255) DEFAULT 'NONE' NOT NULL,
hosts TEXT,
tasks TEXT,
- item_text VARCHAR(1024),
+ item_text TEXT,
CONSTRAINT PK_upgrade_item PRIMARY KEY (upgrade_item_id),
FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/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 7f39535..76d4441 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLAnywhere-CREATE.sql
@@ -837,7 +837,7 @@ CREATE TABLE upgrade_item (
state VARCHAR(255) DEFAULT 'NONE' NOT NULL,
hosts TEXT,
tasks TEXT,
- item_text VARCHAR(1024),
+ item_text TEXT,
CONSTRAINT PK_upgrade_item PRIMARY KEY (upgrade_item_id),
FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
);
http://git-wip-us.apache.org/repos/asf/ambari/blob/7a7d2320/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 aa06c4d..f54a232 100644
--- a/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
+++ b/ambari-server/src/main/resources/Ambari-DDL-SQLServer-CREATE.sql
@@ -858,7 +858,7 @@ CREATE TABLE upgrade_item (
state VARCHAR(255) DEFAULT 'NONE' NOT NULL,
hosts TEXT,
tasks TEXT,
- item_text VARCHAR(1024),
+ item_text TEXT,
CONSTRAINT PK_upgrade_item PRIMARY KEY CLUSTERED (upgrade_item_id),
FOREIGN KEY (upgrade_group_id) REFERENCES upgrade_group(upgrade_group_id)
);
[24/38] 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/db8874b6
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/db8874b6
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/db8874b6
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: db8874b6953e49b13baf3f1dd30d29c2a29949f9
Parents: 885761f
Author: Balázs Bence Sári <bs...@hortonworks.com>
Authored: Thu Jul 6 18:36:18 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:29 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/db8874b6/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/db8874b6/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/db8874b6/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),
[09/38] ambari git commit: AMBARI-21929. UI task for Host Recovery.
(Ishan via Jaimin)
Posted by lp...@apache.org.
AMBARI-21929. UI task for Host Recovery. (Ishan via Jaimin)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/bb4645f7
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/bb4645f7
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/bb4645f7
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: bb4645f7c0e8242a397b192cabd326bef0d99700
Parents: 9316ea8
Author: Jaimin Jetly <ja...@hortonworks.com>
Authored: Tue Sep 12 11:13:39 2017 -0700
Committer: Jaimin Jetly <ja...@hortonworks.com>
Committed: Tue Sep 12 11:13:39 2017 -0700
----------------------------------------------------------------------
ambari-web/app/controllers/main/host/details.js | 143 +++++++++++++++++++
ambari-web/app/messages.js | 8 ++
ambari-web/app/templates/main/host/details.hbs | 3 +
.../main/host/details/recoverHostErrorPopup.hbs | 23 +++
.../main/host/details/recoverHostPopup.hbs | 22 +++
5 files changed, 199 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/bb4645f7/ambari-web/app/controllers/main/host/details.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/host/details.js b/ambari-web/app/controllers/main/host/details.js
index cf223d7..ad2ac98 100644
--- a/ambari-web/app/controllers/main/host/details.js
+++ b/ambari-web/app/controllers/main/host/details.js
@@ -3101,5 +3101,148 @@ App.MainHostDetailsController = Em.Controller.extend(App.SupportClientConfigsDow
} else {
this.set('isConfigsLoadingInProgress', false);
}
+ },
+
+ recoverHost: function() {
+ var components = this.get('content.hostComponents');
+ var hostName = this.get('content.publicHostName');
+ var self = this;
+ var batches = [
+ {
+ "order_id": 1,
+ "type": "PUT",
+ "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/hosts/" + hostName + "/host_components",
+ "RequestBodyInfo": {
+ "RequestInfo": {
+ context: Em.I18n.t('hosts.host.recover.initAllComponents.context'),
+ operation_level: {
+ level: "HOST",
+ cluster_name: App.get('clusterName'),
+ host_name: hostName
+ },
+ query: "HostRoles/component_name.in(" + components.mapProperty('componentName').join(',') + ")"
+ },
+ "Body": {
+ HostRoles: {
+ state: "INIT"
+ }
+ }
+ }
+ }];
+ batches.push(
+ {
+ "order_id": 2,
+ "type": "PUT",
+ "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName') + "/hosts/" + hostName + "/host_components",
+ "RequestBodyInfo": {
+ "RequestInfo": {
+ context: Em.I18n.t('hosts.host.recover.installAllComponents.context'),
+ operation_level: {
+ level: "HOST",
+ cluster_name: App.get('clusterName'),
+ host_name: hostName
+ },
+ query: "HostRoles/component_name.in(" + components.mapProperty('componentName').join(',') + ")"
+ },
+ "Body": {
+ HostRoles: {
+ state: "INSTALLED"
+ }
+ }
+ }
+ });
+
+ if(App.get('isKerberosEnabled')) {
+ batches.push({
+ "order_id": 3,
+ "type": "PUT",
+ "uri": App.get('apiPrefix') + "/clusters/" + App.get('clusterName'),
+ "RequestBodyInfo": {
+ "RequestInfo": {
+ context: Em.I18n.t('hosts.host.recover.regenerateKeytabs.context'),
+ query: "regenerate_keytabs=all®enerate_hosts=" + hostName + "&ignore_config_updates=true",
+ },
+ "Body": {
+ Clusters: {
+ security_type: "KERBEROS"
+ }
+ }
+ }
+ });
+ }
+ App.get('router.mainAdminKerberosController').getSecurityType(function () {
+ App.get('router.mainAdminKerberosController').getKDCSessionState(function () {
+ self._doRecoverHost(batches);
+ });
+ });
+ },
+
+ _doRecoverHost: function (batches) {
+ App.ajax.send ({
+ name: 'common.batch.request_schedules',
+ sender: this,
+ data: {
+ intervalTimeSeconds: 1,
+ tolerateSize: 0,
+ batches: batches
+ },
+ success:'recoverHostSuccessCallback',
+ showLoadingPopup: true
+ });
+ },
+
+ recoverHostSuccessCallback: function (data) {
+ if (data && (data.Requests || data.resources[0].RequestSchedule)) {
+ this.showBackgroundOperationsPopup();
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ recoverHostDisabled: function() {
+
+ var isDisabled = false;
+ var allowedStates = [App.HostComponentStatus.stopped, App.HostComponentStatus.install_failed, App.HostComponentStatus.init];
+ this.get('content.hostComponents').forEach(function (component) {
+ isDisabled = isDisabled ? true : !allowedStates.contains(component.get('workStatus'));
+ });
+ return isDisabled;
+ }.property('content.hostComponents.@each.workStatus'),
+
+ confirmRecoverHost: function() {
+ var self = this;
+ var componentsNotStopped = [];
+ var allowedStates = [App.HostComponentStatus.stopped, App.HostComponentStatus.install_failed, App.HostComponentStatus.init];
+ this.get('content.hostComponents').forEach(function (component) {
+ if(!allowedStates.contains(component.get('workStatus'))) {
+ componentsNotStopped.push(component.get('componentName'));
+ }
+ });
+ if(componentsNotStopped.length) {
+ App.ModalPopup.show({
+ header: Em.I18n.t('hosts.recover.error.popup.title'),
+ recoverErrorPopupBody: Em.I18n.t('hosts.recover.error.popup.body').format(componentsNotStopped.toString()),
+ componentsStr: componentsNotStopped.toString(),
+ bodyClass: Em.View.extend({
+ templateName: require('templates/main/host/details/recoverHostErrorPopup')
+ }),
+ secondary: false
+ });
+ } else {
+ App.ModalPopup.show({
+ header: Em.I18n.t('hosts.recover.popup.title'),
+ bodyClass: Em.View.extend({
+ templateName: require('templates/main/host/details/recoverHostPopup')
+ }),
+ primary: Em.I18n.t('yes'),
+ secondary: Em.I18n.t('no'),
+ onPrimary: function () {
+ self.recoverHost();
+ this.hide();
+ }
+ });
+ }
}
+
});
http://git-wip-us.apache.org/repos/asf/ambari/blob/bb4645f7/ambari-web/app/messages.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/messages.js b/ambari-web/app/messages.js
index bda8228..869608a 100644
--- a/ambari-web/app/messages.js
+++ b/ambari-web/app/messages.js
@@ -2697,6 +2697,7 @@ Em.I18n.translations = {
'hosts.host.details.refreshConfigs':'Refresh configs',
'hosts.host.details.for.postfix':'{0} for host',
'hosts.host.details.setRackId':'Set Rack',
+ 'hosts.host.details.recoverHost': 'Recover Host',
'host.host.details.installClients': 'Install clients',
'host.host.details.reinstallClients': 'Reinstall clients',
'host.host.details.checkHost': 'Check host',
@@ -2762,6 +2763,9 @@ Em.I18n.translations = {
'hosts.host.maintainance.stopAllComponents.context': 'Stop All Host Components',
'hosts.host.maintainance.startAllComponents.context': 'Start All Host Components',
'hosts.host.maintainance.reinstallFailedComponents.context': 'Reinstall Failed Components',
+ 'hosts.host.recover.initAllComponents.context': 'Init All Host Components',
+ 'hosts.host.recover.installAllComponents.context': 'Install All Host Components',
+ 'hosts.host.recover.regenerateKeytabs.context': 'Regenerate keytabs',
'hosts.host.alerts.st':' ! ',
'hosts.decommission.popup.body':'Are you sure?',
'hosts.decommission.popup.header':'Confirmation',
@@ -2777,6 +2781,10 @@ Em.I18n.translations = {
'hosts.delete.popup.header':'Confirmation',
'hosts.delete.popup.title':'Delete Host',
'hosts.delete.popup.unknownComponents':'The following components have unknown status:',
+ 'hosts.recover.popup.title': 'Confirmation',
+ 'hosts.recover.popup.body': 'This action will completely re-install all components on this host, and should only be used when restoring a host using replacement hardware. <strong>Are you sure you want to continue?<strong>',
+ 'hosts.recover.error.popup.title': 'Cannot Recover Host',
+ 'hosts.recover.error.popup.body': 'Host cannot be recovered unless every host component is not in Stopped, Install Failed or Init state',
'hosts.cant.do.popup.title':'Unable to Delete Host',
'hosts.cant.do.popup.masterList.body':'This host cannot be deleted since it has the following master components:',
'hosts.cant.do.popup.masterList.body.end':'To delete this host, you must first move all the master components listed above.',
http://git-wip-us.apache.org/repos/asf/ambari/blob/bb4645f7/ambari-web/app/templates/main/host/details.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/details.hbs b/ambari-web/app/templates/main/host/details.hbs
index bd75f5c..15b0f4a 100644
--- a/ambari-web/app/templates/main/host/details.hbs
+++ b/ambari-web/app/templates/main/host/details.hbs
@@ -65,6 +65,9 @@
</div>
</li>
{{/if}}
+ <li>
+ <a {{action "confirmRecoverHost" target="controller"}}><i class="icon-time"></i> {{t hosts.host.details.recoverHost}} </a>
+ </li>
</ul>
</div>
</div>
http://git-wip-us.apache.org/repos/asf/ambari/blob/bb4645f7/ambari-web/app/templates/main/host/details/recoverHostErrorPopup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/details/recoverHostErrorPopup.hbs b/ambari-web/app/templates/main/host/details/recoverHostErrorPopup.hbs
new file mode 100644
index 0000000..1152801
--- /dev/null
+++ b/ambari-web/app/templates/main/host/details/recoverHostErrorPopup.hbs
@@ -0,0 +1,23 @@
+{{!
+* 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.
+}}
+
+<div class="dialog-delete-component">
+ <div class="warning">
+ <i class="icon-warning-sign"></i> {{recoverErrorPopupBody}}
+ </div>
+</div>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/bb4645f7/ambari-web/app/templates/main/host/details/recoverHostPopup.hbs
----------------------------------------------------------------------
diff --git a/ambari-web/app/templates/main/host/details/recoverHostPopup.hbs b/ambari-web/app/templates/main/host/details/recoverHostPopup.hbs
new file mode 100644
index 0000000..2534bc6
--- /dev/null
+++ b/ambari-web/app/templates/main/host/details/recoverHostPopup.hbs
@@ -0,0 +1,22 @@
+{{!
+* 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.
+}}
+
+
+<div class="alert">
+ {{t hosts.recover.popup.body}}
+</div>
[22/38] ambari git commit: AMBARI-21943. LLAP: Daemon is hung when
task is killed in the middle of orc tail reads
(org.apache.hadoop.hdfs.shortcircuit.DfsClientShmManager.allocSlot).
Posted by lp...@apache.org.
AMBARI-21943. LLAP: Daemon is hung when task is killed in the middle of orc tail reads (org.apache.hadoop.hdfs.shortcircuit.DfsClientShmManager.allocSlot).
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/df3a66d9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/df3a66d9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/df3a66d9
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: df3a66d9767646f6a38b3c64a587a4ab647bf868
Parents: 6c40fdf
Author: Swapan Shridhar <ss...@hortonworks.com>
Authored: Tue Sep 12 16:52:11 2017 -0700
Committer: Swapan Shridhar <ss...@hortonworks.com>
Committed: Wed Sep 13 15:52:49 2017 -0700
----------------------------------------------------------------------
.../stacks/HDP/2.5/upgrades/config-upgrade.xml | 6 ++++++
.../HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml | 5 +++++
.../resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml | 1 +
.../HIVE/configuration/hive-interactive-site.xml | 14 ++++++++++++++
4 files changed, 26 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/df3a66d9/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/config-upgrade.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/config-upgrade.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/config-upgrade.xml
index 13173d2..f5fa744 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/config-upgrade.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/config-upgrade.xml
@@ -532,6 +532,12 @@
<set key="tez.runtime.shuffle.parallel.copies" value="8"/>
</definition>
+ <definition xsi:type="configure" id="hdp_2_6_maint_llap_config" summary="Updating LLAP configuration">
+ <type>hive-interactive-site</type>
+ <set key="dfs.short.circuit.shared.memory.watcher.interrupt.check.ms" value="0" />
+ <set key="dfs.client.mmap.enabled" value="false" />
+ </definition>
+
</changes>
</component>
http://git-wip-us.apache.org/repos/asf/ambari/blob/df3a66d9/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
index 90a7d97..c509f34 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/nonrolling-upgrade-2.6.xml
@@ -635,6 +635,11 @@
<summary>Updating hive atlas application properties</summary>
</task>
</execute-stage>
+
+ <execute-stage service="HIVE" component="HIVE_SERVER_INTERACTIVE" title="Updating DFS related LLAP configurations">
+ <task xsi:type="configure" id="hdp_2_6_maint_llap_config"/>
+ </execute-stage>
+
<!-- SPARK -->
<execute-stage service="SPARK" component="LIVY_SERVER" title="Apply config changes for Livy Server">
<task xsi:type="configure" id="hdp_2_5_0_0_rename_spark_livy_configs"/>
http://git-wip-us.apache.org/repos/asf/ambari/blob/df3a66d9/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
index 5ee82c3..5f1bf12 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.5/upgrades/upgrade-2.6.xml
@@ -860,6 +860,7 @@
<task xsi:type="configure" id="llap_update_shuffle_parallel_copies"/>
<task xsi:type="configure" id="llap_update_settings"/>
<task xsi:type="configure" id="llap_update_tez_settings"/>
+ <task xsi:type="configure" id="hdp_2_6_maint_llap_config"/>
</pre-upgrade>
<pre-downgrade />
http://git-wip-us.apache.org/repos/asf/ambari/blob/df3a66d9/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
index cb4f947..aae2efa 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.6/services/HIVE/configuration/hive-interactive-site.xml
@@ -110,4 +110,18 @@ limitations under the License.
<on-ambari-upgrade add="false"/>
</property>
+ <property>
+ <name>dfs.client.mmap.enabled</name>
+ <value>false</value>
+ <description>Disable HDFS caching fo LLAP</description>
+ <on-ambari-upgrade add="false"/>
+ </property>
+
+ <property>
+ <name>dfs.short.circuit.shared.memory.watcher.interrupt.check.ms</name>
+ <value>0</value>
+ <description>Disable HDFS caching fo LLAP</description>
+ <on-ambari-upgrade add="false"/>
+ </property>
+
</configuration>
[11/38] ambari git commit: AMBARI-21939 : Ambari HDFS Heatmaps are
not showing data (Not Applicable) for bytes read,
bytes written & DataNode Process Network I/O Utilization. (avijayan)
Posted by lp...@apache.org.
AMBARI-21939 : Ambari HDFS Heatmaps are not showing data (Not Applicable) for bytes read, bytes written & DataNode Process Network I/O Utilization. (avijayan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a49121b9
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a49121b9
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a49121b9
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: a49121b9af276f45ef26e0b320de48d6ef6e7563
Parents: 7fa7a6c
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Tue Sep 12 17:07:14 2017 -0700
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Tue Sep 12 17:07:14 2017 -0700
----------------------------------------------------------------------
.../server/upgrade/UpgradeCatalog260.java | 16 ++++
.../PERF/1.0/services/FAKEHDFS/widgets.json | 48 +++++------
.../server/upgrade/UpgradeCatalog260Test.java | 87 ++++++++++++++++++++
3 files changed, 127 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a49121b9/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
index 2de85fc..b17569e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/upgrade/UpgradeCatalog260.java
@@ -21,6 +21,7 @@ import static org.apache.ambari.server.view.ViewContextImpl.CORE_SITE;
import java.sql.SQLException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
@@ -401,6 +402,7 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
ensureZeppelinProxyUserConfigs();
updateKerberosDescriptorArtifacts();
updateAmsConfigs();
+ updateHDFSWidgetDefinition();
}
public int getCurrentVersionID() throws AmbariException, SQLException {
@@ -565,4 +567,18 @@ public class UpgradeCatalog260 extends AbstractUpgradeCatalog {
}
}
}
+
+ protected void updateHDFSWidgetDefinition() throws AmbariException {
+ LOG.info("Updating HDFS widget definition.");
+
+ Map<String, List<String>> widgetMap = new HashMap<>();
+ Map<String, String> sectionLayoutMap = new HashMap<>();
+
+ List<String> hdfsHeatmapWidgets = new ArrayList<>(Arrays.asList("HDFS Bytes Read", "HDFS Bytes Written",
+ "DataNode Process Disk I/O Utilization", "DataNode Process Network I/O Utilization"));
+ widgetMap.put("HDFS_HEATMAPS", hdfsHeatmapWidgets);
+ sectionLayoutMap.put("HDFS_HEATMAPS", "default_hdfs_heatmap");
+
+ updateWidgetDefinitionsForService("HDFS", widgetMap, sectionLayoutMap);
+ }
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a49121b9/ambari-server/src/main/resources/stacks/PERF/1.0/services/FAKEHDFS/widgets.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/PERF/1.0/services/FAKEHDFS/widgets.json b/ambari-server/src/main/resources/stacks/PERF/1.0/services/FAKEHDFS/widgets.json
index 7a793f8..205a364 100644
--- a/ambari-server/src/main/resources/stacks/PERF/1.0/services/FAKEHDFS/widgets.json
+++ b/ambari-server/src/main/resources/stacks/PERF/1.0/services/FAKEHDFS/widgets.json
@@ -416,8 +416,8 @@
"is_visible": true,
"metrics": [
{
- "name": "dfs.datanode.BytesRead._rate",
- "metric_path": "metrics/dfs/datanode/bytes_read._rate",
+ "name": "dfs.datanode.BytesRead",
+ "metric_path": "metrics/dfs/datanode/bytes_read",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
}
@@ -425,7 +425,7 @@
"values": [
{
"name": "FAKEHDFS Bytes Read",
- "value": "${dfs.datanode.BytesRead._rate}"
+ "value": "${dfs.datanode.BytesRead}"
}
],
"properties": {
@@ -440,8 +440,8 @@
"is_visible": false,
"metrics": [
{
- "name": "dfs.datanode.BytesWritten._rate",
- "metric_path": "metrics/dfs/datanode/bytes_written._rate",
+ "name": "dfs.datanode.BytesWritten",
+ "metric_path": "metrics/dfs/datanode/bytes_written",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
}
@@ -449,7 +449,7 @@
"values": [
{
"name": "FAKEHDFS Bytes Written",
- "value": "${dfs.datanode.BytesWritten._rate}"
+ "value": "${dfs.datanode.BytesWritten}"
}
],
"properties": {
@@ -537,26 +537,26 @@
"is_visible": false,
"metrics": [
{
- "name": "dfs.datanode.BytesRead._rate",
- "metric_path": "metrics/dfs/datanode/bytes_read._rate",
+ "name": "dfs.datanode.BytesRead",
+ "metric_path": "metrics/dfs/datanode/bytes_read",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
},
{
- "name": "dfs.datanode.BytesWritten._rate",
- "metric_path": "metrics/dfs/datanode/bytes_written._rate",
+ "name": "dfs.datanode.BytesWritten",
+ "metric_path": "metrics/dfs/datanode/bytes_written",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
},
{
- "name": "dfs.datanode.TotalReadTime._rate",
- "metric_path": "metrics/dfs/datanode/TotalReadTime._rate",
+ "name": "dfs.datanode.TotalReadTime",
+ "metric_path": "metrics/dfs/datanode/TotalReadTime",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
},
{
- "name": "dfs.datanode.TotalWriteTime._rate",
- "metric_path": "metrics/dfs/datanode/TotalWriteTime._rate",
+ "name": "dfs.datanode.TotalWriteTime",
+ "metric_path": "metrics/dfs/datanode/TotalWriteTime",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
}
@@ -564,7 +564,7 @@
"values": [
{
"name": "FAKEDataNode Process Disk I/O Utilization",
- "value": "${((dfs.datanode.BytesRead._rate/dfs.datanode.TotalReadTime._rate)+(dfs.datanode.BytesWritten._rate/dfs.datanode.TotalWriteTime._rate))*50}"
+ "value": "${((dfs.datanode.BytesRead/dfs.datanode.TotalReadTime)+(dfs.datanode.BytesWritten/dfs.datanode.TotalWriteTime))*50}"
}
],
"properties": {
@@ -579,26 +579,26 @@
"is_visible": false,
"metrics": [
{
- "name": "dfs.datanode.RemoteBytesRead._rate",
- "metric_path": "metrics/dfs/datanode/RemoteBytesRead._rate",
+ "name": "dfs.datanode.RemoteBytesRead",
+ "metric_path": "metrics/dfs/datanode/RemoteBytesRead",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
},
{
- "name": "dfs.datanode.ReadsFromRemoteClient._rate",
- "metric_path": "metrics/dfs/datanode/reads_from_remote_client._rate",
+ "name": "dfs.datanode.ReadsFromRemoteClient",
+ "metric_path": "metrics/dfs/datanode/reads_from_remote_client",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
},
{
- "name": "dfs.datanode.RemoteBytesWritten._rate",
- "metric_path": "metrics/dfs/datanode/RemoteBytesWritten._rate",
+ "name": "dfs.datanode.RemoteBytesWritten",
+ "metric_path": "metrics/dfs/datanode/RemoteBytesWritten",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
},
{
- "name": "dfs.datanode.WritesFromRemoteClient._rate",
- "metric_path": "metrics/dfs/datanode/writes_from_remote_client._rate",
+ "name": "dfs.datanode.WritesFromRemoteClient",
+ "metric_path": "metrics/dfs/datanode/writes_from_remote_client",
"service_name": "FAKEHDFS",
"component_name": "FAKEDATANODE"
}
@@ -606,7 +606,7 @@
"values": [
{
"name": "FAKEDataNode Process Network I/O Utilization",
- "value": "${((dfs.datanode.RemoteBytesRead._rate/dfs.datanode.ReadsFromRemoteClient._rate)+(dfs.datanode.RemoteBytesWritten._rate/dfs.datanode.WritesFromRemoteClient._rate))*50}"
+ "value": "${((dfs.datanode.RemoteBytesRead/dfs.datanode.ReadsFromRemoteClient)+(dfs.datanode.RemoteBytesWritten/dfs.datanode.WritesFromRemoteClient))*50}"
}
],
"properties": {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a49121b9/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
index b70f37b..d9c7957 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
@@ -50,8 +50,10 @@ import java.util.Set;
import javax.persistence.EntityManager;
import com.google.common.collect.Maps;
+import com.google.inject.AbstractModule;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.configuration.Configuration;
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.AmbariManagementControllerImpl;
@@ -60,17 +62,23 @@ import org.apache.ambari.server.controller.MaintenanceStateHelper;
import org.apache.ambari.server.orm.DBAccessor;
import org.apache.ambari.server.orm.DBAccessor.DBColumnInfo;
import org.apache.ambari.server.orm.dao.ArtifactDAO;
+import org.apache.ambari.server.orm.dao.WidgetDAO;
import org.apache.ambari.server.orm.entities.ArtifactEntity;
+import org.apache.ambari.server.orm.entities.WidgetEntity;
+import org.apache.ambari.server.stack.StackManagerFactory;
import org.apache.ambari.server.state.Cluster;
import org.apache.ambari.server.state.Clusters;
import org.apache.ambari.server.state.Config;
import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceInfo;
import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
import org.apache.ambari.server.state.kerberos.KerberosComponentDescriptor;
import org.apache.ambari.server.state.kerberos.KerberosDescriptor;
import org.apache.ambari.server.state.kerberos.KerberosDescriptorFactory;
import org.apache.ambari.server.state.kerberos.KerberosServiceDescriptor;
import org.apache.ambari.server.state.stack.OsFamily;
+import org.apache.commons.io.FileUtils;
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.EasyMockRunner;
@@ -80,7 +88,9 @@ import org.easymock.MockType;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import com.google.gson.Gson;
@@ -142,6 +152,9 @@ public class UpgradeCatalog260Test {
@Mock(type = MockType.NICE)
private Injector injector;
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
@Before
public void init() {
reset(entityManagerProvider, injector);
@@ -737,4 +750,78 @@ public class UpgradeCatalog260Test {
assertTrue(Maps.difference(newProperties, updatedProperties).areEqual());
}
+ @Test
+ public void testHDFSWidgetUpdate() throws Exception {
+ final Clusters clusters = createNiceMock(Clusters.class);
+ final Cluster cluster = createNiceMock(Cluster.class);
+ final AmbariManagementController controller = createNiceMock(AmbariManagementController.class);
+ final Gson gson = new Gson();
+ final WidgetDAO widgetDAO = createNiceMock(WidgetDAO.class);
+ final AmbariMetaInfo metaInfo = createNiceMock(AmbariMetaInfo.class);
+ WidgetEntity widgetEntity = createNiceMock(WidgetEntity.class);
+ StackId stackId = new StackId("HDP", "2.0.0");
+ StackInfo stackInfo = createNiceMock(StackInfo.class);
+ ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
+ Service service = createNiceMock(Service.class);
+
+ String widgetStr = "{\n" +
+ " \"layouts\": [\n" +
+ " {\n" +
+ " \"layout_name\": \"default_hdfs_heatmap\",\n" +
+ " \"display_name\": \"Standard HDFS HeatMaps\",\n" +
+ " \"section_name\": \"HDFS_HEATMAPS\",\n" +
+ " \"widgetLayoutInfo\": [\n" +
+ " {\n" +
+ " \"widget_name\": \"HDFS Bytes Read\",\n" +
+ " \"metrics\": [],\n" +
+ " \"values\": []\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+
+ File dataDirectory = temporaryFolder.newFolder();
+ File file = new File(dataDirectory, "hdfs_widget.json");
+ FileUtils.writeStringToFile(file, widgetStr);
+
+ final Injector mockInjector = Guice.createInjector(new AbstractModule() {
+ @Override
+ protected void configure() {
+ bind(EntityManager.class).toInstance(createNiceMock(EntityManager.class));
+ bind(AmbariManagementController.class).toInstance(controller);
+ bind(Clusters.class).toInstance(clusters);
+ bind(DBAccessor.class).toInstance(createNiceMock(DBAccessor.class));
+ bind(OsFamily.class).toInstance(createNiceMock(OsFamily.class));
+ bind(Gson.class).toInstance(gson);
+ bind(WidgetDAO.class).toInstance(widgetDAO);
+ bind(StackManagerFactory.class).toInstance(createNiceMock(StackManagerFactory.class));
+ bind(AmbariMetaInfo.class).toInstance(metaInfo);
+ }
+ });
+ expect(controller.getClusters()).andReturn(clusters).anyTimes();
+ expect(clusters.getClusters()).andReturn(new HashMap<String, Cluster>() {{
+ put("normal", cluster);
+ }}).anyTimes();
+ expect(cluster.getServices()).andReturn(Collections.singletonMap("HDFS", service)).anyTimes();
+ expect(cluster.getClusterId()).andReturn(1L).anyTimes();
+ expect(service.getDesiredStackId()).andReturn(stackId).anyTimes();
+ expect(stackInfo.getService("HDFS")).andReturn(serviceInfo);
+ expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
+ expect(metaInfo.getStack("HDP", "2.0.0")).andReturn(stackInfo).anyTimes();
+ expect(serviceInfo.getWidgetsDescriptorFile()).andReturn(file).anyTimes();
+
+ expect(widgetDAO.findByName(1L, "HDFS Bytes Read", "ambari", "HDFS_HEATMAPS"))
+ .andReturn(Collections.singletonList(widgetEntity));
+ expect(widgetDAO.merge(widgetEntity)).andReturn(null);
+ expect(widgetEntity.getWidgetName()).andReturn("HDFS Bytes Read").anyTimes();
+
+ replay(clusters, cluster, controller, widgetDAO, metaInfo, widgetEntity, stackInfo, serviceInfo, service);
+
+ mockInjector.getInstance(UpgradeCatalog260.class).updateHDFSWidgetDefinition();
+
+ verify(clusters, cluster, controller, widgetDAO, widgetEntity, stackInfo, serviceInfo);
+ }
+
+
}
[26/38] 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/642b5780
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/642b5780
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/642b5780
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 642b5780e0d99f696ce6ab1028fbb3c0125f3429
Parents: db8874b
Author: lpuskas <lp...@apache.org>
Authored: Thu Jul 13 16:20:58 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:29 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/642b5780/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/642b5780/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 e151e63..edabcdb 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/642b5780/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/642b5780/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/642b5780/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/642b5780/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/642b5780/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/642b5780/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
[21/38] ambari git commit: AMBARI-21952 : Refine AMS heap
recommendations in stack advisor. (avijayan)
Posted by lp...@apache.org.
AMBARI-21952 : Refine AMS heap recommendations in stack advisor. (avijayan)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/6c40fdf4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/6c40fdf4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/6c40fdf4
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 6c40fdf48e21db493d3449ba59e652f90e264ec3
Parents: 7a7d232
Author: Aravindan Vijayan <av...@hortonworks.com>
Authored: Wed Sep 13 15:14:12 2017 -0700
Committer: Aravindan Vijayan <av...@hortonworks.com>
Committed: Wed Sep 13 15:14:12 2017 -0700
----------------------------------------------------------------------
.../stacks/HDP/2.0.6/services/stack_advisor.py | 81 +++----
.../stacks/2.0.6/common/test_stack_advisor.py | 4 +-
.../stacks/2.2/common/test_stack_advisor.py | 232 +++++++++++++++++--
3 files changed, 257 insertions(+), 60 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/6c40fdf4/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
index 70cb7a2..0249ea2 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/services/stack_advisor.py
@@ -517,18 +517,22 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
schMemoryMap = {
"HDFS": {
"NAMENODE": HEAP_PER_MASTER_COMPONENT,
+ "SECONDARY_NAMENODE": HEAP_PER_MASTER_COMPONENT,
"DATANODE": HEAP_PER_SLAVE_COMPONENT
},
"YARN": {
"RESOURCEMANAGER": HEAP_PER_MASTER_COMPONENT,
+ "NODEMANAGER": HEAP_PER_SLAVE_COMPONENT,
+ "HISTORYSERVER" : HEAP_PER_MASTER_COMPONENT,
+ "APP_TIMELINE_SERVER": HEAP_PER_MASTER_COMPONENT
},
"HBASE": {
"HBASE_MASTER": HEAP_PER_MASTER_COMPONENT,
"HBASE_REGIONSERVER": HEAP_PER_SLAVE_COMPONENT
},
- "ACCUMULO": {
- "ACCUMULO_MASTER": HEAP_PER_MASTER_COMPONENT,
- "ACCUMULO_TSERVER": HEAP_PER_SLAVE_COMPONENT
+ "HIVE": {
+ "HIVE_METASTORE": HEAP_PER_MASTER_COMPONENT,
+ "HIVE_SERVER": HEAP_PER_MASTER_COMPONENT
},
"KAFKA": {
"KAFKA_BROKER": HEAP_PER_MASTER_COMPONENT
@@ -542,6 +546,13 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
"AMBARI_METRICS": {
"METRICS_COLLECTOR": HEAP_PER_MASTER_COMPONENT,
"METRICS_MONITOR": HEAP_PER_SLAVE_COMPONENT
+ },
+ "ACCUMULO": {
+ "ACCUMULO_MASTER": HEAP_PER_MASTER_COMPONENT,
+ "ACCUMULO_TSERVER": HEAP_PER_SLAVE_COMPONENT
+ },
+ "LOGSEARCH": {
+ "LOGSEARCH_LOGFEEDER" : HEAP_PER_SLAVE_COMPONENT
}
}
total_sinks_count = 0
@@ -552,9 +563,10 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
schCount = len(
self.getHostsWithComponent(serviceName, componentName, services,
hosts))
- hbase_heapsize += int((schCount * multiplier) ** 0.9)
+ hbase_heapsize += int((schCount * multiplier))
total_sinks_count += schCount
- collector_heapsize = int(hbase_heapsize/4 if hbase_heapsize > 2048 else 512)
+ collector_heapsize = int(hbase_heapsize/3 if hbase_heapsize > 2048 else 512)
+ hbase_heapsize = min(hbase_heapsize, 32768)
return round_to_n(collector_heapsize), round_to_n(hbase_heapsize), total_sinks_count
@@ -679,7 +691,7 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
putAmsHbaseSiteProperty("phoenix.coprocessor.maxMetaDataCacheSize", 81920000)
putAmsSiteProperty("phoenix.query.maxGlobalMemoryPercentage", 30)
putAmsSiteProperty("timeline.metrics.service.resultset.fetchSize", 10000)
- elif total_sinks_count >= 500:
+ elif total_sinks_count >= 1000:
putAmsHbaseSiteProperty("hbase.regionserver.handler.count", 60)
putAmsHbaseSiteProperty("hbase.regionserver.hlog.blocksize", 134217728)
putAmsHbaseSiteProperty("hbase.regionserver.maxlogs", 64)
@@ -695,17 +707,17 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
# Distributed mode heap size
if operatingMode == "distributed":
- hbase_heapsize = max(hbase_heapsize, 768)
+ hbase_heapsize = max(hbase_heapsize, 1024)
putHbaseEnvProperty("hbase_master_heapsize", "512")
putHbaseEnvProperty("hbase_master_xmn_size", "102") #20% of 512 heap size
putHbaseEnvProperty("hbase_regionserver_heapsize", hbase_heapsize)
- putHbaseEnvProperty("regionserver_xmn_size", round_to_n(0.15*hbase_heapsize,64))
+ putHbaseEnvProperty("regionserver_xmn_size", round_to_n(0.15 * hbase_heapsize,64))
else:
# Embedded mode heap size : master + regionserver
- hbase_rs_heapsize = 768
+ hbase_rs_heapsize = 512
putHbaseEnvProperty("hbase_regionserver_heapsize", hbase_rs_heapsize)
putHbaseEnvProperty("hbase_master_heapsize", hbase_heapsize)
- putHbaseEnvProperty("hbase_master_xmn_size", round_to_n(0.15*(hbase_heapsize+hbase_rs_heapsize),64))
+ putHbaseEnvProperty("hbase_master_xmn_size", round_to_n(0.15*(hbase_heapsize + hbase_rs_heapsize),64))
# If no local DN in distributed mode
if operatingMode == "distributed":
@@ -832,6 +844,12 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
pass
elif len(self.getComponentHostNames(services, "AMBARI_METRICS", "METRICS_COLLECTOR")) > 1 and op_mode != 'distributed':
correct_op_mode_item = self.getErrorItem("Correct value should be 'distributed' for clusters with more then 1 Metrics collector")
+ elif op_mode == 'embedded':
+ collector_heapsize, hbase_heapsize, total_sinks_count = self.getAmsMemoryRecommendation(services, hosts)
+ if total_sinks_count > 1000:
+ correct_op_mode_item = self.getWarnItem("Number of sinks writing metrics to collector is expected to be more than 1000. "
+ "'Embedded' mode AMS might not be able to handle the load. Consider moving to distributed mode.")
+
validationItems.extend([{"config-name":'timeline.metrics.service.operation.mode', "item": correct_op_mode_item }])
return self.toConfigurationValidationProblems(validationItems, "ams-site")
@@ -1003,6 +1021,11 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
is_hbase_distributed = amsHbaseSite.get("hbase.cluster.distributed").lower() == 'true'
if is_hbase_distributed:
+
+ if not regionServerItem and hbase_regionserver_heapsize > 32768:
+ regionServerItem = self.getWarnItem("Value is more than the recommended maximum heap size of 32G.")
+ validationItems.extend([{"config-name": "hbase_regionserver_heapsize", "item": regionServerItem}])
+
minMasterXmn = 0.12 * hbase_master_heapsize
maxMasterXmn = 0.2 * hbase_master_heapsize
if hbase_master_xmn_size < minMasterXmn:
@@ -1025,6 +1048,11 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
"(20% of hbase_regionserver_heapsize)"
.format(int(floor(maxRegionServerXmn))))
else:
+
+ if not hbaseMasterHeapsizeItem and (hbase_master_heapsize + hbase_regionserver_heapsize) > 32768:
+ hbaseMasterHeapsizeItem = self.getWarnItem("Value of Master + Regionserver heapsize is more than the recommended maximum heap size of 32G.")
+ validationItems.extend([{"config-name": "hbase_master_heapsize", "item": hbaseMasterHeapsizeItem}])
+
minMasterXmn = 0.12 * (hbase_master_heapsize + hbase_regionserver_heapsize)
maxMasterXmn = 0.2 * (hbase_master_heapsize + hbase_regionserver_heapsize)
if hbase_master_xmn_size < minMasterXmn:
@@ -1071,39 +1099,6 @@ class HDP206StackAdvisor(DefaultStackAdvisor):
collectorHostName, str(", ".join(hostMasterComponents[collectorHostName]))))
if hbaseMasterHeapsizeItem:
validationItems.extend([{"config-name": "hbase_master_heapsize", "item": hbaseMasterHeapsizeItem}])
-
- # Check for unused RAM on AMS Collector node
- hostComponents = []
- for service in services["services"]:
- for component in service["components"]:
- if component["StackServiceComponents"]["hostnames"] is not None:
- if collectorHostName in component["StackServiceComponents"]["hostnames"]:
- hostComponents.append(component["StackServiceComponents"]["component_name"])
-
- requiredMemory = self.getMemorySizeRequired(services, hostComponents, configurations)
- unusedMemory = host["Hosts"]["total_mem"] * 1024 - requiredMemory # in bytes
-
- heapPropertyToIncrease = "hbase_regionserver_heapsize" if is_hbase_distributed else "hbase_master_heapsize"
- xmnPropertyToIncrease = "regionserver_xmn_size" if is_hbase_distributed else "hbase_master_xmn_size"
- hbase_needs_increase = self.to_number(properties[heapPropertyToIncrease]) * mb < 32 * gb
-
- if unusedMemory > 4*gb and hbase_needs_increase: # warn user, if more than 4GB RAM is unused
-
- recommended_hbase_heapsize = int((unusedMemory - 4*gb)*4/5) + self.to_number(properties.get(heapPropertyToIncrease))*mb
- recommended_hbase_heapsize = min(32*gb, recommended_hbase_heapsize) #Make sure heapsize <= 32GB
- recommended_hbase_heapsize = round_to_n(recommended_hbase_heapsize/mb,128) # Round to 128m multiple
- if self.to_number(properties[heapPropertyToIncrease]) < recommended_hbase_heapsize:
- hbaseHeapsizeItem = self.getWarnItem("Consider allocating {0} MB to {1} in ams-hbase-env to use up some "
- "unused memory on host"
- .format(recommended_hbase_heapsize,
- heapPropertyToIncrease))
- validationItems.extend([{"config-name": heapPropertyToIncrease, "item": hbaseHeapsizeItem}])
-
- recommended_xmn_size = round_to_n(0.15*recommended_hbase_heapsize,128)
- if self.to_number(properties[xmnPropertyToIncrease]) < recommended_xmn_size:
- xmnPropertyToIncreaseItem = self.getWarnItem("Consider allocating {0} MB to use up some unused memory "
- "on host".format(recommended_xmn_size))
- validationItems.extend([{"config-name": xmnPropertyToIncrease, "item": xmnPropertyToIncreaseItem}])
pass
return self.toConfigurationValidationProblems(validationItems, "ams-hbase-env")
http://git-wip-us.apache.org/repos/asf/ambari/blob/6c40fdf4/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
index 0c4996b..65b23b0 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/common/test_stack_advisor.py
@@ -2410,7 +2410,7 @@ class TestHDP206StackAdvisor(TestCase):
'ams-hbase-env': {'properties': {'hbase_log_dir': '/var/log/ambari-metrics-collector',
'hbase_master_heapsize': '512',
'hbase_master_xmn_size': '102',
- 'hbase_regionserver_heapsize': '768',
+ 'hbase_regionserver_heapsize': '1024',
'regionserver_xmn_size': '128'}},
'ams-hbase-site': {'properties': {'hbase.cluster.distributed': 'true',
'hbase.hregion.memstore.flush.size': '134217728',
@@ -2475,7 +2475,7 @@ class TestHDP206StackAdvisor(TestCase):
'ams-hbase-env': {'properties': {'hbase_log_dir': '/var/log/ambari-metrics-collector',
'hbase_master_heapsize': '512',
'hbase_master_xmn_size': '102',
- 'hbase_regionserver_heapsize': '768',
+ 'hbase_regionserver_heapsize': '1024',
'regionserver_xmn_size': '128'}},
'ams-hbase-site': {'properties': {'hbase.cluster.distributed': 'true',
'hbase.hregion.memstore.flush.size': '134217728',
http://git-wip-us.apache.org/repos/asf/ambari/blob/6c40fdf4/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py b/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
index 571ff26..d6b572e 100644
--- a/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
+++ b/ambari-server/src/test/python/stacks/2.2/common/test_stack_advisor.py
@@ -2338,9 +2338,9 @@ class TestHDP22StackAdvisor(TestCase):
expected = {
"ams-hbase-env": {
"properties": {
- "hbase_master_xmn_size": "192",
+ "hbase_master_xmn_size": "128",
"hbase_master_heapsize": "512",
- "hbase_regionserver_heapsize": "768"
+ "hbase_regionserver_heapsize": "512"
}
},
"ams-grafana-env": {
@@ -2416,14 +2416,14 @@ class TestHDP22StackAdvisor(TestCase):
expected["ams-site"]['properties']['timeline.metrics.cache.size'] = '500'
expected["ams-site"]['properties']['timeline.metrics.cache.commit.interval'] = '7'
- expected["ams-hbase-env"]['properties']['hbase_master_heapsize'] = '1408'
- expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '320'
- expected["ams-env"]['properties']['metrics_collector_heapsize'] = '512'
+ expected["ams-hbase-env"]['properties']['hbase_master_heapsize'] = '2560'
+ expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '448'
+ expected["ams-env"]['properties']['metrics_collector_heapsize'] = '896'
self.stackAdvisor.recommendAmsConfigurations(configurations, clusterData, services, hosts)
self.assertEquals(configurations, expected)
- # Still 100 nodes, but with HDFS and YARN services installed on all nodes
+ # 200 nodes, but with HDFS and YARN services installed on all nodes
services['services'] = [
{
"StackServices": {
@@ -2484,14 +2484,22 @@ class TestHDP22StackAdvisor(TestCase):
}
]
- expected["ams-site"]['properties']['timeline.metrics.host.aggregate.splitpoints'] = 'mem_total'
+ expected["ams-site"]['properties']['timeline.metrics.host.aggregate.splitpoints'] = 'dfs.FSNamesystem.FilesTotal,' \
+ 'dfs.datanode.WritesFromRemoteClient,' \
+ 'ipc.IPC.numCallsInReplicationQueue,' \
+ 'mapred.ShuffleMetrics.ShuffleOutputsFailed,' \
+ 'mem_buffered,' \
+ 'read_count,' \
+ 'regionserver.Server.percentFilesLocal,' \
+ 'rpcdetailed.rpcdetailed.RegisterNodeManagerNumOps,' \
+ 'sdisk_vdb_write_count'
expected["ams-site"]['properties']['timeline.metrics.cluster.aggregate.splitpoints'] = 'mem_total'
- expected["ams-site"]['properties']['timeline.metrics.cache.size'] = '500'
- expected["ams-site"]['properties']['timeline.metrics.cache.commit.interval'] = '7'
- expected["ams-hbase-env"]['properties']['hbase_master_heapsize'] = '2432'
- expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '512'
- expected["ams-env"]['properties']['metrics_collector_heapsize'] = '640'
+ expected["ams-site"]['properties']['timeline.metrics.cache.size'] = '600'
+ expected["ams-site"]['properties']['timeline.metrics.cache.commit.interval'] = '6'
+ expected["ams-hbase-env"]['properties']['hbase_master_heapsize'] = '6656'
+ expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '1088'
+ expected["ams-env"]['properties']['metrics_collector_heapsize'] = '2176'
self.stackAdvisor.recommendAmsConfigurations(configurations, clusterData, services, hosts)
self.assertEquals(configurations, expected)
@@ -2535,6 +2543,7 @@ class TestHDP22StackAdvisor(TestCase):
self.stackAdvisor.recommendAmsConfigurations(configurations, clusterData, services, hosts)
self.assertEquals(configurations, expected)
+
# Embedded mode, 8192m master heapsize, more splitpoints recommended
services["configurations"]['ams-hbase-env']['properties']['hbase_master_heapsize'] = '8192'
expected['ams-hbase-env']['properties']['hbase_master_heapsize'] = '8192'
@@ -2559,12 +2568,11 @@ class TestHDP22StackAdvisor(TestCase):
expected['ams-hbase-site']['properties']['dfs.client.read.shortcircuit'] = 'true'
# Distributed mode, low memory, no splitpoints recommended
- services["configurations"]['ams-hbase-env']['properties']['hbase_regionserver_heapsize'] = '512'
expected['ams-site']['properties']['timeline.metrics.host.aggregate.splitpoints'] = 'mem_total'
expected['ams-site']['properties']['timeline.metrics.cluster.aggregate.splitpoints'] = 'mem_total'
- expected['ams-hbase-env']['properties']['hbase_regionserver_heapsize'] = '512'
+ expected['ams-hbase-env']['properties']['hbase_regionserver_heapsize'] = '6656'
expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '102'
- expected['ams-hbase-env']['properties']['regionserver_xmn_size'] = '384'
+ expected['ams-hbase-env']['properties']['regionserver_xmn_size'] = '1024'
expected['ams-site']['properties']['timeline.metrics.service.watcher.disabled'] = 'true'
self.stackAdvisor.recommendAmsConfigurations(configurations, clusterData, services, hosts)
self.assertEquals(configurations, expected)
@@ -2610,6 +2618,200 @@ class TestHDP22StackAdvisor(TestCase):
self.assertEquals(configurations["ams-site"]['properties']['timeline.metrics.cache.size'], '700')
self.assertEquals(configurations["ams-site"]['properties']['timeline.metrics.cache.commit.interval'], '5')
+ # 500 Nodes with HDFS, YARN, HIVE, STORM, HBASE, KAFKA, AMS
+ node_count = 500
+ hosts = {
+ "items": []
+ }
+ for i in range(1, node_count):
+ hosts['items'].extend([{
+ "Hosts": {
+ "host_name": "host" + str(i)
+ }
+ }])
+
+ services['services'] = [
+ {
+ "StackServices": {
+ "service_name": "HDFS"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "NAMENODE",
+ "hostnames": ["host1"]
+ }
+ } ,
+ {
+ "StackServiceComponents": {
+ "component_name": "SECONDARY_NAMENODE",
+ "hostnames": ["host2"]
+ }
+ },
+ {
+ "StackServiceComponents": {
+ "component_name": "DATANODE",
+ "hostnames": ["host" + str(i) for i in range(6, node_count + 1)]
+ }
+ }
+ ]
+ },
+ {
+ "StackServices": {
+ "service_name": "HBASE"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "HBASE_MASTER",
+ "hostnames": ["host3"]
+ }
+ },
+ {
+ "StackServiceComponents": {
+ "component_name": "HBASE_REGIONSERVER",
+ "hostnames": ["host" + str(i) for i in range(6, node_count + 1)]
+ }
+ }
+ ]
+ },
+ {
+ "StackServices": {
+ "service_name": "YARN"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "RESOURCEMANAGER",
+ "hostnames": ["host4"]
+ }
+ },
+ {
+ "StackServiceComponents": {
+ "component_name": "NODEMANAGER",
+ "hostnames": ["host" + str(i) for i in range(6, node_count + 1)]
+ }
+ }
+ ]
+ },
+ {
+ "StackServices": {
+ "service_name": "HIVE"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "HIVE_METASTORE",
+ "hostnames": ["host3"]
+ }
+ },
+ {
+ "StackServiceComponents": {
+ "component_name": "HIVE_SERVER",
+ "hostnames": ["host3"]
+ }
+ }
+ ]
+ },
+ {
+ "StackServices": {
+ "service_name": "STORM"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "NIMBUS",
+ "hostnames": ["host" + str(i) for i in range(1, 6)]
+ }
+ }
+ ]
+ },
+ {
+ "StackServices": {
+ "service_name": "KAFKA"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "KAFKA_BROKER",
+ "hostnames": ["host" + str(i) for i in range(1, 6)]
+ }
+ }
+ ]
+ },
+ {
+ "StackServices": {
+ "service_name": "AMBARI_METRICS"
+ },
+ "components": [
+ {
+ "StackServiceComponents": {
+ "component_name": "METRICS_COLLECTOR",
+ "hostnames": ["host6"]
+ }
+ },
+ {
+ "StackServiceComponents": {
+ "component_name": "METRICS_MONITOR",
+ "hostnames": ["host" + str(i) for i in range(6, node_count + 1)]
+ }
+ }
+ ]
+ }
+ ]
+
+ services['configurations'] = {
+ 'core-site': {'properties': {}},
+ 'ams-site': {'properties': {}},
+ 'ams-hbase-site': {'properties': {}},
+ 'ams-hbase-env': {'properties': {}}
+ }
+ services["configurations"]['ams-site']['properties']['timeline.metrics.service.operation.mode'] = 'distributed'
+
+ expected['ams-hbase-site']['properties']['hbase.cluster.distributed'] = 'true'
+ expected['ams-hbase-site']['properties']['hbase.rootdir'] = '/user/ams/hbase'
+ expected['ams-hbase-site']['properties']['hbase.zookeeper.property.clientPort'] = '2181'
+
+ expected["ams-site"]['properties']['timeline.metrics.host.aggregate.splitpoints'] = 'default.General.active_calls_api_get_all_databases,' \
+ 'default.General.api_get_database_mean,' \
+ 'default.General.gc.PS-MarkSweep.count,' \
+ 'dfs.FsVolume.TotalDataFileIos,' \
+ 'disk_free,' \
+ 'jvm.JvmMetrics.MemHeapMaxM,' \
+ 'kafka.network.RequestMetrics.RemoteTimeMs.request.Metadata.75percentile,' \
+ 'kafka.network.RequestMetrics.ResponseQueueTimeMs.request.Update.Metadata.mean,' \
+ 'load_one,master.FileSystem.MetaHlogSplitTime_75th_percentile,' \
+ 'metricssystem.MetricsSystem.NumActiveSources,' \
+ 'regionserver.Server.Append_95th_percentile,' \
+ 'regionserver.Server.blockCacheEvictionCount,' \
+ 'rpc.rpc.client.SentBytes,' \
+ 'sdisk_vda1_write_bytes'
+ expected["ams-site"]['properties']['timeline.metrics.cluster.aggregate.splitpoints'] = 'ipc.IPC.authorizationSuccesses,' \
+ 'metricssystem.MetricsSystem.PublishNumOps'
+
+ expected["ams-site"]['properties']['timeline.metrics.cache.size'] = '700'
+ expected["ams-site"]['properties']['timeline.metrics.cache.commit.interval'] = '5'
+ expected["ams-site"]['properties']['timeline.metrics.service.resultset.fetchSize'] = '5000'
+ expected["ams-site"]['properties']['phoenix.query.maxGlobalMemoryPercentage'] = '30'
+
+ expected["ams-env"]['properties']['metrics_collector_heapsize'] = '7040'
+
+ expected["ams-hbase-env"]['properties']['hbase_master_heapsize'] = '512'
+ expected["ams-hbase-env"]['properties']['hbase_master_xmn_size'] = '102'
+
+ expected["ams-hbase-env"]['properties']['hbase_regionserver_heapsize'] = '21120'
+ expected["ams-hbase-env"]['properties']['regionserver_xmn_size'] = '3200'
+
+ expected["ams-hbase-site"]['properties']['phoenix.query.maxGlobalMemoryPercentage'] = '20'
+ expected['ams-hbase-site']['properties']['hbase.hregion.memstore.flush.size'] = '268435456'
+ expected['ams-hbase-site']['properties']['hbase.regionserver.handler.count'] = '60'
+ expected['ams-hbase-site']['properties']['hbase.regionserver.hlog.blocksize'] = '134217728'
+ expected['ams-hbase-site']['properties']['hbase.regionserver.maxlogs'] = '64'
+ expected['ams-hbase-site']['properties']['phoenix.coprocessor.maxMetaDataCacheSize'] = '40960000'
+
+ self.stackAdvisor.recommendAmsConfigurations(configurations, clusterData, services, hosts)
+ self.assertEquals(configurations, expected)
+
def test_recommendHbaseConfigurations(self):
servicesList = ["HBASE"]
configurations = {}
[16/38] ambari git commit: AMBARI-21946 Log Search UI: reorganize
generated files structure. (ababiichuk)
Posted by lp...@apache.org.
AMBARI-21946 Log Search UI: reorganize generated files structure. (ababiichuk)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/2a6dd58f
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/2a6dd58f
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/2a6dd58f
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 2a6dd58f506b5e9fcaf7b435e645c2397fe35855
Parents: 18ae06d
Author: ababiichuk <ab...@hortonworks.com>
Authored: Wed Sep 13 16:19:25 2017 +0300
Committer: ababiichuk <ab...@hortonworks.com>
Committed: Wed Sep 13 16:56:56 2017 +0300
----------------------------------------------------------------------
.../ambari-logsearch-web/.angular-cli.json | 34 +-
ambari-logsearch/ambari-logsearch-web/README.md | 10 +-
.../ambari-logsearch-web/package.json | 34 +-
ambari-logsearch/ambari-logsearch-web/pom.xml | 1 +
.../ambari-logsearch-web/src/app/app.module.ts | 2 +-
.../ambari-logsearch-web/webpack.config.js | 530 +++++++++++++++++++
6 files changed, 571 insertions(+), 40 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/2a6dd58f/ambari-logsearch/ambari-logsearch-web/.angular-cli.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/.angular-cli.json b/ambari-logsearch/ambari-logsearch-web/.angular-cli.json
index 70fd7b6..267f5e0 100644
--- a/ambari-logsearch/ambari-logsearch-web/.angular-cli.json
+++ b/ambari-logsearch/ambari-logsearch-web/.angular-cli.json
@@ -1,12 +1,12 @@
{
"$schema": "./node_modules/@angular/cli/lib/config/schema.json",
"project": {
- "name": "ambari-logsearch-web"
+ "name": "ambari-logsearch-web",
+ "ejected": true
},
"apps": [
{
"root": "src",
- "outDir": "dist",
"assets": [
"assets",
"favicon.ico"
@@ -15,20 +15,8 @@
"main": "main.ts",
"polyfills": "polyfills.ts",
"test": "test.ts",
- "tsconfig": "tsconfig.app.json",
"testTsconfig": "tsconfig.spec.json",
- "prefix": "app",
- "styles": [
- "styles.less",
- "../node_modules/bootstrap/dist/css/bootstrap.min.css",
- "../node_modules/font-awesome/css/font-awesome.min.css",
- "../src/vendor/css/bootstrap-logsearch.min.css"
- ],
- "scripts": [
- "../node_modules/jquery/dist/jquery.min.js",
- "../node_modules/bootstrap/dist/js/bootstrap.min.js",
- "../src/vendor/js/bootstrap-logsearch.min.js"
- ],
+ "prefix": "",
"environmentSource": "environments/environment.ts",
"environments": {
"dev": "environments/environment.ts",
@@ -36,11 +24,6 @@
}
}
],
- "e2e": {
- "protractor": {
- "config": "./protractor.conf.js"
- }
- },
"lint": [
{
"project": "src/tsconfig.app.json"
@@ -52,13 +35,8 @@
"project": "e2e/tsconfig.e2e.json"
}
],
- "test": {
- "karma": {
- "config": "./karma.conf.js"
- }
- },
"defaults": {
- "styleExt": "less",
- "component": {}
- }
+ "styleExt": "less"
+ },
+ "packageManager": "yarn"
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2a6dd58f/ambari-logsearch/ambari-logsearch-web/README.md
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/README.md b/ambari-logsearch/ambari-logsearch-web/README.md
index ff1456e..081d22a 100644
--- a/ambari-logsearch/ambari-logsearch-web/README.md
+++ b/ambari-logsearch/ambari-logsearch-web/README.md
@@ -4,7 +4,7 @@ This project was generated with [Angular CLI](https://github.com/angular/angular
## Development server
-Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
+Run `npm start` or `yarn start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files.
## Code scaffolding
@@ -12,16 +12,16 @@ Run `ng generate component component-name` to generate a new component. You can
## Build
-Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build.
+Run `npm run build` or `yarn build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `npm run build-prod` or `yarn build-prod` command for a production build.
## Running unit tests
-Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+Run `npm test` or `yarn test` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Running end-to-end tests
-Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
-Before running the tests make sure you are serving the app via `ng serve`.
+Run `npm run e2e` or `yarn e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
+Before running the tests make sure you are serving the app via `npm start` or `yarn start`.
## Further help
http://git-wip-us.apache.org/repos/asf/ambari/blob/2a6dd58f/ambari-logsearch/ambari-logsearch-web/package.json
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/package.json b/ambari-logsearch/ambari-logsearch-web/package.json
index 0892d85..7e8a0ba 100644
--- a/ambari-logsearch/ambari-logsearch-web/package.json
+++ b/ambari-logsearch/ambari-logsearch-web/package.json
@@ -4,12 +4,13 @@
"license": "Apache 2.0",
"scripts": {
"ng": "ng",
- "start": "ng serve",
- "build": "ng build",
- "build-prod": "ng build -prod",
- "test": "ng test",
+ "start": "webpack-dev-server --port=4200",
+ "build": "webpack",
+ "build-prod": "NODE_ENV='production' webpack -p",
+ "test": "karma start ./karma.conf.js",
"lint": "ng lint",
- "e2e": "ng e2e"
+ "e2e": "protractor ./protractor.conf.js",
+ "pree2e": "webdriver-manager update --standalone false --gecko false --quiet"
},
"dependencies": {
"@angular/common": "^4.0.0",
@@ -60,6 +61,27 @@
"protractor": "~5.1.0",
"ts-node": "~2.0.0",
"tslint": "~4.5.0",
- "typescript": "~2.2.0"
+ "typescript": "~2.2.0",
+ "webpack-dev-server": "~2.7.1",
+ "webpack": "~3.5.5",
+ "autoprefixer": "^6.5.3",
+ "css-loader": "^0.28.1",
+ "cssnano": "^3.10.0",
+ "exports-loader": "^0.6.3",
+ "file-loader": "^0.10.0",
+ "html-webpack-plugin": "^2.29.0",
+ "less-loader": "^4.0.5",
+ "postcss-loader": "^1.3.3",
+ "postcss-url": "^5.1.2",
+ "raw-loader": "^0.5.1",
+ "sass-loader": "^6.0.3",
+ "source-map-loader": "^0.2.0",
+ "istanbul-instrumenter-loader": "^2.0.0",
+ "style-loader": "^0.13.1",
+ "stylus-loader": "^3.0.1",
+ "url-loader": "^0.5.7",
+ "circular-dependency-plugin": "^3.0.0",
+ "webpack-concat-plugin": "1.4.0",
+ "copy-webpack-plugin": "^4.0.1"
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/2a6dd58f/ambari-logsearch/ambari-logsearch-web/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/pom.xml b/ambari-logsearch/ambari-logsearch-web/pom.xml
index 075527b..7a6b02e 100644
--- a/ambari-logsearch/ambari-logsearch-web/pom.xml
+++ b/ambari-logsearch/ambari-logsearch-web/pom.xml
@@ -117,6 +117,7 @@
<include>karma.conf.js</include>
<include>tsconfig.json</include>
<include>tslint.json</include>
+ <include>webpack.config.js</include>
</includes>
</resource>
</resources>
http://git-wip-us.apache.org/repos/asf/ambari/blob/2a6dd58f/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
index c15ecbc..8ea933c 100644
--- a/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
+++ b/ambari-logsearch/ambari-logsearch-web/src/app/app.module.ts
@@ -79,7 +79,7 @@ import {TimeZoneAbbrPipe} from '@app/pipes/timezone-abbr.pipe';
export function HttpLoaderFactory(http: Http) {
// adding 'static' parameter to step over mock data request
- return new TranslateHttpLoader(http, 'assets/i18n/', '.json?static=true');
+ return new TranslateHttpLoader(http, 'resources/assets/i18n/', '.json?static=true');
}
export function getXHRBackend(injector: Injector, browser: BrowserXhr, xsrf: XSRFStrategy, options: ResponseOptions): any {
http://git-wip-us.apache.org/repos/asf/ambari/blob/2a6dd58f/ambari-logsearch/ambari-logsearch-web/webpack.config.js
----------------------------------------------------------------------
diff --git a/ambari-logsearch/ambari-logsearch-web/webpack.config.js b/ambari-logsearch/ambari-logsearch-web/webpack.config.js
new file mode 100644
index 0000000..72eaa7f
--- /dev/null
+++ b/ambari-logsearch/ambari-logsearch-web/webpack.config.js
@@ -0,0 +1,530 @@
+/**
+ * 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.
+ */
+
+const fs = require('fs');
+const path = require('path');
+const ConcatPlugin = require('webpack-concat-plugin');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const ProgressPlugin = require('webpack/lib/ProgressPlugin');
+const CircularDependencyPlugin = require('circular-dependency-plugin');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const autoprefixer = require('autoprefixer');
+const postcssUrl = require('postcss-url');
+const cssnano = require('cssnano');
+
+const {NoEmitOnErrorsPlugin, SourceMapDevToolPlugin, NamedModulesPlugin} = require('webpack');
+const {InsertConcatAssetsWebpackPlugin, NamedLazyChunksWebpackPlugin, BaseHrefWebpackPlugin} = require('@angular/cli/plugins/webpack');
+const {CommonsChunkPlugin} = require('webpack').optimize;
+const {AotPlugin} = require('@ngtools/webpack');
+
+const nodeModules = path.join(process.cwd(), 'node_modules');
+const realNodeModules = fs.realpathSync(nodeModules);
+const genDirNodeModules = path.join(process.cwd(), 'src', '$$_gendir', 'node_modules');
+const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];
+const minimizeCss = false;
+const baseHref = "";
+const deployUrl = "";
+const postcssPlugins = function () {
+ // safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193
+ const importantCommentRe = /@preserve|@license|[@#]\s*source(?:Mapping)?URL|^!/i;
+ const minimizeOptions = {
+ autoprefixer: false,
+ safe: true,
+ mergeLonghand: false,
+ discardComments: { remove: (comment) => !importantCommentRe.test(comment) }
+ };
+ return [
+ postcssUrl({
+ url: (URL) => {
+ // Only convert root relative URLs, which CSS-Loader won't process into require().
+ if (!URL.startsWith('/') || URL.startsWith('//')) {
+ return URL;
+ }
+ if (deployUrl.match(/:\/\//)) {
+ // If deployUrl contains a scheme, ignore baseHref use deployUrl as is.
+ return `${deployUrl.replace(/\/$/, '')}${URL}`;
+ }
+ else if (baseHref.match(/:\/\//)) {
+ // If baseHref contains a scheme, include it as is.
+ return baseHref.replace(/\/$/, '') +
+ `/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
+ }
+ else {
+ // Join together base-href, deploy-url and the original URL.
+ // Also dedupe multiple slashes into single ones.
+ return `/${baseHref}/${deployUrl}/${URL}`.replace(/\/\/+/g, '/');
+ }
+ }
+ }),
+ autoprefixer(),
+ ].concat(minimizeCss ? [cssnano(minimizeOptions)] : []);
+ };
+
+module.exports = {
+ "resolve": {
+ "extensions": [
+ ".ts",
+ ".js"
+ ],
+ "modules": [
+ "./node_modules",
+ "./node_modules"
+ ],
+ "symlinks": true
+ },
+ "resolveLoader": {
+ "modules": [
+ "./node_modules",
+ "./node_modules"
+ ]
+ },
+ "entry": {
+ "main": [
+ "./src/main.ts"
+ ],
+ "polyfills": [
+ "./src/polyfills.ts"
+ ],
+ "styles": [
+ "./src/styles.less",
+ "./node_modules/bootstrap/dist/css/bootstrap.min.css",
+ "./node_modules/font-awesome/css/font-awesome.min.css",
+ "./src/vendor/css/bootstrap-logsearch.min.css"
+ ]
+ },
+ "output": {
+ "path": path.join(process.cwd(), "dist/resources"),
+ "publicPath": "resources/",
+ "filename": "[name].bundle.js",
+ "chunkFilename": "[id].chunk.js"
+ },
+ "module": {
+ "rules": [
+ {
+ "enforce": "pre",
+ "test": /\.js$/,
+ "loader": "source-map-loader",
+ "exclude": [
+ /(\\|\/)node_modules(\\|\/)/
+ ]
+ },
+ {
+ "test": /\.html$/,
+ "loader": "raw-loader"
+ },
+ {
+ "test": /\.(eot|svg|cur)$/,
+ "loader": "file-loader?name=[name].[ext]"
+ },
+ {
+ "test": /\.(jpg|png|webp|gif|otf|ttf|woff|woff2|ani)$/,
+ "loader": "url-loader?name=[name].[ext]&limit=10000"
+ },
+ {
+ "exclude": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.css$/,
+ "use": [
+ "exports-loader?module.exports.toString()",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ }
+ ]
+ },
+ {
+ "exclude": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.scss$|\.sass$/,
+ "use": [
+ "exports-loader?module.exports.toString()",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ },
+ {
+ "loader": "sass-loader",
+ "options": {
+ "sourceMap": false,
+ "precision": 8,
+ "includePaths": []
+ }
+ }
+ ]
+ },
+ {
+ "exclude": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.less$/,
+ "use": [
+ "exports-loader?module.exports.toString()",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ },
+ {
+ "loader": "less-loader",
+ "options": {
+ "sourceMap": false,
+ "paths": []
+ }
+ }
+ ]
+ },
+ {
+ "exclude": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.styl$/,
+ "use": [
+ "exports-loader?module.exports.toString()",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ },
+ {
+ "loader": "stylus-loader",
+ "options": {
+ "sourceMap": false,
+ "paths": []
+ }
+ }
+ ]
+ },
+ {
+ "include": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.css$/,
+ "use": [
+ "style-loader",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ }
+ ]
+ },
+ {
+ "include": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.scss$|\.sass$/,
+ "use": [
+ "style-loader",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ },
+ {
+ "loader": "sass-loader",
+ "options": {
+ "sourceMap": false,
+ "precision": 8,
+ "includePaths": []
+ }
+ }
+ ]
+ },
+ {
+ "include": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.less$/,
+ "use": [
+ "style-loader",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ },
+ {
+ "loader": "less-loader",
+ "options": {
+ "sourceMap": false,
+ "paths": []
+ }
+ }
+ ]
+ },
+ {
+ "include": [
+ path.join(process.cwd(), "src/styles.less"),
+ path.join(process.cwd(), "node_modules/bootstrap/dist/css/bootstrap.min.css"),
+ path.join(process.cwd(), "node_modules/font-awesome/css/font-awesome.min.css"),
+ path.join(process.cwd(), "src/vendor/css/bootstrap-logsearch.min.css")
+ ],
+ "test": /\.styl$/,
+ "use": [
+ "style-loader",
+ {
+ "loader": "css-loader",
+ "options": {
+ "sourceMap": false,
+ "importLoaders": 1
+ }
+ },
+ {
+ "loader": "postcss-loader",
+ "options": {
+ "ident": "postcss",
+ "plugins": postcssPlugins
+ }
+ },
+ {
+ "loader": "stylus-loader",
+ "options": {
+ "sourceMap": false,
+ "paths": []
+ }
+ }
+ ]
+ },
+ {
+ "test": /\.ts$/,
+ "loader": "@ngtools/webpack"
+ }
+ ]
+ },
+ "plugins": [
+ new NoEmitOnErrorsPlugin(),
+ new ConcatPlugin({
+ "uglify": false,
+ "sourceMap": true,
+ "name": "scripts",
+ "fileName": "../resources/[name].bundle.js",
+ "filesToConcat": [
+ "node_modules/jquery/dist/jquery.min.js",
+ "node_modules/bootstrap/dist/js/bootstrap.min.js",
+ "src/vendor/js/bootstrap-logsearch.min.js"
+ ]
+ }),
+ new InsertConcatAssetsWebpackPlugin([
+ "scripts"
+ ]),
+ new CopyWebpackPlugin([
+ {
+ "context": "src/",
+ "to": "",
+ "from": {
+ "glob": "assets/**/*",
+ "dot": true
+ }
+ },
+ {
+ "context": "src/",
+ "to": "../favicon.ico",
+ "from": {
+ "glob": "favicon.ico",
+ "dot": true
+ }
+ }
+ ], {
+ "ignore": [
+ ".gitkeep"
+ ],
+ "debug": "warning"
+ }),
+ new ProgressPlugin(),
+ new CircularDependencyPlugin({
+ "exclude": /(\\|\/)node_modules(\\|\/)/,
+ "failOnError": false
+ }),
+ new NamedLazyChunksWebpackPlugin(),
+ new HtmlWebpackPlugin({
+ "template": "./src/index.html",
+ "filename": "../index.html",
+ "hash": false,
+ "inject": true,
+ "compile": true,
+ "favicon": false,
+ "minify": false,
+ "cache": true,
+ "showErrors": true,
+ "chunks": "all",
+ "excludeChunks": [],
+ "title": "Webpack App",
+ "xhtml": true,
+ "chunksSortMode": function sort(left, right) {
+ let leftIndex = entryPoints.indexOf(left.names[0]);
+ let rightindex = entryPoints.indexOf(right.names[0]);
+ if (leftIndex > rightindex) {
+ return 1;
+ }
+ else if (leftIndex < rightindex) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
+ }
+ }),
+ new BaseHrefWebpackPlugin({}),
+ new CommonsChunkPlugin({
+ "name": [
+ "inline"
+ ],
+ "minChunks": null
+ }),
+ new CommonsChunkPlugin({
+ "name": [
+ "vendor"
+ ],
+ "minChunks": (module) => {
+ return module.resource
+ && (module.resource.startsWith(nodeModules)
+ || module.resource.startsWith(genDirNodeModules)
+ || module.resource.startsWith(realNodeModules));
+ },
+ "chunks": [
+ "main"
+ ]
+ }),
+ new SourceMapDevToolPlugin({
+ "filename": "[file].map[query]",
+ "moduleFilenameTemplate": "[resource-path]",
+ "fallbackModuleFilenameTemplate": "[resource-path]?[hash]",
+ "sourceRoot": "webpack:///"
+ }),
+ new CommonsChunkPlugin({
+ "name": [
+ "main"
+ ],
+ "minChunks": 2,
+ "async": "common"
+ }),
+ new NamedModulesPlugin({}),
+ new AotPlugin({
+ "mainPath": "main.ts",
+ "replaceExport": false,
+ "hostReplacementPaths": {
+ "environments/environment.ts": `environments/environment${process.env.NODE_ENV === "production" ? ".prod" : ""}.ts`
+ },
+ "exclude": [],
+ "tsConfigPath": "src/tsconfig.app.json",
+ "skipCodeGeneration": true
+ })
+ ],
+ "node": {
+ "fs": "empty",
+ "global": true,
+ "crypto": "empty",
+ "tls": "empty",
+ "net": "empty",
+ "process": true,
+ "module": false,
+ "clearImmediate": false,
+ "setImmediate": false
+ },
+ "devServer": {
+ "contentBase": path.join(process.cwd(), "dist"),
+ "historyApiFallback": true
+ }
+};
[27/38] ambari git commit: AMBARI-21545 Stack Advisor support for
LDAP configuration (benyoka)
Posted by lp...@apache.org.
AMBARI-21545 Stack Advisor support for LDAP configuration (benyoka)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/a7757b22
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/a7757b22
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/a7757b22
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: a7757b222d33b7aace9319303956c6bf456cb16c
Parents: faf9534
Author: Balazs Bence Sari <be...@apache.org>
Authored: Tue Aug 8 20:17:14 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:30 2017 +0200
----------------------------------------------------------------------
.../services/AmbariConfigurationService.java | 4 +-
.../stackadvisor/StackAdvisorRequest.java | 12 ++
.../commands/StackAdvisorCommand.java | 54 +++++
.../commands/StackAdvisorCommandTest.java | 212 +++++++++++++++++++
.../StackAdvisorResourceProviderTest.java | 97 ++++-----
5 files changed, 324 insertions(+), 55 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/a7757b22/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 0632361..927e518 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,9 +56,9 @@ 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>
http://git-wip-us.apache.org/repos/asf/ambari/blob/a7757b22/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
index 3a2b488..cd26c56 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRequest.java
@@ -31,6 +31,8 @@ import org.apache.ambari.server.api.services.stackadvisor.recommendations.Recomm
import org.apache.ambari.server.state.ChangedConfigInfo;
import org.apache.commons.lang.StringUtils;
+import com.google.common.base.Preconditions;
+
/**
* Stack advisor request.
*/
@@ -48,6 +50,7 @@ public class StackAdvisorRequest {
private List<ChangedConfigInfo> changedConfigurations = new LinkedList<>();
private Set<RecommendationResponse.ConfigGroup> configGroups;
private Map<String, String> userContext = new HashMap<>();
+ private Map<String, Object> ldapConfig = new HashMap<>();
public String getStackName() {
return stackName;
@@ -93,6 +96,8 @@ public class StackAdvisorRequest {
return configurations;
}
+ public Map<String, Object> getLdapConfig() { return ldapConfig; }
+
public List<ChangedConfigInfo> getChangedConfigurations() {
return changedConfigurations;
}
@@ -189,6 +194,13 @@ public class StackAdvisorRequest {
return this;
}
+ public StackAdvisorRequestBuilder withLdapConfig(Map<String, Object> ldapConfig) {
+ Preconditions.checkNotNull(ldapConfig);
+ this.instance.ldapConfig = ldapConfig;
+ return this;
+ }
+
+
public StackAdvisorRequest build() {
return this.instance;
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/a7757b22/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 356754d..2dc45de 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
@@ -84,6 +84,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
+ ",services/configurations/dependencies/StackConfigurationDependency/dependency_name"
+ ",services/configurations/dependencies/StackConfigurationDependency/dependency_type,services/configurations/StackConfigurations/type"
+ "&services/StackServices/service_name.in(%s)";
+ private static final String GET_LDAP_CONFIG_URI = "/api/v1/configurations?AmbariConfiguration/type=ldap&fields=AmbariConfiguration/*";
private static final String SERVICES_PROPERTY = "services";
private static final String SERVICES_COMPONENTS_PROPERTY = "components";
private static final String CONFIG_GROUPS_PROPERTY = "config-groups";
@@ -95,6 +96,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
private static final String CHANGED_CONFIGURATIONS_PROPERTY = "changed-configurations";
private static final String USER_CONTEXT_PROPERTY = "user-context";
private static final String AMBARI_SERVER_CONFIGURATIONS_PROPERTY = "ambari-server-properties";
+ protected static final String LDAP_CONFIGURATION_PROPERTY = "ldap-configuration";
private File recommendationsDir;
private String recommendationsArtifactsLifetime;
@@ -160,6 +162,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
populateConfigurations(root, request);
populateConfigGroups(root, request);
populateAmbariServerInfo(root);
+ populateLdapConfiguration(root);
data.servicesJSON = mapper.writeValueAsString(root);
} catch (Exception e) {
// should not happen
@@ -171,6 +174,52 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
return data;
}
+ /**
+ * Retrieves the LDAP configuration if exists and adds it to services.json
+ * @param root The JSON document that will become service.json when passed to the stack advisor engine
+ * @throws StackAdvisorException
+ * @throws IOException
+ */
+ protected void populateLdapConfiguration(ObjectNode root) throws StackAdvisorException, IOException {
+ Response response = handleRequest(null, null, new LocalUriInfo(GET_LDAP_CONFIG_URI), Request.Type.GET,
+ createConfigResource());
+
+ if (response.getStatus() != Status.OK.getStatusCode()) {
+ String message = String.format(
+ "Error occured during retrieving ldap configuration, status=%s, response=%s",
+ response.getStatus(), (String) response.getEntity());
+ LOG.warn(message);
+ throw new StackAdvisorException(message);
+ }
+
+ String ldapConfigJSON = (String) response.getEntity();
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("LDAP configuration: {}", ldapConfigJSON);
+ }
+
+ JsonNode ldapConfigRoot = mapper.readTree(ldapConfigJSON);
+ ArrayNode ldapConfigs = ((ArrayNode)ldapConfigRoot.get("items"));
+ int numConfigs = ldapConfigs.size();
+ // Zero or one config may exist
+ switch (numConfigs) {
+ case 0:
+ LOG.debug("No LDAP config is stored in the DB");
+ break;
+ case 1:
+ ArrayNode ldapConfigData = (ArrayNode)ldapConfigs.get(0).get("AmbariConfiguration").get("data");
+ if (ldapConfigData.size() == 0) {
+ throw new StackAdvisorException("No configuration data for LDAP configuration.");
+ }
+ if (ldapConfigData.size() > 1) {
+ throw new StackAdvisorException("Ambigous configuration data for LDAP configuration.");
+ }
+ root.put(LDAP_CONFIGURATION_PROPERTY, ldapConfigData.get(0));
+ break;
+ default:
+ throw new StackAdvisorException(String.format("Multiple (%s) LDAP configs are found in the DB.", numConfigs));
+ }
+ }
+
protected void populateAmbariServerInfo(ObjectNode root) throws StackAdvisorException {
Map<String, String> serverProperties = metaInfo.getAmbariServerProperties();
@@ -437,6 +486,11 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend
return createResource(Resource.Type.Host, mapIds);
}
+ protected ResourceInstance createConfigResource() {
+ return createResource(Resource.Type.AmbariConfiguration, new HashMap<>());
+ }
+
+
private ResourceInstance createStackVersionResource(String stackName, String stackVersion) {
Map<Resource.Type, String> mapIds = new HashMap<>();
mapIds.put(Resource.Type.Stack, stackName);
http://git-wip-us.apache.org/repos/asf/ambari/blob/a7757b22/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
index eaa4716..959db15 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java
@@ -18,6 +18,7 @@
package org.apache.ambari.server.api.services.stackadvisor.commands;
+import static org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand.LDAP_CONFIGURATION_PROPERTY;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
@@ -33,12 +34,21 @@ import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import javax.ws.rs.WebApplicationException;
+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.api.resources.ResourceInstance;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.Request;
+import org.apache.ambari.server.api.services.ResultStatus;
import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException;
import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest;
import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest.StackAdvisorRequestBuilder;
@@ -50,6 +60,7 @@ import org.apache.ambari.server.state.ServiceInfo;
import org.apache.commons.io.FileUtils;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.annotate.JsonProperty;
+import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.ObjectNode;
import org.junit.After;
@@ -59,6 +70,8 @@ import org.junit.rules.TemporaryFolder;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
+import com.google.common.collect.Lists;
+
/**
* StackAdvisorCommand unit tests.
*/
@@ -265,6 +278,197 @@ public class StackAdvisorCommandTest {
assertEquals(0, stackVersions.size());
}
+ @Test
+ public void testPopulateLdapConfig() throws Exception {
+ File recommendationsDir = temp.newFolder("recommendationDir");
+ String recommendationsArtifactsLifetime = "1w";
+ int requestId = 0;
+ StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+ AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+ doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+ TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+ ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+ StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion").build();
+
+ Map<String, Object> ldapConfigData = map(
+ "authentication.ldap.primaryUrl", "localhost:33389",
+ "authentication.ldap.secondaryUrl", "localhost:333",
+ "authentication.ldap.baseDn", "c=ambari,dc=apache,dc=org"
+ );
+
+ Map<String, Object> storedLdapConfigResult = map(
+ "items",
+ list(
+ map(
+ "AmbariConfiguration",
+ map(
+ "data", list(ldapConfigData)
+ )
+ )
+ )
+ );
+
+ Response response =
+ Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+ doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+ JsonNode servicesRootNode = json("{}");
+ command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+
+ JsonNode expectedLdapConfig = json(
+ map(LDAP_CONFIGURATION_PROPERTY, ldapConfigData)
+ );
+
+ assertEquals(expectedLdapConfig, servicesRootNode);
+ }
+
+ @Test
+ public void testPopulateLdapConfig_NoConfigs() throws Exception {
+ File recommendationsDir = temp.newFolder("recommendationDir");
+ String recommendationsArtifactsLifetime = "1w";
+ int requestId = 0;
+ StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+ AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+ doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+ TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+ ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+ StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion").build();
+
+ Map<String, Object> storedLdapConfigResult = map(
+ "items", list()
+ );
+
+ Response response =
+ Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+ doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+ JsonNode servicesRootNode = json("{}");
+ command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+
+ JsonNode expectedLdapConfig = json("{}");
+
+ assertEquals(expectedLdapConfig, servicesRootNode);
+ }
+
+ /**
+ * An ambigous ldap config that has two items in its data[] array should result in exception
+ */
+ @Test(expected = StackAdvisorException.class)
+ public void testPopulateLdapConfig_multipleConfigs() throws Exception {
+ File recommendationsDir = temp.newFolder("recommendationDir");
+ String recommendationsArtifactsLifetime = "1w";
+ int requestId = 0;
+ StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+ AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+ doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+ TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+ ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+ StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion").build();
+
+ Map<String, Object> ldapConfigData = map(
+ "authentication.ldap.primaryUrl", "localhost:33389",
+ "authentication.ldap.secondaryUrl", "localhost:333",
+ "authentication.ldap.baseDn", "c=ambari,dc=apache,dc=org"
+ );
+
+ Map<String, Object> storedLdapConfigResult = map(
+ "items",
+ list(
+ map(
+ "AmbariConfiguration",
+ map(
+ "data",
+ list(ldapConfigData, ldapConfigData)
+ )
+ )
+ )
+ );
+
+ Response response =
+ Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+ doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+ JsonNode servicesRootNode = json("{}");
+ command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+ }
+
+ /**
+ * An if multiple ambari configurations are stored with 'ldap-config' type, an
+ * exception should be thrown
+ */
+ @Test(expected = StackAdvisorException.class)
+ public void testPopulateLdapConfig_multipleResults() throws Exception {
+ File recommendationsDir = temp.newFolder("recommendationDir");
+ String recommendationsArtifactsLifetime = "1w";
+ int requestId = 0;
+ StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class);
+ AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class);
+ doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString());
+ TestStackAdvisorCommand command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime,
+ ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo));
+
+ StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion")
+ .build();
+
+ Map<String, Object> ldapConfig = map(
+ "AmbariConfiguration",
+ map(
+ "data",
+ list(
+ map(
+ "authentication.ldap.primaryUrl", "localhost:33389",
+ "authentication.ldap.secondaryUrl", "localhost:333",
+ "authentication.ldap.baseDn", "c=ambari,dc=apache,dc=org"
+ )
+ )
+ )
+ );
+
+ Map<String, Object> storedLdapConfigResult = map(
+ "items",
+ list(ldapConfig, ldapConfig)
+ );
+
+ Response response =
+ Response.status(ResultStatus.STATUS.OK.getStatus()).entity(jsonString(storedLdapConfigResult)).build();
+
+ doReturn(response).when(command).handleRequest(any(), any(), any(), any(), any(), any());
+
+ JsonNode servicesRootNode = json("{}");
+ command.populateLdapConfiguration((ObjectNode)servicesRootNode);
+ }
+
+ private static String jsonString(Object obj) throws IOException {
+ return new ObjectMapper().writeValueAsString(obj);
+ }
+
+ private static JsonNode json(Object obj) throws IOException {
+ return new ObjectMapper().convertValue(obj, JsonNode.class);
+ }
+
+ private static JsonNode json(String jsonString) throws IOException {
+ return new ObjectMapper().readTree(jsonString);
+ }
+
+ private static List<Object> list(Object... items) {
+ return Lists.newArrayList(items);
+ }
+
+ private static Map<String, Object> map(Object... keysAndValues) {
+ Map<String, Object> map = new HashMap<>();
+ Iterator<Object> iterator = Arrays.asList(keysAndValues).iterator();
+ while (iterator.hasNext()) {
+ map.put(iterator.next().toString(), iterator.next());
+ }
+ return map;
+ }
+
class TestStackAdvisorCommand extends StackAdvisorCommand<TestResource> {
public TestStackAdvisorCommand(File recommendationsDir, String recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType serviceAdvisorType,
int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) {
@@ -290,6 +494,14 @@ public class StackAdvisorCommandTest {
protected TestResource updateResponse(StackAdvisorRequest request, TestResource response) {
return response;
}
+
+ // Overridden to ensure visiblity in tests
+ @Override
+ public javax.ws.rs.core.Response handleRequest(HttpHeaders headers, String body,
+ UriInfo uriInfo, Request.Type requestType,
+ MediaType mediaType, ResourceInstance resource) {
+ return super.handleRequest(headers, body, uriInfo, requestType, mediaType, resource);
+ }
}
public static class TestResource extends StackAdvisorResponse {
http://git-wip-us.apache.org/repos/asf/ambari/blob/a7757b22/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
index ab60948..05232ea 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/StackAdvisorResourceProviderTest.java
@@ -27,43 +27,35 @@ import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.List;
import java.util.Map;
import java.util.Set;
+import javax.annotation.Nonnull;
+
import org.apache.ambari.server.controller.AmbariManagementController;
import org.apache.ambari.server.controller.spi.Request;
import org.apache.ambari.server.controller.spi.Resource;
import org.junit.Assert;
+import org.junit.Before;
import org.junit.Test;
+import com.google.common.collect.Lists;
+
public class StackAdvisorResourceProviderTest {
+ private RecommendationResourceProvider provider;
+
@Test
public void testCalculateConfigurations() throws Exception {
-
- Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
- Set<String> propertyIds = Collections.emptySet();
- AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
- RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
- keyPropertyIds, ambariManagementController);
-
- Request request = mock(Request.class);
- Set<Map<String, Object>> propertiesSet = new HashSet<>();
- Map<String, Object> propertiesMap = new HashMap<>();
- propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string");
- List<Object> array = new ArrayList<>();
- array.add("array1");
- array.add("array2");
- propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", array);
- propertiesSet.add(propertiesMap);
-
- doReturn(propertiesSet).when(request).getProperties();
+ Request request = createMockRequest(
+ CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string",
+ CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", Lists.newArrayList("array1", "array2"));
Map<String, Map<String, Map<String, String>>> calculatedConfigurations = provider.calculateConfigurations(request);
@@ -79,27 +71,37 @@ public class StackAdvisorResourceProviderTest {
assertEquals("[array1, array2]", properties.get("array_prop"));
}
- @Test
- public void testReadUserContext() throws Exception {
-
+ @Nonnull
+ private RecommendationResourceProvider createRecommendationResourceProvider() {
Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
Set<String> propertyIds = Collections.emptySet();
AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
- RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
- keyPropertyIds, ambariManagementController);
+ return new RecommendationResourceProvider(propertyIds,
+ keyPropertyIds, ambariManagementController);
+ }
+ @Nonnull
+ private Request createMockRequest(Object... propertyKeysAndValues) {
Request request = mock(Request.class);
Set<Map<String, Object>> propertiesSet = new HashSet<>();
Map<String, Object> propertiesMap = new HashMap<>();
- propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string");
- List<Object> array = new ArrayList<>();
- array.add("array1");
- array.add("array2");
- propertiesMap.put(USER_CONTEXT_OPERATION_PROPERTY, "op1");
- propertiesMap.put(USER_CONTEXT_OPERATION_DETAILS_PROPERTY, "op_det");
+ Iterator<Object> it = Arrays.asList(propertyKeysAndValues).iterator();
+ while(it.hasNext()) {
+ String key = (String)it.next();
+ Object value = it.next();
+ propertiesMap.put(key, value);
+ }
propertiesSet.add(propertiesMap);
-
doReturn(propertiesSet).when(request).getProperties();
+ return request;
+ }
+
+ @Test
+ public void testReadUserContext() throws Exception {
+ Request request = createMockRequest(
+ CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", "string",
+ USER_CONTEXT_OPERATION_PROPERTY, "op1",
+ USER_CONTEXT_OPERATION_DETAILS_PROPERTY, "op_det");
Map<String, String> userContext = provider.readUserContext(request);
@@ -111,24 +113,9 @@ public class StackAdvisorResourceProviderTest {
@Test
public void testCalculateConfigurationsWithNullPropertyValues() throws Exception {
-
- Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
- Set<String> propertyIds = Collections.emptySet();
- AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
- RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
- keyPropertyIds, ambariManagementController);
-
- Request request = mock(Request.class);
- Set<Map<String, Object>> propertiesSet = new HashSet<>();
- Map<String, Object> propertiesMap = new HashMap<>();
- propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", null); //null value means no value specified for the property
- List<Object> array = new ArrayList<>();
- array.add("array1");
- array.add("array2");
- propertiesMap.put(CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", array);
- propertiesSet.add(propertiesMap);
-
- doReturn(propertiesSet).when(request).getProperties();
+ Request request = createMockRequest(
+ CONFIGURATIONS_PROPERTY_ID + "site/properties/string_prop", null,
+ CONFIGURATIONS_PROPERTY_ID + "site/properties/array_prop", Lists.newArrayList("array1", "array2"));
Map<String, Map<String, Map<String, String>>> calculatedConfigurations = provider.calculateConfigurations(request);
@@ -142,19 +129,18 @@ public class StackAdvisorResourceProviderTest {
assertEquals("[array1, array2]", properties.get("array_prop"));
-
// config properties with null values should be ignored
assertFalse(properties.containsKey("string_prop"));
-
}
+
@Test
public void testStackAdvisorWithEmptyHosts() {
Map<Resource.Type, String> keyPropertyIds = Collections.emptyMap();
Set<String> propertyIds = Collections.emptySet();
AmbariManagementController ambariManagementController = mock(AmbariManagementController.class);
RecommendationResourceProvider provider = new RecommendationResourceProvider(propertyIds,
- keyPropertyIds, ambariManagementController);
+ keyPropertyIds, ambariManagementController);
Request request = mock(Request.class);
Set<Map<String, Object>> propertiesSet = new HashSet<>();
@@ -170,4 +156,9 @@ public class StackAdvisorResourceProviderTest {
} catch (Exception e) {
}
}
+
+ @Before
+ public void init() {
+ provider = createRecommendationResourceProvider();
+ }
}
[28/38] ambari git commit: AMBARI-21307 Draft skimplementation for
the user related ldap config attribute validation
Posted by lp...@apache.org.
AMBARI-21307 Draft skimplementation for the user related ldap config attribute validation
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/43dbbc95
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/43dbbc95
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/43dbbc95
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 43dbbc9594cc9fbd61a1152556d8c896ef21ca76
Parents: 642b578
Author: lpuskas <lp...@apache.org>
Authored: Tue Jul 18 17:48:07 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:30 2017 +0200
----------------------------------------------------------------------
ambari-project/pom.xml | 1 +
ambari-server/pom.xml | 7 +-
.../AmbariConfigurationRequestSwagger.java | 1 -
.../services/ldap/AmbariConfigurationDTO.java | 67 +++++++
.../ldap/LdapCheckConfigurationRequest.java | 47 +++++
.../api/services/ldap/LdapOperationRequest.java | 18 ++
.../api/services/ldap/LdapRequestInfo.java | 61 +++++++
.../api/services/ldap/LdapRestService.java | 132 ++++++++++++++
.../ambari/server/controller/AmbariServer.java | 3 +-
.../server/controller/ControllerModule.java | 1 +
.../server/ldap/AmbariLdapConfiguration.java | 129 ++++++++++++++
.../server/ldap/LdapConfigurationFactory.java | 21 +++
.../ldap/LdapConfigurationValidatorService.java | 52 ++++++
.../apache/ambari/server/ldap/LdapModule.java | 37 ++++
.../ldap/service/AmbariLdapException.java | 33 ++++
.../server/ldap/service/AmbariLdapFacade.java | 107 +++++++++++
.../ambari/server/ldap/service/LdapFacade.java | 52 ++++++
.../server/ldap/service/LdapSearchService.java | 18 ++
.../ad/AdLdapConfigurationValidatorService.java | 177 +++++++++++++++++++
.../service/ad/LdapConfigurationConverter.java | 50 ++++++
.../api/services/ldap/LDAPServiceTest.java | 85 +++++++++
...AdLdapConfigurationValidatorServiceTest.java | 129 ++++++++++++++
22 files changed, 1224 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-project/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml
index 00ba1bc..e4d4423 100644
--- a/ambari-project/pom.xml
+++ b/ambari-project/pom.xml
@@ -31,6 +31,7 @@
<ambari.dir>${project.parent.basedir}</ambari.dir>
<powermock.version>1.6.3</powermock.version>
<jetty.version>8.1.19.v20160209</jetty.version>
+ <ldap-api.version>1.0.0</ldap-api.version>
<checkstyle.version>6.19</checkstyle.version> <!-- last version that does not require Java 8 -->
<swagger.version>1.5.10</swagger.version>
<swagger.maven.plugin.version>3.1.4</swagger.maven.plugin.version>
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml
index 29a820a..c0f30be 100644
--- a/ambari-server/pom.xml
+++ b/ambari-server/pom.xml
@@ -1287,7 +1287,6 @@
<dependency>
<groupId>org.apache.directory.shared</groupId>
<artifactId>shared-ldap</artifactId>
- <scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
@@ -1686,8 +1685,12 @@
<artifactId>jna</artifactId>
<version>4.2.2</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.directory.api</groupId>
+ <artifactId>api-all</artifactId>
+ <version>${ldap-api.version}</version>
+ </dependency>
</dependencies>
-
<pluginRepositories>
<pluginRepository>
<id>oss.sonatype.org</id>
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/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
index d6714f9..5e8094e 100644
--- 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
@@ -16,7 +16,6 @@ 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;
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java
new file mode 100644
index 0000000..1b134fe
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/AmbariConfigurationDTO.java
@@ -0,0 +1,67 @@
+/*
+ * 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.Collections;
+import java.util.Map;
+import java.util.Set;
+
+public class AmbariConfigurationDTO {
+ private String type;
+ private Set<Map<String, Object>> data = Collections.emptySet();
+ private String versionTag;
+ private Integer version;
+ private long createdTs;
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Set<Map<String, Object>> getData() {
+ return data;
+ }
+
+ public void setData(Set<Map<String, Object>> data) {
+ this.data = data;
+ }
+
+ public String getVersionTag() {
+ return versionTag;
+ }
+
+ public void setVersionTag(String versionTag) {
+ this.versionTag = versionTag;
+ }
+
+ public Integer getVersion() {
+ return version;
+ }
+
+ public void setVersion(Integer version) {
+ this.version = version;
+ }
+
+ public long getCreatedTs() {
+ return createdTs;
+ }
+
+ public void setCreatedTs(long createdTs) {
+ this.createdTs = createdTs;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java
new file mode 100644
index 0000000..188f1b9
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapCheckConfigurationRequest.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+public class LdapCheckConfigurationRequest implements LdapOperationRequest {
+
+ @SerializedName("AmbariConfiguration")
+ private AmbariConfigurationDTO ambariConfiguration;
+
+ @SerializedName("RequestInfo")
+ private LdapRequestInfo requestInfo;
+
+ public LdapCheckConfigurationRequest() {
+ }
+
+
+ public AmbariConfigurationDTO getAmbariConfiguration() {
+ return ambariConfiguration;
+ }
+
+ public void setAmbariConfiguration(AmbariConfigurationDTO 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/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java
new file mode 100644
index 0000000..06f6c40
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapOperationRequest.java
@@ -0,0 +1,18 @@
+/*
+ * 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;
+
+public interface LdapOperationRequest {
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/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
new file mode 100644
index 0000000..eeecfee
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRequestInfo.java
@@ -0,0 +1,61 @@
+/*
+ * 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/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
new file mode 100644
index 0000000..33b10fa
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/ldap/LdapRestService.java
@@ -0,0 +1,132 @@
+/*
+ * 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 javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+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.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationFactory;
+import org.apache.ambari.server.ldap.service.LdapFacade;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Endpoint designated to LDAP specific operations.
+ */
+@StaticallyInject
+@Path("/ldap")
+public class LdapRestService extends BaseService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LdapRestService.class);
+
+ @Inject
+ private static LdapFacade ldapFacade;
+
+ @Inject
+ private static LdapConfigurationFactory ldapConfigurationFactory;
+
+ @POST
+ @ApiIgnore // until documented
+ @Path("/action") // todo this needs to be moved under the resource
+ @Consumes(MediaType.APPLICATION_JSON)
+ public Response validateConfiguration(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+
+ Result result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.OK));
+ try {
+
+ validateRequest(ldapCheckConfigurationRequest);
+
+ AmbariLdapConfiguration ambariLdapConfiguration = ldapConfigurationFactory.createLdapConfiguration(
+ ldapCheckConfigurationRequest.getAmbariConfiguration().getData().iterator().next());
+
+ switch (ldapCheckConfigurationRequest.getRequestInfo().getAction()) {
+ case "test-connection":
+
+ LOGGER.info("Testing connection to the LDAP server ...");
+ ldapFacade.checkConnection(ambariLdapConfiguration);
+
+ break;
+ case "test-attributes":
+
+ LOGGER.info("Testing LDAP attributes ....");
+ ldapFacade.checkLdapAttibutes(ldapCheckConfigurationRequest.getRequestInfo().getParameters(), ambariLdapConfiguration);
+
+ break;
+ case "detect-attributes":
+
+ LOGGER.info("Detecting LDAP attributes ...");
+ ldapFacade.detectAttributes(ambariLdapConfiguration);
+
+ break;
+ default:
+ LOGGER.warn("No action provided ...");
+ throw new IllegalArgumentException("No request action provided");
+ }
+
+ } catch (Exception e) {
+ result = new ResultImpl(new ResultStatus(ResultStatus.STATUS.BAD_REQUEST, e));
+ }
+
+ return Response.status(result.getStatus().getStatusCode()).entity(getResultSerializer().serialize(result)).build();
+ }
+
+ private void validateRequest(LdapCheckConfigurationRequest ldapCheckConfigurationRequest) {
+ String errMsg;
+
+ if (null == ldapCheckConfigurationRequest) {
+ errMsg = "No ldap configuraiton request provided";
+ LOGGER.error(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ if (null == ldapCheckConfigurationRequest.getRequestInfo()) {
+ errMsg = String.format("No request information provided. Request: [%s]", ldapCheckConfigurationRequest);
+ LOGGER.error(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+
+ if (null == ldapCheckConfigurationRequest.getAmbariConfiguration()
+ || ldapCheckConfigurationRequest.getAmbariConfiguration().getData().size() != 1) {
+ errMsg = String.format("No / Invalid configuration data provided. Request: [%s]", ldapCheckConfigurationRequest);
+ LOGGER.error(errMsg);
+ throw new IllegalArgumentException(errMsg);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
index 8988be0..6ceed4a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java
@@ -77,6 +77,7 @@ import org.apache.ambari.server.controller.internal.ViewPermissionResourceProvid
import org.apache.ambari.server.controller.metrics.ThreadPoolEnabledPropertyProvider;
import org.apache.ambari.server.controller.utilities.KerberosChecker;
import org.apache.ambari.server.controller.utilities.KerberosIdentityCleaner;
+import org.apache.ambari.server.ldap.LdapModule;
import org.apache.ambari.server.metrics.system.MetricsService;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.PersistenceType;
@@ -1061,7 +1062,7 @@ public class AmbariServer {
public static void main(String[] args) throws Exception {
logStartup();
- Injector injector = Guice.createInjector(new ControllerModule(), new AuditLoggerModule());
+ Injector injector = Guice.createInjector(new ControllerModule(), new AuditLoggerModule(), new LdapModule());
AmbariServer server = null;
try {
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/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 edabcdb..bf790a7 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
@@ -504,6 +504,7 @@ public class ControllerModule extends AbstractModule {
install(new FactoryModuleBuilder().implement(CollectionPersisterService.class, CsvFilePersisterService.class).build(CollectionPersisterServiceFactory.class));
install(new FactoryModuleBuilder().build(ConfigureClusterTaskFactory.class));
+
}
/**
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
new file mode 100644
index 0000000..519f400
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -0,0 +1,129 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.inject.assistedinject.Assisted;
+
+/**
+ * This class is an immutable representation of all the LDAP related configurationMap entries.
+ */
+@Singleton
+public class AmbariLdapConfiguration {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AmbariLdapConfiguration.class);
+
+ /**
+ * Constants representing supported LDAP related property names
+ */
+ public enum LdapConfigProperty {
+ LDAP_CONFIGURED("ambari.ldap.configured"),
+ AUTOMATIC_ATTRIBUTE_DETECTION("ambari.ldap.automatic.attribute.detection"),
+
+ USE_SSL("ambari.ldap.usessl"),
+ LDAP_SERVER_HOST("ambari.ldap.server.host"),
+ LDAP_SERVER_PORT("ambari.ldap.server.port"),
+ BASE_DN("ambari.ldap.base.dn"),
+
+ BIND_ANONIMOUSLY("ambari.ldap.bindanonymously"),
+ MANAGER_DN("ambari.ldap.managerdn"),
+ MANAGER_PASSWORD("ambari.ldap.managerpassword"),
+ USER_OBJECT_CLASS("ambari.ldap.user.object.class"),
+ USER_NAME_ATTRIBUTE("ambari.ldap.user.name.attribute"),
+ USER_SEARCH_BASE("ambari.ldap.user.search.Base"),
+
+ GROUP_OBJECT_CLASS("ambari.ldap.group.object.class"),
+ GROUP_NAME_ATTRIBUTE("ambari.ldap.group.name.attribute"),
+ GROUP_MEMBER_ATTRIBUTE("ambari.ldap.group.member.attribute"),
+ GROUP_SEARCH_BASE("ambari.ldap.group.member.attribute"),
+ DN_ATTRIBUTE("authentication.ldap.dnAttribute");
+
+ private String propertyName;
+
+ LdapConfigProperty(String propertyName) {
+ this.propertyName = propertyName;
+ }
+
+ public String propertyName() {
+ return this.propertyName;
+ }
+ }
+
+ private final Map<String, Object> configurationMap;
+
+ private Object configurationValue(LdapConfigProperty ldapConfigProperty) {
+ Object value = null;
+ if (configurationMap.containsKey(ldapConfigProperty.propertyName)) {
+ value = configurationMap.get(ldapConfigProperty.propertyName);
+ } else {
+ LOGGER.warn("Ldap configuration property [{}] hasn't been set", ldapConfigProperty.propertyName());
+ }
+
+ return value;
+ }
+
+ @Inject
+ public AmbariLdapConfiguration(@Assisted Map<String, Object> configuration) {
+ this.configurationMap = configuration;
+ }
+
+
+ public String ldapServerHost() {
+ return (String) configurationValue(LdapConfigProperty.LDAP_SERVER_HOST);
+ }
+
+ public int ldapServerPort() {
+ return Integer.valueOf((String) configurationValue(LdapConfigProperty.LDAP_SERVER_PORT));
+ }
+
+ public boolean useSSL() {
+ return Boolean.valueOf((String) configurationValue(LdapConfigProperty.USE_SSL));
+ }
+
+ public boolean bindAnonimously() {
+ return Boolean.valueOf((String) configurationValue(LdapConfigProperty.BIND_ANONIMOUSLY));
+ }
+
+ public String managerDn() {
+ return (String) configurationValue(LdapConfigProperty.MANAGER_DN);
+ }
+
+ public String managerPassword() {
+ return (String) configurationValue(LdapConfigProperty.MANAGER_PASSWORD);
+ }
+
+ public boolean automaticAttributeDetection() {
+ return Boolean.valueOf((String) configurationValue(LdapConfigProperty.AUTOMATIC_ATTRIBUTE_DETECTION));
+ }
+
+ public String baseDn() {
+ return (String) configurationValue(LdapConfigProperty.BASE_DN);
+ }
+
+ public String userObjectClass() {
+ return (String) configurationValue(LdapConfigProperty.USER_OBJECT_CLASS);
+ }
+
+ public String userNameAttribute() {
+ return (String) configurationValue(LdapConfigProperty.USER_NAME_ATTRIBUTE);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
new file mode 100644
index 0000000..bcd6e39
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationFactory.java
@@ -0,0 +1,21 @@
+/*
+ * 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;
+
+import java.util.Map;
+
+public interface LdapConfigurationFactory {
+ AmbariLdapConfiguration createLdapConfiguration(Map<String, Object> configuration);
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
new file mode 100644
index 0000000..4667721
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapConfigurationValidatorService.java
@@ -0,0 +1,52 @@
+/*
+ * 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;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+
+/**
+ * Collection of operations for validating ldap configuration.
+ * It's intended to decouple implementations using different libraries.
+ */
+public interface LdapConfigurationValidatorService {
+
+ /**
+ * Tests the connection based on the provided configuration.
+ *
+ * @param configuration the ambari ldap configuration instance
+ * @throws AmbariLdapException if the connection is not possible
+ */
+ void checkConnection(AmbariLdapConfiguration configuration) throws AmbariLdapException;
+
+ /**
+ * Checks whether the group related LDAP attributes in the configuration are correct.
+ *
+ * @param configuration the configuration instance holding the available properties
+ * @throws AmbariException if the attributes are not valid
+ */
+ void checkGroupAttributes(AmbariLdapConfiguration configuration) throws AmbariException;
+
+ /**
+ * Tries to connect to the LDAP server with the given credentials.
+ * Primarily used for testing the user before performing other operations (eg. attribute detection)s
+ *
+ * @param username the username
+ * @param password the password
+ * @param configuration the available ldap configuration
+ * @throws AmbariException if the connection couldn't be estabilished
+ */
+ void checkUserAttributes(String username, String password, AmbariLdapConfiguration configuration) throws AmbariException;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/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
new file mode 100644
index 0000000..625ce8b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/LdapModule.java
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+import org.apache.ambari.server.ldap.service.AmbariLdapFacade;
+import org.apache.ambari.server.ldap.service.LdapFacade;
+import org.apache.ambari.server.ldap.service.ad.AdLdapConfigurationValidatorService;
+
+import com.google.inject.AbstractModule;
+import com.google.inject.assistedinject.FactoryModuleBuilder;
+
+/**
+ * GUICE configuration module for setting up LDAP related infrastructure.
+ */
+public class LdapModule extends AbstractModule {
+
+ @Override
+ protected void configure() {
+ bind(LdapFacade.class).to(AmbariLdapFacade.class);
+ bind(LdapConfigurationValidatorService.class).to(AdLdapConfigurationValidatorService.class);
+
+ install(new FactoryModuleBuilder().build(LdapConfigurationFactory.class));
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapException.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapException.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapException.java
new file mode 100644
index 0000000..cb38acc
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapException.java
@@ -0,0 +1,33 @@
+/*
+ * 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.service;
+
+public class AmbariLdapException extends Exception {
+ public AmbariLdapException() {
+ super();
+ }
+
+ public AmbariLdapException(String message) {
+ super(message);
+ }
+
+ public AmbariLdapException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public AmbariLdapException(Throwable cause) {
+ super(cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
new file mode 100644
index 0000000..abd028a
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -0,0 +1,107 @@
+/*
+ * 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.service;
+
+import java.util.Map;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class AmbariLdapFacade implements LdapFacade {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AmbariLdapFacade.class);
+
+ private enum Parameters {
+ TEST_USER_NAME("ldap.test.user.name"),
+ TEST_USER_PASSWORD("ldap.test.user.password");
+
+ private String parameterKey;
+
+ Parameters(String parameterKey) {
+ this.parameterKey = parameterKey;
+ }
+
+ private String getParameterKey() {
+ return parameterKey;
+ }
+
+ }
+
+ @Inject
+ private LdapConfigurationValidatorService ldapConfigurationValidatorService;
+
+ @Inject
+ public AmbariLdapFacade() {
+ }
+
+ @Override
+ public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException {
+ try {
+ LOGGER.info("Validating LDAP connection related configuration based on: {}", ambariLdapConfiguration);
+ ldapConfigurationValidatorService.checkConnection(ambariLdapConfiguration);
+ } catch (AmbariLdapException e) {
+ LOGGER.error("Validating LDAP connection configuration failed", e);
+ throw new AmbariException("Validating LDAP connection configuration failed", e);
+ }
+ LOGGER.info("Validating LDAP connection related configuration: SUCCESS");
+ }
+
+
+ @Override
+ public void detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration) {
+ LOGGER.info("Detecting LDAP configuration attributes ...");
+ throw new UnsupportedOperationException("Not yet implemented");
+ }
+
+ @Override
+ public void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ldapConfiguration) throws AmbariException {
+ String userName = getTestUserNameFromParameters(parameters);
+ String testUserPass = getTestUserPasswordFromParameters(parameters);
+
+ if (null == userName) {
+ throw new IllegalArgumentException("No test user available for testing LDAP attributes");
+ }
+
+ LOGGER.info("Testing LDAP attributes with test user: {}", userName);
+ ldapConfigurationValidatorService.checkUserAttributes(userName, testUserPass, ldapConfiguration);
+ }
+
+
+ private String getTestUserNameFromParameters(Map<String, Object> parameters) {
+ return (String) parameterValue(parameters, Parameters.TEST_USER_NAME);
+ }
+
+ private String getTestUserPasswordFromParameters(Map<String, Object> parameters) {
+ return (String) parameterValue(parameters, Parameters.TEST_USER_PASSWORD);
+ }
+
+ private Object parameterValue(Map<String, Object> parameters, Parameters parameter) {
+ Object value = null;
+ if (parameters.containsKey(parameter.getParameterKey())) {
+ value = parameters.get(parameter.getParameterKey());
+ } else {
+ LOGGER.warn("Parameter [{}] is missing from parameters", parameter.getParameterKey());
+ }
+ return value;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
new file mode 100644
index 0000000..38553f0
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -0,0 +1,52 @@
+/*
+ * 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.service;
+
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+
+/**
+ * The contract defining all the operations required by the application when communicating with an arbitrary LDAP server.
+ * This interface is intended to decouple LDAP specific details from the application.
+ */
+public interface LdapFacade {
+
+ /**
+ * Tests the connection to the LDAP server based on the provided configuration.
+ *
+ * @param ambariLdapConfiguration the available ldap related configuration
+ * @throws AmbariException if the connection fails or other problems occur during the operation
+ */
+ void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException;
+
+
+ /**
+ * Runs the user and group attribute detection algorithms
+ *
+ * @param ambariLdapConfiguration
+ */
+ void detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration);
+
+ /**
+ * Checks user and group related LDAP configuration attributes in the configuration object with the help of the provided parameters
+ *
+ * @param parameters a map of property name and value pairs holding information to facilitate checking the attributes
+ * @param ambariLdapConfiguration configutration instance with available attributes
+ * @throws AmbariException if the attribute checking fails
+ */
+ void checkLdapAttibutes(Map<String, Object> parameters, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException;
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
new file mode 100644
index 0000000..f1abc8b
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapSearchService.java
@@ -0,0 +1,18 @@
+/*
+ * 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.service;
+
+public interface LdapSearchService {
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java
new file mode 100644
index 0000000..11e8655
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorService.java
@@ -0,0 +1,177 @@
+/*
+ * 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.service.ad;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.ambari.server.ldap.service.AmbariLdapException;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Lists;
+
+/**
+ * Implementation of the validation logic using the Apache Directory API.
+ */
+@Singleton
+public class AdLdapConfigurationValidatorService implements LdapConfigurationValidatorService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AdLdapConfigurationValidatorService.class);
+
+ @Inject
+ private LdapConfigurationConverter ldapConfigurationConverter;
+
+ /**
+ * Facilitating the instantiation
+ */
+ @Inject
+ public AdLdapConfigurationValidatorService() {
+ }
+
+ @Override
+ public void checkConnection(AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariLdapException {
+ try {
+ LOGGER.info("Testing the connection based on the configuration: {}", ambariLdapConfiguration);
+
+ LdapConnectionConfig connectionConfig = ldapConfigurationConverter.getLdapConnectionConfig(ambariLdapConfiguration);
+ LdapNetworkConnection connection = new LdapNetworkConnection(connectionConfig);
+
+ if (ambariLdapConfiguration.bindAnonimously()) {
+ LOGGER.debug("Binding anonimously ...");
+ connection.bind();
+ } else {
+ LOGGER.debug("Binding with manager DN and manager password ...");
+ connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
+ }
+
+ if (connection.isConnected()) {
+ LOGGER.info("Successfully connected to the LDAP server.");
+ }
+
+ connection.close();
+
+ } catch (Exception e) {
+ LOGGER.warn("Could not bind to the LDAP server base don the provided configuration ...");
+ throw new AmbariLdapException(e);
+ }
+ }
+
+
+ /**
+ * Checks the user attributes provided in the configuration instance by issuing a search for a (known) test user in the LDAP.
+ * Attributes are considered correct if there is at least one entry found.
+ *
+ * Invalid attributes are signaled by throwing an exception.
+ *
+ * @param username the username
+ * @param password the password
+ * @param ambariLdapConfiguration configuration instance holding ldap configuration details
+ * @throws AmbariException if the attributes are not valid or any errors occurs
+ */
+ @Override
+ public void checkUserAttributes(String username, String password, AmbariLdapConfiguration ambariLdapConfiguration) throws AmbariException {
+ LdapNetworkConnection connection = null;
+ SearchCursor searchCursor = null;
+ try {
+ LOGGER.info("Checking user attributes for user {} r ...", username);
+
+ LdapConnectionConfig connectionConfig = ldapConfigurationConverter.getLdapConnectionConfig(ambariLdapConfiguration);
+ connection = new LdapNetworkConnection(connectionConfig);
+
+
+ if (!ambariLdapConfiguration.bindAnonimously()) {
+ LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
+ connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
+ } else {
+ LOGGER.debug("Binding anonimously ...");
+ connection.bind();
+ }
+
+ if (!connection.isConnected()) {
+ LOGGER.error("Not connected to the LDAP server. Connection instance: {}", connection);
+ throw new IllegalStateException("The connection to the LDAP server is not alive");
+ }
+
+ // set up a filter based on the provided attributes
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), username))
+ .toString();
+
+ LOGGER.info("Searching for the user: {} using the search filter: {}", username, filter);
+ EntryCursor entryCursor = connection.search(new Dn(ambariLdapConfiguration.baseDn()), filter, SearchScope.SUBTREE);
+
+ // collecting search result entries
+ List<Entry> users = Lists.newArrayList();
+ for (Entry entry : entryCursor) {
+ users.add(entry);
+ }
+
+ // there should be at least one user found
+ if (users.isEmpty()) {
+ String msg = String.format("There are no users found using the filter: [ %s ]. Try changing the attribute values", filter);
+ LOGGER.error(msg);
+ throw new Exception(msg);
+ }
+
+ LOGGER.info("Attibute validation succeeded. Filter: {}", filter);
+
+ } catch (Exception e) {
+
+ LOGGER.error("Error while checking user attributes.");
+ throw new AmbariException("Error while checking user attributes", e);
+
+ } finally {
+
+ LOGGER.debug("Closing the connection and searchresult ...");
+
+ if (null != searchCursor) {
+ searchCursor.close();
+ }
+
+ if (null != connection) {
+ try {
+ connection.close();
+ } catch (IOException e) {
+ LOGGER.error("Exception occurred while closing the connection", e);
+ }
+ }
+
+ }
+ }
+
+ @Override
+ public void checkGroupAttributes(AmbariLdapConfiguration configuration) throws AmbariException {
+
+ }
+
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java
new file mode 100644
index 0000000..a8839f1
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ad/LdapConfigurationConverter.java
@@ -0,0 +1,50 @@
+/*
+ * 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.service.ad;
+
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Converts between ambari specific ldap types and the 3rd party ldap library
+ */
+@Singleton
+public class LdapConfigurationConverter {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(LdapConfigurationConverter.class);
+
+ /**
+ * Creates a {@link LdapConnectionConfig} instance based on the provided ambari specific configurations
+ *
+ * @param ambariAmbariLdapConfiguration
+ * @return
+ */
+ public LdapConnectionConfig getLdapConnectionConfig(AmbariLdapConfiguration ambariAmbariLdapConfiguration) {
+ LOGGER.debug("Creating a configuration instance based on the ambari configuration: {}", ambariAmbariLdapConfiguration);
+
+ LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
+ ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.ldapServerHost());
+ ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
+ ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
+
+ //todo set the other values as required
+ return ldapConnectionConfig;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
new file mode 100644
index 0000000..f20cd1f
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/ldap/LDAPServiceTest.java
@@ -0,0 +1,85 @@
+/*
+ * 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 org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.codehaus.jackson.map.ObjectMapper;
+import org.junit.Assert;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class LDAPServiceTest {
+
+ private static String JSON_STRING = "{\n" +
+ " \"AmbariConfiguration\": {\n" +
+ " \"type\": \"ldap-config\",\n" +
+ " \"data\": [{\n" +
+ " \"authentication.ldap.primaryUrl\": \"localhost:33389\",\n" +
+ " \"authentication.ldap.secondaryUrl\": \"localhost:333\",\n" +
+ " \"authentication.ldap.baseDn\": \"dc=ambari,dc=apache,dc=org\"\n" +
+ " }]\n" +
+ " }\n" +
+ "}";
+
+ @Test
+ public void testJaxRsJsonTransformation() throws Exception {
+ // GIVEN
+ ObjectMapper objectMapper = new ObjectMapper();
+
+ Gson gsonJsonProvider = new GsonBuilder().create();
+
+
+ // WHEN
+ LdapCheckConfigurationRequest ldapCheckConfigurationRequest = gsonJsonProvider.fromJson(JSON_STRING, LdapCheckConfigurationRequest.class);
+ // LdapCheckConfigurationRequest ldapCheckConfigurationRequest = objectMapper.readValue(JSON_STRING, LdapCheckConfigurationRequest.class);
+
+ // THEN
+ Assert.assertNotNull(ldapCheckConfigurationRequest);
+
+ }
+
+
+ @Test
+ public void testLdapConnection() throws Exception {
+ // GIVEN
+ LdapConnection connection = new LdapNetworkConnection("localhost", 389);
+
+ // WHEN
+ connection.bind();
+ // THEN
+
+ }
+
+
+ @Test
+ public void testLdapConnectionConfigs() throws Exception {
+ // GIVEN
+ LdapConnectionConfig config = new LdapConnectionConfig();
+ config.setLdapHost("localhost");
+ config.setLdapPort(389);
+
+ // WHEN
+ LdapConnection connection = new LdapNetworkConnection(config);
+
+ // THEN
+ connection.anonymousBind();
+
+ Assert.assertNotNull(connection);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/43dbbc95/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java
new file mode 100644
index 0000000..0f57099
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ad/AdLdapConfigurationValidatorServiceTest.java
@@ -0,0 +1,129 @@
+/*
+ * 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.service.ad;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.util.Map;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationValidatorService;
+import org.apache.directory.api.ldap.model.cursor.EntryCursor;
+import org.apache.directory.api.ldap.model.cursor.SearchCursor;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.message.Response;
+import org.apache.directory.api.ldap.model.message.SearchRequest;
+import org.apache.directory.api.ldap.model.message.SearchRequestImpl;
+import org.apache.directory.api.ldap.model.message.SearchResultEntry;
+import org.apache.directory.api.ldap.model.message.SearchScope;
+import org.apache.directory.api.ldap.model.name.Dn;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapConnectionConfig;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.apache.directory.ldap.client.api.search.FilterBuilder;
+import org.apache.directory.shared.ldap.constants.SchemaConstants;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class AdLdapConfigurationValidatorServiceTest {
+ private static final Logger LOGGER = LoggerFactory.getLogger(AdLdapConfigurationValidatorService.class);
+ private static final String TEST_USER = "Jocika10";
+
+ LdapConfigurationValidatorService ldapConfigurationValidatorService = new AdLdapConfigurationValidatorService();
+
+
+ @Test
+ public void testCheckAttributes() throws Exception {
+
+ // WHEN
+ LdapConnectionConfig config = new LdapConnectionConfig();
+ config.setLdapHost("localhost");
+ config.setLdapPort(389);
+ LdapConnection connection = new LdapNetworkConnection(config);
+
+ // THEN
+ connection.anonymousBind();
+
+
+ EntryCursor cursor = connection.search("dc=dev,dc=local", "(objectclass=*)", SearchScope.ONELEVEL);
+
+ for (Entry entry : cursor) {
+ assertNotNull(entry);
+ System.out.println(entry);
+ }
+
+ cursor.close();
+
+ }
+
+ @Test
+ public void testCheckUserAttributes() throws Exception {
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), true);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "localhost");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=dev,dc=local");
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
+
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
+
+
+ try {
+ LOGGER.info("Authenticating user {} against the LDAP server ...", TEST_USER);
+ LdapConfigurationConverter ldapConfigurationConverter = new LdapConfigurationConverter();
+
+ LdapConnectionConfig connectionConfig = ldapConfigurationConverter.getLdapConnectionConfig(ambariLdapConfiguration);
+ LdapNetworkConnection connection = new LdapNetworkConnection(connectionConfig);
+
+ String filter = FilterBuilder.and(
+ FilterBuilder.equal(SchemaConstants.OBJECT_CLASS_AT, ambariLdapConfiguration.userObjectClass()),
+ FilterBuilder.equal(ambariLdapConfiguration.userNameAttribute(), TEST_USER))
+ .toString();
+
+ SearchRequest searchRequest = new SearchRequestImpl();
+ searchRequest.setBase(new Dn(ambariLdapConfiguration.baseDn()));
+ searchRequest.setFilter(filter);
+ searchRequest.setScope(SearchScope.SUBTREE);
+
+ LOGGER.info("loking up user: {} based on the filtr: {}", TEST_USER, filter);
+
+ connection.bind();
+ SearchCursor searchCursor = connection.search(searchRequest);
+
+ while (searchCursor.next()) {
+ Response response = searchCursor.get();
+
+ // process the SearchResultEntry
+ if (response instanceof SearchResultEntry) {
+ Entry resultEntry = ((SearchResultEntry) response).getEntry();
+ System.out.println(resultEntry);
+ }
+ }
+
+ searchCursor.close();
+
+ } catch (Exception e) {
+ throw new AmbariException("Error during user authentication check", e);
+ }
+
+ }
+
+}
\ No newline at end of file
[36/38] ambari git commit: AMBARI-21307 Added the supported ldap
properties to the code. Refactored existing code relying on these properties
Posted by lp...@apache.org.
AMBARI-21307 Added the supported ldap properties to the code. Refactored existing code relying on these properties
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/e4a80b18
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/e4a80b18
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/e4a80b18
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: e4a80b18b02f4b8ce0f0d19be1629fc19219cf7a
Parents: 2750e62
Author: lpuskas <lp...@apache.org>
Authored: Fri Sep 8 13:57:25 2017 +0300
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:32 2017 +0200
----------------------------------------------------------------------
.../server/ldap/AmbariLdapConfiguration.java | 189 ++++++++++++-------
.../AmbariLdapConfigurationProvider.java | 6 +-
.../server/ldap/service/AmbariLdapFacade.java | 10 +-
.../service/LdapAttributeDetectionService.java | 43 +++++
.../ambari/server/ldap/service/LdapFacade.java | 2 +-
.../ads/DefaultAttributeDetectionService.java | 47 +++++
.../ads/DefaultLdapConfigurationService.java | 4 +-
.../ads/DefaultLdapConnectionService.java | 4 +-
.../DefaultAttributeDetectionServiceTest.java | 102 ++++++++++
.../DefaultLdapConfigurationServiceTest.java | 30 ++-
10 files changed, 348 insertions(+), 89 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
index e913e77..76faeed 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/AmbariLdapConfiguration.java
@@ -34,63 +34,67 @@ public class AmbariLdapConfiguration {
/**
* Constants representing supported LDAP related property names
*/
- public enum LdapConfigProperty {
- LDAP_CONFIGURED("ambari.ldap.configured"),
- AUTOMATIC_ATTRIBUTE_DETECTION("ambari.ldap.automatic.attribute.detection"),
- USE_SSL("ambari.ldap.usessl"),
- LDAP_SERVER_HOST("ambari.ldap.server.host"),
- LDAP_SERVER_PORT("ambari.ldap.server.port"),
- LDAP_TRUSTSTORE("ambari.ldap.truststore"),
- LDAP_TRUSTSTORE_TYPE("ambari.ldap.truststore.type"),
- LDAP_TRUSTSTORE_PATH("ambari.ldap.truststore.path"),
- LDAP_TRUSTSTORE_PASSWORD("ambari.ldap.truststore.password"),
- BASE_DN("ambari.ldap.bind.dn"),
- REFERRAL("ambari.ldap.referral"),
- PAGINATION_ENABLED("ambari.ldap.pagination.enabled"),
-
- BIND_ANONIMOUSLY("ambari.ldap.bindanonymously"),
- MANAGER_DN("ambari.ldap.managerdn"),
- MANAGER_PASSWORD("ambari.ldap.managerpassword"),
- USER_OBJECT_CLASS("ambari.ldap.user.object.class"),
- USER_NAME_ATTRIBUTE("ambari.ldap.user.name.attribute"),
- USER_NAME_FORCE_LOWERCASE("ambari.ldap.username.force.lowercase"),
- USER_SEARCH_BASE("ambari.ldap.user.search.base"),
- SYNC_USER_MEMBER_REPLACE_PATTERN("ambari.ldap.sync.user.member.replacepattern"),
- SYNC_USER_MEMBER_FILTER("ambari.ldap.sync.user.member_filter"),
-
- ADMIN_GROUP_MAPPING_RULES ("ambari.ldap.admin.group.mappingrules"),
- GROUP_OBJECT_CLASS("ambari.ldap.group.object.class"),
- GROUP_NAME_ATTRIBUTE("ambari.ldap.group.name.attribute"),
- GROUP_MEMBER_ATTRIBUTE("ambari.ldap.group.member.attribute"),
- GROUP_SEARCH_BASE("ambari.ldap.group.search.base"),
- SYNC_GROUP_MEMBER_REPLACE_PATTERN("ambari.ldap.sync.group.member.replacepattern"),
- SYNC_GROUP_MEMBER_FILTER("ambari.ldap.sync.group.member_filter"),
- DN_ATTRIBUTE("authentication.ldap.dnAttribute"),
-
- TEST_USER_NAME("ambari.ldap.test.user.name"),
- TEST_USER_PASSWORD("ambari.ldap.test.user.password");
+ public enum AmbariLdapConfig {
+
+ 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_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.user.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;
- LdapConfigProperty(String propertyName) {
- this.propertyName = propertyName;
+ AmbariLdapConfig(String propName) {
+ this.propertyName = propName;
}
- public String propertyName() {
+ public String key() {
return this.propertyName;
}
}
private final Map<String, Object> configurationMap;
- private Object configurationValue(LdapConfigProperty ldapConfigProperty) {
+ private Object configValue(AmbariLdapConfig ambariLdapConfig) {
Object value = null;
- if (configurationMap.containsKey(ldapConfigProperty.propertyName)) {
- value = configurationMap.get(ldapConfigProperty.propertyName);
+ if (configurationMap.containsKey(ambariLdapConfig.key())) {
+ value = configurationMap.get(ambariLdapConfig.key());
} else {
- LOGGER.warn("Ldap configuration property [{}] hasn't been set", ldapConfigProperty.propertyName());
+ LOGGER.warn("Ldap configuration property [{}] hasn't been set", ambariLdapConfig.key());
}
-
return value;
}
@@ -99,65 +103,120 @@ public class AmbariLdapConfiguration {
this.configurationMap = configuration;
}
+ public boolean ldapEnabled() {
+ return Boolean.valueOf((String) configValue(AmbariLdapConfig.LDAP_ENABLED));
+ }
- public String ldapServerHost() {
- return (String) configurationValue(LdapConfigProperty.LDAP_SERVER_HOST);
+ public String serverHost() {
+ return (String) configValue(AmbariLdapConfig.SERVER_HOST);
}
- public int ldapServerPort() {
- return Integer.valueOf((String) configurationValue(LdapConfigProperty.LDAP_SERVER_PORT));
+ public int serverPort() {
+ return Integer.valueOf((String) configValue(AmbariLdapConfig.SERVER_PORT));
}
public boolean useSSL() {
- return Boolean.valueOf((String) configurationValue(LdapConfigProperty.USE_SSL));
+ return Boolean.valueOf((String) configValue(AmbariLdapConfig.USE_SSL));
+ }
+
+ public String trustStore() {
+ return (String) configValue(AmbariLdapConfig.TRUST_STORE);
+ }
+
+ public String trustStoreType() {
+ return (String) configValue(AmbariLdapConfig.TRUST_STORE_TYPE);
+ }
+
+ public String trustStorePath() {
+ return (String) configValue(AmbariLdapConfig.TRUST_STORE_PATH);
+ }
+
+ public String trustStorePassword() {
+ return (String) configValue(AmbariLdapConfig.TRUST_STORE_PASSWORD);
}
- public boolean bindAnonimously() {
- return Boolean.valueOf((String) configurationValue(LdapConfigProperty.BIND_ANONIMOUSLY));
+ public boolean anonymousBind() {
+ return Boolean.valueOf((String) configValue(AmbariLdapConfig.ANONYMOUS_BIND));
}
- public String managerDn() {
- return (String) configurationValue(LdapConfigProperty.MANAGER_DN);
+ public String bindDn() {
+ return (String) configValue(AmbariLdapConfig.BIND_DN);
}
- public String managerPassword() {
- return (String) configurationValue(LdapConfigProperty.MANAGER_PASSWORD);
+ public String bindPassword() {
+ return (String) configValue(AmbariLdapConfig.BIND_PASSWORD);
}
- public boolean automaticAttributeDetection() {
- return Boolean.valueOf((String) configurationValue(LdapConfigProperty.AUTOMATIC_ATTRIBUTE_DETECTION));
+ public String attributeDetection() {
+ return (String) configValue(AmbariLdapConfig.ATTR_DETECTION);
}
- public String baseDn() {
- return (String) configurationValue(LdapConfigProperty.BASE_DN);
+ public String dnAttribute() {
+ return (String) configValue(AmbariLdapConfig.DN_ATTRIBUTE);
}
public String userObjectClass() {
- return (String) configurationValue(LdapConfigProperty.USER_OBJECT_CLASS);
+ return (String) configValue(AmbariLdapConfig.USER_OBJECT_CLASS);
}
public String userNameAttribute() {
- return (String) configurationValue(LdapConfigProperty.USER_NAME_ATTRIBUTE);
+ return (String) configValue(AmbariLdapConfig.USER_NAME_ATTRIBUTE);
}
public String userSearchBase() {
- return (String) configurationValue(LdapConfigProperty.USER_SEARCH_BASE);
+ return (String) configValue(AmbariLdapConfig.USER_SEARCH_BASE);
}
public String groupObjectClass() {
- return (String) configurationValue(LdapConfigProperty.GROUP_OBJECT_CLASS);
+ return (String) configValue(AmbariLdapConfig.GROUP_OBJECT_CLASS);
}
public String groupNameAttribute() {
- return (String) configurationValue(LdapConfigProperty.GROUP_NAME_ATTRIBUTE);
+ return (String) configValue(AmbariLdapConfig.GROUP_NAME_ATTRIBUTE);
}
public String groupMemberAttribute() {
- return (String) configurationValue(LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE);
+ return (String) configValue(AmbariLdapConfig.GROUP_MEMBER_ATTRIBUTE);
}
public String groupSearchBase() {
- return (String) configurationValue(LdapConfigProperty.GROUP_SEARCH_BASE);
+ return (String) configValue(AmbariLdapConfig.GROUP_SEARCH_BASE);
+ }
+
+ public String userSearchFilter() {
+ return (String) configValue(AmbariLdapConfig.USER_SEARCH_FILTER);
+ }
+
+ public String userMemberReplacePattern() {
+ return (String) configValue(AmbariLdapConfig.USER_MEMBER_REPLACE_PATTERN);
+ }
+
+ public String userMemberFilter() {
+ return (String) configValue(AmbariLdapConfig.USER_MEMBER_FILTER);
+ }
+
+ public String groupSearchFilter() {
+ return (String) configValue(AmbariLdapConfig.GROUP_SEARCH_FILTER);
+ }
+
+ public String groupMemberReplacePattern() {
+ return (String) configValue(AmbariLdapConfig.GROUP_MEMBER_REPLACE_PATTERN);
+ }
+
+ public String groupMemberFilter() {
+ return (String) configValue(AmbariLdapConfig.GROUP_MEMBER_FILTER);
+ }
+
+ public boolean forceLowerCaseUserNames() {
+ return Boolean.valueOf((String) configValue(AmbariLdapConfig.FORCE_LOWERCASE_USERNAMES));
+ }
+
+ public boolean paginationEnabled() {
+ return Boolean.valueOf((String) configValue(AmbariLdapConfig.PAGINATION_ENABLED));
+ }
+
+ public String referralHandling() {
+ return (String) configValue(AmbariLdapConfig.REFERRAL_HANDLING);
}
}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
index 7f3e8a9..80ed828 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapConfigurationProvider.java
@@ -24,6 +24,7 @@ import javax.inject.Singleton;
import org.apache.ambari.server.events.AmbariLdapConfigChangedEvent;
import org.apache.ambari.server.events.publishers.AmbariEventPublisher;
import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.LdapConfigurationFactory;
import org.apache.ambari.server.orm.dao.AmbariConfigurationDAO;
import org.apache.ambari.server.orm.entities.AmbariConfigurationEntity;
import org.apache.ambari.server.security.authorization.AmbariLdapAuthenticationProvider;
@@ -55,6 +56,9 @@ public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfi
@Inject
private Provider<AmbariConfigurationDAO> ambariConfigurationDAOProvider;
+ @Inject
+ private LdapConfigurationFactory ldapConfigurationFactory;
+
private Gson gson = new GsonBuilder().create();
@Inject
@@ -95,7 +99,7 @@ public class AmbariLdapConfigurationProvider implements Provider<AmbariLdapConfi
if (configEntity != null) {
Set propertyMaps = gson.fromJson(configEntity.getConfigurationBaseEntity().getConfigurationData(), Set.class);
- instance = new AmbariLdapConfiguration((Map<String, Object>) propertyMaps.iterator().next());
+ instance = ldapConfigurationFactory.createLdapConfiguration((Map<String, Object>) propertyMaps.iterator().next());
}
LOGGER.info("Loaded LDAP configuration instance: [ {} ]", instance);
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
index 90a5ba7..16bf6b7 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/AmbariLdapFacade.java
@@ -55,6 +55,9 @@ public class AmbariLdapFacade implements LdapFacade {
@Inject
private LdapConnectionService ldapConnectionService;
+ @Inject
+ private LdapAttributeDetectionService ldapAttributeDetectionService;
+
//todo remove this, added for testing purposes only
@Inject
private Provider<AmbariLdapConfiguration> ambariLdapConfigurationProvider;
@@ -78,9 +81,12 @@ public class AmbariLdapFacade implements LdapFacade {
@Override
- public void detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration) {
+ public AmbariLdapConfiguration detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration) {
LOGGER.info("Detecting LDAP configuration attributes ...");
- LOGGER.info("LDAP config: {}", ambariLdapConfigurationProvider.get());
+
+ LdapConnection connection = ldapConnectionService.createLdapConnection(ambariLdapConfiguration);
+ ambariLdapConfiguration = ldapAttributeDetectionService.detectLdapUserAttributes(connection, ambariLdapConfiguration);
+ return ambariLdapConfiguration;
}
@Override
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
new file mode 100644
index 0000000..70a8977
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapAttributeDetectionService.java
@@ -0,0 +1,43 @@
+/*
+ * 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.service;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.directory.ldap.client.api.LdapConnection;
+
+/**
+ * Contract defining operations to detect user and group attributes.
+ */
+public interface LdapAttributeDetectionService {
+
+ /**
+ * Decorates the passed in configuration with the detected ldap user attribute values
+ *
+ * @param ldapConnection the connection instance to LDAP
+ * @param ambariLdapConfiguration configuration instance holding connection details
+ * @return the configuration decorated with user related attributes
+ */
+ AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+
+ /**
+ * Decorates the passed in configuration with the detected ldap group attribute values
+ *
+ * @param ldapConnection the connection instance to LDAP
+ * @param ambariLdapConfiguration configuration instance holding connection details
+ * @return the configuration decorated with group related attributes
+ */
+ AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection ldapConnection, AmbariLdapConfiguration ambariLdapConfiguration);
+}
+
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
index eadff7d..76b16c4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/LdapFacade.java
@@ -39,7 +39,7 @@ public interface LdapFacade {
*
* @param ambariLdapConfiguration
*/
- void detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration);
+ AmbariLdapConfiguration detectAttributes(AmbariLdapConfiguration ambariLdapConfiguration);
/**
* Checks user and group related LDAP configuration attributes in the configuration object with the help of the provided parameters
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
new file mode 100644
index 0000000..55d0765
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionService.java
@@ -0,0 +1,47 @@
+/*
+ * 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.service.ads;
+
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.LdapAttributeDetectionService;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@Singleton
+public class DefaultAttributeDetectionService implements LdapAttributeDetectionService {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAttributeDetectionService.class);
+
+ @Inject
+ public DefaultAttributeDetectionService() {
+ }
+
+ @Override
+ public AmbariLdapConfiguration detectLdapUserAttributes(LdapConnection connection, AmbariLdapConfiguration ambariLdapConfiguration) {
+ LOGGER.info("Detecting LDAP user attributes ...");
+
+ return null;
+ }
+
+ @Override
+ public AmbariLdapConfiguration detectLdapGroupAttributes(LdapConnection connection, AmbariLdapConfiguration ambariLdapConfiguration) {
+ LOGGER.info("Detecting LDAP group attributes ...");
+ return null;
+ }
+}
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
index abc9201..db8c77f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationService.java
@@ -186,9 +186,9 @@ public class DefaultLdapConfigurationService implements LdapConfigurationService
*/
private void bind(AmbariLdapConfiguration ambariLdapConfiguration, LdapConnection connection) throws LdapException {
LOGGER.info("Connecting to LDAP ....");
- if (!ambariLdapConfiguration.bindAnonimously()) {
+ if (!ambariLdapConfiguration.anonymousBind()) {
LOGGER.debug("Anonimous binding not supported, binding with the manager detailas...");
- connection.bind(ambariLdapConfiguration.managerDn(), ambariLdapConfiguration.managerPassword());
+ connection.bind(ambariLdapConfiguration.bindDn(), ambariLdapConfiguration.bindPassword());
} else {
LOGGER.debug("Binding anonimously ...");
connection.bind();
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
index ced52fc..f39df54 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConnectionService.java
@@ -52,8 +52,8 @@ public class DefaultLdapConnectionService implements LdapConnectionService {
LOGGER.debug("Creating a configuration instance based on the ambari configuration: {}", ambariAmbariLdapConfiguration);
LdapConnectionConfig ldapConnectionConfig = new LdapConnectionConfig();
- ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.ldapServerHost());
- ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.ldapServerPort());
+ ldapConnectionConfig.setLdapHost(ambariAmbariLdapConfiguration.serverHost());
+ ldapConnectionConfig.setLdapPort(ambariAmbariLdapConfiguration.serverPort());
ldapConnectionConfig.setUseSsl(ambariAmbariLdapConfiguration.useSSL());
// todo set the other values as required
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
new file mode 100644
index 0000000..5b3ac20
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultAttributeDetectionServiceTest.java
@@ -0,0 +1,102 @@
+/*
+ * 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.service.ads;
+
+
+import java.util.Map;
+
+import org.apache.ambari.server.ldap.AmbariLdapConfiguration;
+import org.apache.ambari.server.ldap.service.LdapConnectionService;
+import org.apache.directory.api.ldap.model.constants.SchemaConstants;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.ldap.client.api.LdapNetworkConnection;
+import org.easymock.EasyMockRule;
+import org.easymock.TestSubject;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.Maps;
+
+public class DefaultAttributeDetectionServiceTest {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAttributeDetectionServiceTest.class);
+
+ @Rule
+ public EasyMockRule mocks = new EasyMockRule(this);
+
+ private AmbariLdapConfiguration testLdapConfiguration;
+ private LdapConnection connection;
+
+ @TestSubject
+ private DefaultAttributeDetectionService attributeDetectionService = new DefaultAttributeDetectionService();
+
+ @Before
+ public void before() {
+
+ Map<String, Object> initialProps = Maps.newHashMap();
+ initialProps.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "");
+ testLdapConfiguration = new AmbariLdapConfiguration(initialProps);
+ }
+
+ @Test
+ public void testShouldUserNameAttributeBeDetectedWhenSearchReturnsValidUsers() throws Exception {
+ // GIVEN
+// a set of entries returned from the LDAP search
+
+ // WHEN
+ AmbariLdapConfiguration ambariLdapConfiguration = attributeDetectionService.detectLdapUserAttributes(connection, testLdapConfiguration);
+
+ // THEN
+ Assert.assertNotNull(ambariLdapConfiguration);
+ Assert.assertEquals("The username attribute is not the expected", "uid", ambariLdapConfiguration.userNameAttribute());
+
+ }
+
+
+ private Map<String, Object> getTestPropertiesMap() {
+ Map<String, Object> ldapPropsMap = Maps.newHashMap();
+
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.ANONYMOUS_BIND.key(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_HOST.key(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_PORT.key(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "dc=example,dc=com");
+
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(), SchemaConstants.UID_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_SEARCH_BASE.key(), "dc=example,dc=com");
+
+ return ldapPropsMap;
+
+ }
+
+ @Test
+ public void functionalTest() throws Exception {
+ // GIVEN
+ AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(getTestPropertiesMap());
+ LdapConnectionService connectionService = new DefaultLdapConnectionService();
+ LdapNetworkConnection ldapConnection = connectionService.createLdapConnection(ambariLdapConfiguration);
+
+
+ // WHEN
+ AmbariLdapConfiguration config = attributeDetectionService.detectLdapUserAttributes(ldapConnection, ambariLdapConfiguration);
+
+ // THEN
+
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/e4a80b18/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
index b5978a5..e023c6c 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/ldap/service/ads/DefaultLdapConfigurationServiceTest.java
@@ -74,14 +74,14 @@ public class DefaultLdapConfigurationServiceTest {
// GIVEN
Map<String, Object> ldapPropsMap = Maps.newHashMap();
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.ANONYMOUS_BIND.key(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_HOST.key(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_PORT.key(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "dc=example,dc=com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_OBJECT_CLASS.propertyName(), SchemaConstants.PERSON_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_NAME_ATTRIBUTE.propertyName(), SchemaConstants.UID_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.USER_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(), SchemaConstants.UID_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_SEARCH_BASE.key(), "dc=example,dc=com");
AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
@@ -96,16 +96,14 @@ public class DefaultLdapConfigurationServiceTest {
// GIVEN
Map<String, Object> ldapPropsMap = Maps.newHashMap();
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BIND_ANONIMOUSLY.propertyName(), "true");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_HOST.propertyName(), "ldap.forumsys.com");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.LDAP_SERVER_PORT.propertyName(), "389");
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.BASE_DN.propertyName(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.ANONYMOUS_BIND.key(), "true");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_HOST.key(), "ldap.forumsys.com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.SERVER_PORT.key(), "389");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.BIND_DN.key(), "dc=example,dc=com");
-
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_OBJECT_CLASS.propertyName(), SchemaConstants.GROUP_OF_UNIQUE_NAMES_OC);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_NAME_ATTRIBUTE.propertyName(), SchemaConstants.CN_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_MEMBER_ATTRIBUTE.propertyName(), SchemaConstants.UNIQUE_MEMBER_AT);
- ldapPropsMap.put(AmbariLdapConfiguration.LdapConfigProperty.GROUP_SEARCH_BASE.propertyName(), "dc=example,dc=com");
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_OBJECT_CLASS.key(), SchemaConstants.PERSON_OC);
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_NAME_ATTRIBUTE.key(), SchemaConstants.UID_AT);
+ ldapPropsMap.put(AmbariLdapConfiguration.AmbariLdapConfig.USER_SEARCH_BASE.key(), "dc=example,dc=com");
AmbariLdapConfiguration ambariLdapConfiguration = new AmbariLdapConfiguration(ldapPropsMap);
[14/38] ambari git commit: AMBARI-21934. All config versions for a
config group are disabled right after renaming the config group (akovalenko)
Posted by lp...@apache.org.
AMBARI-21934. All config versions for a config group are disabled right after renaming the config group (akovalenko)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/fa0ecc48
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/fa0ecc48
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/fa0ecc48
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: fa0ecc48ac68335fcce06bd41d473cfcfcfd475e
Parents: c6e19b7
Author: Aleksandr Kovalenko <ak...@hortonworks.com>
Authored: Tue Sep 12 16:07:46 2017 +0300
Committer: Aleksandr Kovalenko <ak...@hortonworks.com>
Committed: Wed Sep 13 14:15:05 2017 +0300
----------------------------------------------------------------------
.../controllers/main/service/manage_config_groups_controller.js | 4 ++--
ambari-web/app/views/common/configs/config_history_flow.js | 5 ++---
2 files changed, 4 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa0ecc48/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
index a260652..cca3d89 100644
--- a/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
+++ b/ambari-web/app/controllers/main/service/manage_config_groups_controller.js
@@ -956,8 +956,8 @@ App.ManageConfigGroupsController = Em.Controller.extend(App.ConfigOverridable, {
if (errors.length > 0) {
self.get('subViewController').set('errorMessage', errors.join(". "));
} else {
- if (!self.get('isAddService') && !self.get('isInstaller') && !modifiedConfigGroups.toCreate.everyProperty('properties.length', 0)) {
- //update service config versions only if it is service configs page and at least one newly created group had properties
+ if (!self.get('isAddService') && !self.get('isInstaller')) {
+ //update service config versions only if it is service configs page
App.router.get('mainServiceInfoConfigsController').loadServiceConfigVersions().done(function () {
self.updateConfigGroupOnServicePage();
self.hide();
http://git-wip-us.apache.org/repos/asf/ambari/blob/fa0ecc48/ambari-web/app/views/common/configs/config_history_flow.js
----------------------------------------------------------------------
diff --git a/ambari-web/app/views/common/configs/config_history_flow.js b/ambari-web/app/views/common/configs/config_history_flow.js
index 6903e8e..32a5e71 100644
--- a/ambari-web/app/views/common/configs/config_history_flow.js
+++ b/ambari-web/app/views/common/configs/config_history_flow.js
@@ -95,13 +95,12 @@ App.ConfigHistoryFlowView = Em.View.extend({
shortNotes: Em.computed.truncate('displayedServiceVersion.notes', 100, 100),
serviceVersions: function () {
- var groupName = this.get('controller.selectedConfigGroup.isDefault') ? App.ServiceConfigGroup.defaultGroupName
- : this.get('controller.selectedConfigGroup.name');
+ var isDefaultGroupSelected = this.get('controller.selectedConfigGroup.isDefault');
var groupId = this.get('controller.selectedConfigGroup.id');
var self = this;
this.get('allServiceVersions').forEach(function (version) {
- version.set('isDisabled', !(version.get('groupName') === groupName));
+ version.set('isDisabled', !(version.get('groupId') === groupId || isDefaultGroupSelected && version.get('groupName') === App.ServiceConfigGroup.defaultGroupName));
}, this);
var serviceVersions = this.get('allServiceVersions').filter(function(s) {
[23/38] 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/885761f4
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/885761f4
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/885761f4
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: 885761f439756f8ce364a7238b7550c3820b1892
Parents: a02052d
Author: lpuskas <lp...@apache.org>
Authored: Thu Jul 6 18:15:18 2017 +0200
Committer: lpuskas <la...@sequenceiq.com>
Committed: Thu Sep 14 16:37:29 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/885761f4/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/885761f4/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/885761f4/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/885761f4/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 74fff6c..5978c68 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,
@@ -1145,6 +1162,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;
@@ -1245,6 +1264,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
@@ -1446,6 +1466,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/885761f4/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 beda848..fd5f650 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/885761f4/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 4f27dfb..fd2b73d 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/885761f4/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 8550c2b..a59b4e3 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/885761f4/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 76d4441..9d6403a 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/885761f4/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 f54a232..a5a0b20 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,
@@ -1112,6 +1129,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)
@@ -1200,6 +1218,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
@@ -1405,6 +1424,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
[13/38] ambari git commit: AMBARI-21922. Allow SERVER Type Alerts To
Run For Any Service/Component - addendum: fix imports (amagyar)
Posted by lp...@apache.org.
AMBARI-21922. Allow SERVER Type Alerts To Run For Any Service/Component - addendum: fix imports (amagyar)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/c6e19b76
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/c6e19b76
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/c6e19b76
Branch: refs/heads/feature-branch-AMBARI-21307
Commit: c6e19b765e80ad7e22ec63cdd4e8004960683466
Parents: 4f6ef91
Author: Attila Magyar <am...@hortonworks.com>
Authored: Wed Sep 13 09:12:40 2017 +0200
Committer: Attila Magyar <am...@hortonworks.com>
Committed: Wed Sep 13 09:12:40 2017 +0200
----------------------------------------------------------------------
.../ambari/server/state/services/AmbariServerAlertService.java | 1 -
.../org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java | 4 ++--
2 files changed, 2 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ambari/blob/c6e19b76/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
index f5d811d..d3237a9 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/services/AmbariServerAlertService.java
@@ -30,7 +30,6 @@ import java.util.concurrent.TimeUnit;
import org.apache.ambari.server.AmbariService;
import org.apache.ambari.server.alerts.AlertRunnable;
import org.apache.ambari.server.controller.RootServiceResponseFactory.Components;
-import org.apache.ambari.server.controller.RootServiceResponseFactory.Services;
import org.apache.ambari.server.orm.dao.AlertDefinitionDAO;
import org.apache.ambari.server.orm.entities.AlertDefinitionEntity;
import org.apache.ambari.server.state.Cluster;
http://git-wip-us.apache.org/repos/asf/ambari/blob/c6e19b76/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
index d9c7957..34d415b 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/upgrade/UpgradeCatalog260Test.java
@@ -49,8 +49,6 @@ import java.util.Set;
import javax.persistence.EntityManager;
-import com.google.common.collect.Maps;
-import com.google.inject.AbstractModule;
import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.actionmanager.ActionManager;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
@@ -93,7 +91,9 @@ import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
+import com.google.common.collect.Maps;
import com.google.gson.Gson;
+import com.google.inject.AbstractModule;
import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Injector;