AMBARI-21639. When Adding a New Service the Repository ID is Required (ncole)


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

Branch: refs/heads/branch-feature-AMBARI-14714
Commit: 9e91639ba3579e3f0d9e74b8c9c42990ef59b553
Parents: ea57a6b
Author: Nate Cole <nc...@hortonworks.com>
Authored: Wed Aug 2 15:40:10 2017 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Wed Aug 2 15:40:10 2017 -0400

----------------------------------------------------------------------
 .../internal/ServiceResourceProvider.java       |  27 +++
 .../internal/ServiceResourceProviderTest.java   | 232 ++++++++++++++++++-
 2 files changed, 255 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9e91639b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
index daab1aa..89f75f3 100644
--- 
a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
+++ 
b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/ServiceResourceProvider.java
@@ -74,6 +74,7 @@ import org.apache.ambari.server.state.ServiceComponentHost;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.State;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.Validate;
 
@@ -1066,6 +1067,32 @@ public class ServiceResourceProvider extends 
AbstractControllerResourceProvider
       }
 
       Long desiredRepositoryVersion = request.getDesiredRepositoryVersionId();
+
+      if (null == desiredRepositoryVersion) {
+        Set<Long> repoIds = new HashSet<>();
+
+        for (Service service : cluster.getServices().values()) {
+          RepositoryVersionEntity serviceRepo = 
service.getDesiredRepositoryVersion();
+          if (null != serviceRepo.getParentId()) {
+            repoIds.add(serviceRepo.getParentId());
+          } else {
+            repoIds.add(serviceRepo.getId());
+          }
+        }
+
+        LOG.info("{} was not specified; the following repository ids were 
found: {}",
+            SERVICE_DESIRED_REPO_VERSION_ID_PROPERTY_ID, 
StringUtils.join(repoIds, ','));
+
+        if (CollectionUtils.isEmpty(repoIds)) {
+          throw new IllegalArgumentException("No repositories were found for 
service installation");
+        } else if (repoIds.size() > 1) {
+          throw new IllegalArgumentException(String.format("%s was not 
specified, and the cluster " +
+              "contains more than one standard-type repository", 
SERVICE_DESIRED_REPO_VERSION_ID_PROPERTY_ID));
+        } else {
+          desiredRepositoryVersion = repoIds.iterator().next();
+        }
+      }
+
       if (null == desiredRepositoryVersion) {
         throw new IllegalArgumentException(String.format("%s is required when 
adding a service.", SERVICE_DESIRED_REPO_VERSION_ID_PROPERTY_ID));
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9e91639b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
----------------------------------------------------------------------
diff --git 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
index a0c58ea..2bb7b7a 100644
--- 
a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
+++ 
b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/ServiceResourceProviderTest.java
@@ -70,6 +70,7 @@ import 
org.apache.ambari.server.serveraction.kerberos.KerberosAdminAuthenticatio
 import 
org.apache.ambari.server.serveraction.kerberos.KerberosMissingAdminCredentialsException;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
+import org.apache.ambari.server.state.RepositoryType;
 import org.apache.ambari.server.state.Service;
 import org.apache.ambari.server.state.ServiceComponent;
 import org.apache.ambari.server.state.ServiceComponentHost;
@@ -85,6 +86,8 @@ import org.junit.Test;
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 
+import com.google.common.collect.ImmutableMap;
+
 /**
  * ServiceResourceProvider tests.
  */
@@ -140,7 +143,7 @@ public class ServiceResourceProviderTest {
 
     SecurityContextHolder.getContext().setAuthentication(authentication);
 
-    ResourceProvider provider = getServiceProvider(managementController, true);
+    ResourceProvider provider = getServiceProvider(managementController, true, 
null);
 
     // add the property map to a set for the request.  add more maps for 
multiple creates
     Set<Map<String, Object>> propertySet = new LinkedHashSet<>();
@@ -1149,7 +1152,224 @@ public class ServiceResourceProviderTest {
     }
   }
 
-  private static ServiceResourceProvider 
getServiceProvider(AmbariManagementController managementController, boolean 
mockFindByStack) throws  AmbariException {
+  @Test
+  public void testCreateWithNoRepositoryId() throws Exception {
+    AmbariManagementController managementController = 
createNiceMock(AmbariManagementController.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    Service service1 = createNiceMock(Service.class);
+    Service service2 = createNiceMock(Service.class);
+
+    RepositoryVersionEntity repoVersion = 
createNiceMock(RepositoryVersionEntity.class);
+    expect(repoVersion.getId()).andReturn(500L).anyTimes();
+    
expect(service1.getDesiredRepositoryVersion()).andReturn(repoVersion).atLeastOnce();
+
+    StackId stackId = new StackId("HDP-2.5");
+    ServiceFactory serviceFactory = createNiceMock(ServiceFactory.class);
+    AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class);
+    ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
+
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    
expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
+
+    expect(cluster.addService(eq("Service200"), 
EasyMock.anyObject(RepositoryVersionEntity.class))).andReturn(service2);
+
+    expect(clusters.getCluster("Cluster100")).andReturn(cluster).anyTimes();
+
+    expect(cluster.getServices()).andReturn(
+        ImmutableMap.<String, Service>builder()
+          .put("Service100", service1).build()).atLeastOnce();
+
+    expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
+    expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+
+    expect(ambariMetaInfo.isValidService( (String) anyObject(), (String) 
anyObject(), (String) anyObject())).andReturn(true);
+    expect(ambariMetaInfo.getService((String)anyObject(), (String)anyObject(), 
(String)anyObject())).andReturn(serviceInfo).anyTimes();
+
+    // replay
+    replay(managementController, clusters, cluster, service1, service2,
+        ambariMetaInfo, serviceFactory, serviceInfo, repoVersion);
+
+    
SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+
+    Capture<Long> pkCapture = Capture.newInstance();
+    ResourceProvider provider = getServiceProvider(managementController, true, 
pkCapture);
+
+    // add the property map to a set for the request.  add more maps for 
multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<>();
+
+    // add properties to the request map
+    properties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, 
"Cluster100");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, 
"Service200");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, 
"INIT");
+    properties.put(ServiceResourceProvider.SERVICE_DESIRED_STACK_PROPERTY_ID, 
"HDP-1.1");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, clusters, cluster, service1, service2,
+        ambariMetaInfo, serviceFactory, serviceInfo);
+
+    Assert.assertTrue(pkCapture.hasCaptured());
+    Assert.assertEquals(Long.valueOf(500L), pkCapture.getValue());
+  }
+
+  @Test
+  public void testCreateWithNoRepositoryIdAndPatch() throws Exception {
+    AmbariManagementController managementController = 
createNiceMock(AmbariManagementController.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    Service service1 = createNiceMock(Service.class);
+    Service service2 = createNiceMock(Service.class);
+
+    RepositoryVersionEntity repoVersion = 
createNiceMock(RepositoryVersionEntity.class);
+    expect(repoVersion.getId()).andReturn(500L).anyTimes();
+    expect(repoVersion.getParentId()).andReturn(600L).anyTimes();
+    expect(repoVersion.getType()).andReturn(RepositoryType.PATCH).anyTimes();
+    
expect(service1.getDesiredRepositoryVersion()).andReturn(repoVersion).atLeastOnce();
+
+    StackId stackId = new StackId("HDP-2.5");
+    ServiceFactory serviceFactory = createNiceMock(ServiceFactory.class);
+    AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class);
+    ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
+
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    
expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
+
+    expect(cluster.addService(eq("Service200"), 
EasyMock.anyObject(RepositoryVersionEntity.class))).andReturn(service2);
+
+    expect(clusters.getCluster("Cluster100")).andReturn(cluster).anyTimes();
+
+    expect(cluster.getServices()).andReturn(
+        ImmutableMap.<String, Service>builder()
+          .put("Service100", service1).build()).atLeastOnce();
+
+    expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
+    expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+
+    expect(ambariMetaInfo.isValidService( (String) anyObject(), (String) 
anyObject(), (String) anyObject())).andReturn(true);
+    expect(ambariMetaInfo.getService((String)anyObject(), (String)anyObject(), 
(String)anyObject())).andReturn(serviceInfo).anyTimes();
+
+    // replay
+    replay(managementController, clusters, cluster, service1, service2,
+        ambariMetaInfo, serviceFactory, serviceInfo, repoVersion);
+
+    
SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+
+    Capture<Long> pkCapture = Capture.newInstance();
+    ResourceProvider provider = getServiceProvider(managementController, true, 
pkCapture);
+
+    // add the property map to a set for the request.  add more maps for 
multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<>();
+
+    // add properties to the request map
+    properties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, 
"Cluster100");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, 
"Service200");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, 
"INIT");
+    properties.put(ServiceResourceProvider.SERVICE_DESIRED_STACK_PROPERTY_ID, 
"HDP-1.1");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+    provider.createResources(request);
+
+    // verify
+    verify(managementController, clusters, cluster, service1, service2,
+        ambariMetaInfo, serviceFactory, serviceInfo);
+
+    Assert.assertTrue(pkCapture.hasCaptured());
+    Assert.assertEquals(Long.valueOf(600L), pkCapture.getValue());
+  }
+
+  @Test
+  public void testCreateWithNoRepositoryIdAndMultiBase() throws Exception {
+    AmbariManagementController managementController = 
createNiceMock(AmbariManagementController.class);
+    Clusters clusters = createNiceMock(Clusters.class);
+    Cluster cluster = createNiceMock(Cluster.class);
+    Service service1 = createNiceMock(Service.class);
+    Service service2 = createNiceMock(Service.class);
+    Service service3 = createNiceMock(Service.class);
+
+    RepositoryVersionEntity repoVersion1 = 
createNiceMock(RepositoryVersionEntity.class);
+    expect(repoVersion1.getId()).andReturn(500L).anyTimes();
+    
expect(service1.getDesiredRepositoryVersion()).andReturn(repoVersion1).atLeastOnce();
+
+    RepositoryVersionEntity repoVersion2 = 
createNiceMock(RepositoryVersionEntity.class);
+    expect(repoVersion2.getId()).andReturn(600L).anyTimes();
+    
expect(service2.getDesiredRepositoryVersion()).andReturn(repoVersion2).atLeastOnce();
+
+    StackId stackId = new StackId("HDP-2.5");
+    ServiceFactory serviceFactory = createNiceMock(ServiceFactory.class);
+    AmbariMetaInfo ambariMetaInfo = createNiceMock(AmbariMetaInfo.class);
+    ServiceInfo serviceInfo = createNiceMock(ServiceInfo.class);
+
+    expect(managementController.getClusters()).andReturn(clusters).anyTimes();
+    
expect(managementController.getAmbariMetaInfo()).andReturn(ambariMetaInfo).anyTimes();
+
+    expect(clusters.getCluster("Cluster100")).andReturn(cluster).anyTimes();
+
+    expect(cluster.getServices()).andReturn(
+        ImmutableMap.<String, Service>builder()
+          .put("Service100", service1)
+          .put("Service200", service2).build()).atLeastOnce();
+
+    expect(cluster.getDesiredStackVersion()).andReturn(stackId).anyTimes();
+    expect(cluster.getClusterId()).andReturn(2L).anyTimes();
+
+    // replay
+    replay(managementController, clusters, cluster, service1, service2, 
service3,
+        ambariMetaInfo, serviceFactory, serviceInfo, repoVersion1, 
repoVersion2);
+
+    
SecurityContextHolder.getContext().setAuthentication(TestAuthenticationFactory.createAdministrator());
+
+    Capture<Long> pkCapture = Capture.newInstance();
+    ResourceProvider provider = getServiceProvider(managementController, true, 
pkCapture);
+
+    // add the property map to a set for the request.  add more maps for 
multiple creates
+    Set<Map<String, Object>> propertySet = new LinkedHashSet<>();
+
+    // Service 1: create a map of properties for the request
+    Map<String, Object> properties = new LinkedHashMap<>();
+
+    // add properties to the request map
+    properties.put(ServiceResourceProvider.SERVICE_CLUSTER_NAME_PROPERTY_ID, 
"Cluster100");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_NAME_PROPERTY_ID, 
"Service200");
+    properties.put(ServiceResourceProvider.SERVICE_SERVICE_STATE_PROPERTY_ID, 
"INIT");
+    properties.put(ServiceResourceProvider.SERVICE_DESIRED_STACK_PROPERTY_ID, 
"HDP-1.1");
+
+    propertySet.add(properties);
+
+    // create the request
+    Request request = PropertyHelper.getCreateRequest(propertySet, null);
+
+    try {
+      provider.createResources(request);
+      Assert.fail("Expected an exception when more than one base version was 
found");
+    } catch (IllegalArgumentException expected) {
+      // !!! expected
+    }
+
+    // verify
+    verify(managementController, clusters, cluster, service1, service2, 
service3,
+        ambariMetaInfo, serviceFactory, serviceInfo);
+
+  }
+
+  private static ServiceResourceProvider 
getServiceProvider(AmbariManagementController managementController,
+      boolean mockFindByStack, Capture<Long> pkCapture) throws  
AmbariException {
     MaintenanceStateHelper maintenanceStateHelperMock = 
createNiceMock(MaintenanceStateHelper.class);
     RepositoryVersionDAO repositoryVersionDAO = 
createNiceMock(RepositoryVersionDAO.class);
     
expect(maintenanceStateHelperMock.isOperationAllowed(anyObject(Resource.Type.class),
 anyObject(Service.class))).andReturn(true).anyTimes();
@@ -1158,7 +1378,11 @@ public class ServiceResourceProviderTest {
     if (mockFindByStack) {
       RepositoryVersionEntity repositoryVersion = 
createNiceMock(RepositoryVersionEntity.class);
 
-      
expect(repositoryVersionDAO.findByPK(EasyMock.anyLong())).andReturn(repositoryVersion).atLeastOnce();
+      if (null != pkCapture) {
+        
expect(repositoryVersionDAO.findByPK(capture(pkCapture))).andReturn(repositoryVersion).atLeastOnce();
+      } else {
+        
expect(repositoryVersionDAO.findByPK(EasyMock.anyLong())).andReturn(repositoryVersion).atLeastOnce();
+      }
 
       expect(repositoryVersion.getStackId()).andReturn(new 
StackId("HDP-2.2")).anyTimes();
       replay(repositoryVersion);
@@ -1173,7 +1397,7 @@ public class ServiceResourceProviderTest {
    * It's useful in most cases (when we don't care about Maintenance State)
    */
   public static ServiceResourceProvider 
getServiceProvider(AmbariManagementController managementController) throws  
AmbariException {
-    return getServiceProvider(managementController, false);
+    return getServiceProvider(managementController, false, null);
   }
 
   /**

Reply via email to