You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by nc...@apache.org on 2016/06/09 21:13:57 UTC

ambari git commit: AMBARI-17130. Duplicate key in database exception during version registration (ncole)

Repository: ambari
Updated Branches:
  refs/heads/trunk 66decdeb2 -> 3303cdce3


AMBARI-17130. Duplicate key in database exception during version registration (ncole)


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

Branch: refs/heads/trunk
Commit: 3303cdce30259bb3b51d1c73c922721cd94308cb
Parents: 66decde
Author: Nate Cole <nc...@hortonworks.com>
Authored: Thu Jun 9 10:47:46 2016 -0400
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Thu Jun 9 17:13:43 2016 -0400

----------------------------------------------------------------------
 .../src/main/python/ambari_agent/NetUtil.py     |  2 +-
 .../VersionDefinitionResourceProvider.java      | 75 +++++++++++++----
 .../VersionDefinitionResourceProviderTest.java  | 85 ++++++++++++++++++++
 3 files changed, 146 insertions(+), 16 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/3303cdce/ambari-agent/src/main/python/ambari_agent/NetUtil.py
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/python/ambari_agent/NetUtil.py b/ambari-agent/src/main/python/ambari_agent/NetUtil.py
index 79181f1..80bf3ae 100644
--- a/ambari-agent/src/main/python/ambari_agent/NetUtil.py
+++ b/ambari-agent/src/main/python/ambari_agent/NetUtil.py
@@ -61,7 +61,7 @@ class NetUtil:
     logger.info("Connecting to " + url)
     responseBody = ""
 
-    ssl_verify_cert = self.config.get("security","ssl_verify_cert") != "0"
+    ssl_verify_cert = self.config.get("security","ssl_verify_cert", "0") != "0"
 
     try:
       parsedurl = urlparse(url)

http://git-wip-us.apache.org/repos/asf/ambari/blob/3303cdce/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
index 049c4a7..c18d722 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProvider.java
@@ -62,6 +62,7 @@ import org.apache.ambari.server.state.repository.VersionDefinitionXml;
 import org.apache.ambari.server.state.stack.upgrade.RepositoryVersionHelper;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.lang.StringUtils;
 import org.apache.commons.lang.math.NumberUtils;
 import org.codehaus.jackson.node.ArrayNode;
@@ -98,6 +99,8 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
   protected static final String VERSION_DEF_AVAILABLE_SERVICES       = "VersionDefinition/services";
   protected static final String VERSION_DEF_STACK_SERVICES           = "VersionDefinition/stack_services";
   protected static final String VERSION_DEF_STACK_DEFAULT            = "VersionDefinition/stack_default";
+  protected static final String VERSION_DEF_DISPLAY_NAME             = "VersionDefinition/display_name";
+  protected static final String VERSION_DEF_VALIDATION               = "VersionDefinition/validation";
   protected static final String SHOW_AVAILABLE                       = "VersionDefinition/show_available";
 
   public static final String SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID  = new OperatingSystemResourceDefinition().getPluralName();
@@ -146,6 +149,8 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
       VERSION_DEF_AVAILABLE_SERVICES,
       VERSION_DEF_STACK_SERVICES,
       VERSION_DEF_STACK_DEFAULT,
+      VERSION_DEF_DISPLAY_NAME,
+      VERSION_DEF_VALIDATION,
       SUBRESOURCE_OPERATING_SYSTEMS_PROPERTY_ID,
       SHOW_AVAILABLE);
 
@@ -197,14 +202,13 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
     final String definitionUrl = (String) properties.get(VERSION_DEF_DEFINITION_URL);
     final String definitionBase64 = (String) properties.get(VERSION_DEF_DEFINITION_BASE64);
     final String definitionName = (String) properties.get(VERSION_DEF_AVAILABLE_DEFINITION);
-
+    final Set<String> validations = new HashSet<>();
     final boolean dryRun = request.isDryRunRequest();
 
     XmlHolder xmlHolder = createResources(new Command<XmlHolder>() {
       @Override
       public XmlHolder invoke() throws AmbariException {
 
-
         XmlHolder holder = null;
         if (null != definitionUrl) {
           holder = loadXml(definitionUrl);
@@ -212,6 +216,7 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
           holder = loadXml(Base64.decodeBase64(definitionBase64));
         } else if (null != definitionName) {
           VersionDefinitionXml xml = s_metaInfo.get().getVersionDefinition(definitionName);
+
           if (null == xml) {
             throw new AmbariException(String.format("Version %s not found", definitionName));
           }
@@ -228,23 +233,54 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
           throw new AmbariException("Cannot determine creation method");
         }
 
+        // !!! must be in this anonymous method because things throw AmbariException
+
         toRepositoryVersionEntity(holder);
 
-        if (!dryRun) {
+        try {
           RepositoryVersionResourceProvider.validateRepositoryVersion(s_repoVersionDAO,
               s_metaInfo.get(), holder.entity);
+        } catch (AmbariException e) {
+          if (dryRun) {
+            validations.add(e.getMessage());
+          } else {
+            throw e;
+          }
         }
 
         checkForParent(holder);
 
-        if (!dryRun) {
-          s_repoVersionDAO.create(holder.entity);
-        }
-
         return holder;
       }
     });
 
+    if (StringUtils.isNotBlank(ObjectUtils.toString(properties.get(VERSION_DEF_DISPLAY_NAME)))) {
+      xmlHolder.xml.release.display = properties.get(VERSION_DEF_DISPLAY_NAME).toString();
+      xmlHolder.entity.setDisplayName(properties.get(VERSION_DEF_DISPLAY_NAME).toString());
+    }
+
+    if (s_repoVersionDAO.findByDisplayName(xmlHolder.entity.getDisplayName()) != null) {
+      String err = String.format("Repository version with name %s already exists.",
+          xmlHolder.entity.getDisplayName());
+
+      if (dryRun) {
+        validations.add(err);
+      } else {
+        throw new IllegalArgumentException(err);
+      }
+    }
+
+    if (s_repoVersionDAO.findByStackAndVersion(xmlHolder.entity.getStack(), xmlHolder.entity.getVersion()) != null) {
+      String err = String.format("Repository version for stack %s and version %s already exists.",
+              xmlHolder.entity.getStackId(), xmlHolder.entity.getVersion());
+
+      if (dryRun) {
+        validations.add(err);
+      } else {
+        throw new IllegalArgumentException(err);
+      }
+    }
+
     final Resource res;
 
     if (dryRun) {
@@ -258,10 +294,12 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
         VERSION_DEF_RELEASE_COMPATIBLE_WITH,
         VERSION_DEF_RELEASE_NOTES,
         VERSION_DEF_RELEASE_VERSION,
+        VERSION_DEF_DISPLAY_NAME,
         VERSION_DEF_AVAILABLE_SERVICES,
+        VERSION_DEF_VALIDATION,
         VERSION_DEF_STACK_SERVICES);
 
-      res = toResource(null, xmlHolder.xml, ids);
+      res = toResource(null, xmlHolder.xml, ids, validations);
       // !!! if the definition name is not null, it can only be from available
       if (null != definitionName) {
         res.setProperty(SHOW_AVAILABLE, true);
@@ -269,12 +307,14 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
 
       addSubresources(res, xmlHolder.entity);
     } else {
+
+      s_repoVersionDAO.create(xmlHolder.entity);
+
       res = toResource(xmlHolder.entity, Collections.<String>emptySet());
       notifyCreate(Resource.Type.VersionDefinition, request);
     }
 
-    RequestStatusImpl status = new RequestStatusImpl(null,
-        Collections.singleton(res));
+    RequestStatusImpl status = new RequestStatusImpl(null, Collections.singleton(res));
 
     return status;
   }
@@ -302,12 +342,10 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
             Boolean.parseBoolean(propertyMap.get(SHOW_AVAILABLE).toString())) {
 
           for (Entry<String, VersionDefinitionXml> entry : s_metaInfo.get().getVersionDefinitions().entrySet()) {
-            Resource res = toResource(entry.getKey(), entry.getValue(), requestPropertyIds);
+            Resource res = toResource(entry.getKey(), entry.getValue(), requestPropertyIds, null);
             res.setProperty(SHOW_AVAILABLE, true);
             results.add(res);
-
           }
-
         } else {
           String id = (String) propertyMap.get(VERSION_DEF_ID);
 
@@ -325,7 +363,7 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
                 throw new NoSuchResourceException(String.format("Could not find version %s",
                     id));
               }
-              Resource res = toResource(id, xml, requestPropertyIds);
+              Resource res = toResource(id, xml, requestPropertyIds, null);
               res.setProperty(SHOW_AVAILABLE, true);
               results.add(res);
             }
@@ -522,7 +560,8 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
    * @return the resource
    * @throws SystemException
    */
-  private Resource toResource(String id, VersionDefinitionXml xml, Set<String> requestedIds) throws SystemException {
+  private Resource toResource(String id, VersionDefinitionXml xml, Set<String> requestedIds,
+      Set<String> validations) throws SystemException {
 
     Resource resource = new ResourceImpl(Resource.Type.VersionDefinition);
     resource.setProperty(VERSION_DEF_ID, id);
@@ -547,6 +586,11 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
     setResourceProperty(resource, VERSION_DEF_RELEASE_NOTES, xml.release.releaseNotes, requestedIds);
     setResourceProperty(resource, VERSION_DEF_RELEASE_VERSION, xml.release.version, requestedIds);
     setResourceProperty(resource, VERSION_DEF_STACK_DEFAULT, xml.isStackDefault(), requestedIds);
+    setResourceProperty(resource, VERSION_DEF_DISPLAY_NAME, xml.release.display, requestedIds);
+
+    if (null != validations) {
+      setResourceProperty(resource, VERSION_DEF_VALIDATION, validations, requestedIds);
+    }
 
     setResourceProperty(resource, VERSION_DEF_AVAILABLE_SERVICES, xml.getAvailableServices(stack), requestedIds);
     setResourceProperty(resource, VERSION_DEF_STACK_SERVICES, xml.getStackServices(stack), requestedIds);
@@ -591,6 +635,7 @@ public class VersionDefinitionResourceProvider extends AbstractAuthorizedResourc
     setResourceProperty(resource, VERSION_DEF_RELEASE_NOTES, xml.release.releaseNotes, requestedIds);
     setResourceProperty(resource, VERSION_DEF_RELEASE_VERSION, xml.release.version, requestedIds);
     setResourceProperty(resource, VERSION_DEF_STACK_DEFAULT, xml.isStackDefault(), requestedIds);
+    setResourceProperty(resource, VERSION_DEF_DISPLAY_NAME, xml.release.display, requestedIds);
 
     StackInfo stack = null;
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/3303cdce/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java
index 75427ff..e0ff2b3 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/VersionDefinitionResourceProviderTest.java
@@ -420,10 +420,95 @@ public class VersionDefinitionResourceProviderTest {
     Assert.assertTrue(res.getPropertiesMap().containsKey("VersionDefinition"));
     Assert.assertEquals("2.2.1.0", res.getPropertyValue("VersionDefinition/repository_version"));
     Assert.assertNotNull(res.getPropertyValue("VersionDefinition/show_available"));
+    Assert.assertNotNull(res.getPropertyValue("VersionDefinition/validation"));
+
+    Set<String> validation = (Set<String>) res.getPropertyValue("VersionDefinition/validation");
+    Assert.assertNotNull(validation);
+    Assert.assertEquals(0, validation.size());
 
     getRequest = PropertyHelper.getReadRequest("VersionDefinition");
     results = versionProvider.getResources(getRequest, null);
     Assert.assertEquals(0, results.size());
+  }
+
+  @Test
+  public void testCreateDryWithValidation() throws Exception {
+    AmbariMetaInfo ami = injector.getInstance(AmbariMetaInfo.class);
+    // ensure that all of the latest repo retrieval tasks have completed
+    StackManager sm = ami.getStackManager();
+    int maxWait = 15000;
+    int waitTime = 0;
+    while (waitTime < maxWait && ! sm.haveAllRepoUrlsBeenResolved()) {
+      Thread.sleep(5);
+      waitTime += 5;
+    }
+
+    if (waitTime >= maxWait) {
+      fail("Latest Repo tasks did not complete");
+    }
+
+
+    // !!! make sure we have none
+    Authentication authentication = TestAuthenticationFactory.createAdministrator();
+    SecurityContextHolder.getContext().setAuthentication(authentication);
+
+    final ResourceProvider versionProvider = new VersionDefinitionResourceProvider();
+
+    Request getRequest = PropertyHelper.getReadRequest("VersionDefinition");
+    Set<Resource> results = versionProvider.getResources(getRequest, null);
+    Assert.assertEquals(0, results.size());
+
+
+    // !!! create one
+    Map<String, Object> createMap = new HashMap<>();
+    createMap.put("VersionDefinition/available", "HDP-2.2.0-2.2.1.0");
+
+    Request createRequest = PropertyHelper.getCreateRequest(Collections.singleton(createMap), null);
+    versionProvider.createResources(createRequest);
+
+    results = versionProvider.getResources(getRequest, null);
+    Assert.assertEquals(1, results.size());
+
+
+    // !!! create one, but a dry run to make sure we get two validation errors
+    Map<String, String> infoProps = Collections.singletonMap(Request.DIRECTIVE_DRY_RUN, "true");
+
+    createRequest = PropertyHelper.getCreateRequest(Collections.singleton(createMap), infoProps);
+    RequestStatus status = versionProvider.createResources(createRequest);
+
+    Assert.assertEquals(1, status.getAssociatedResources().size());
+
+    Resource res = status.getAssociatedResources().iterator().next();
+    // because we aren't using subresources, but return subresource-like properties, the key is an empty string
+    Assert.assertTrue(res.getPropertiesMap().containsKey(""));
+    Map<String, Object> resMap = res.getPropertiesMap().get("");
+    Assert.assertTrue(resMap.containsKey("operating_systems"));
+
+    Assert.assertTrue(res.getPropertiesMap().containsKey("VersionDefinition"));
+    Assert.assertEquals("2.2.1.0", res.getPropertyValue("VersionDefinition/repository_version"));
+    Assert.assertNotNull(res.getPropertyValue("VersionDefinition/show_available"));
+    Assert.assertEquals("HDP-2.2.0.4", res.getPropertyValue("VersionDefinition/display_name"));
+    Assert.assertNotNull(res.getPropertyValue("VersionDefinition/validation"));
+
+    Set<String> validation = (Set<String>) res.getPropertyValue("VersionDefinition/validation");
+    Assert.assertEquals(3, validation.size());
+
+    // dry-run with a changed name.  should get one validation error about version
+    createMap.put(VersionDefinitionResourceProvider.VERSION_DEF_DISPLAY_NAME, "HDP-2.2.0.4-a");
+    createRequest = PropertyHelper.getCreateRequest(Collections.singleton(createMap), infoProps);
+    status = versionProvider.createResources(createRequest);
+
+    Assert.assertEquals(1, status.getAssociatedResources().size());
+
+    res = status.getAssociatedResources().iterator().next();
+    Assert.assertTrue(res.getPropertiesMap().containsKey("VersionDefinition"));
+    Assert.assertEquals("2.2.1.0", res.getPropertyValue("VersionDefinition/repository_version"));
+    Assert.assertEquals("HDP-2.2.0.4-a", res.getPropertyValue("VersionDefinition/display_name"));
+    Assert.assertNotNull(res.getPropertyValue("VersionDefinition/show_available"));
+    Assert.assertNotNull(res.getPropertyValue("VersionDefinition/validation"));
+
+    validation = (Set<String>) res.getPropertyValue("VersionDefinition/validation");
+    Assert.assertEquals(2, validation.size());
 
   }
 }