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 2014/11/14 19:05:54 UTC

ambari git commit: AMBARI-8314. Repository Version Management - Add validation for created repo versions (Yurii Shylov via ncole)

Repository: ambari
Updated Branches:
  refs/heads/trunk 27c239f13 -> 692d14819


AMBARI-8314. Repository Version Management - Add validation for created repo versions (Yurii Shylov via ncole)


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

Branch: refs/heads/trunk
Commit: 692d1481924fa9fbc081c8214bf7c73cf7e94486
Parents: 27c239f
Author: Nate Cole <nc...@hortonworks.com>
Authored: Fri Nov 14 13:05:44 2014 -0500
Committer: Nate Cole <nc...@hortonworks.com>
Committed: Fri Nov 14 13:05:44 2014 -0500

----------------------------------------------------------------------
 .../RepositoryVersionResourceProvider.java      |  55 ++++++
 .../RepositoryVersionResourceProviderTest.java  | 168 ++++++++++++++++---
 2 files changed, 201 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/692d1481/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
index 502a94e..255b470 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProvider.java
@@ -23,8 +23,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.spi.NoSuchParentResourceException;
 import org.apache.ambari.server.controller.spi.NoSuchResourceException;
 import org.apache.ambari.server.controller.spi.Predicate;
@@ -40,6 +43,9 @@ import org.apache.ambari.server.orm.dao.ClusterVersionDAO;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.ClusterVersionEntity;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.state.OperatingSystemInfo;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.UpgradePack;
 
 import com.google.gson.Gson;
 import com.google.inject.Inject;
@@ -90,6 +96,9 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   @Inject
   private ClusterVersionDAO clusterVersionDAO;
 
+  @Inject
+  private AmbariMetaInfo ambariMetaInfo;
+
   /**
    * Create a new resource provider.
    *
@@ -136,6 +145,7 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
           if (repositoryVersionDAO.findByStackAndVersion(entity.getStack(), entity.getVersion()) != null) {
             throw new AmbariException("Repository version for stack " + entity.getStack() + " and version " + entity.getVersion() + " already exists");
           }
+          validateRepositoryVersion(entity);
           repositoryVersionDAO.create(entity);
           notifyCreate(Resource.Type.RepositoryVersion, request);
           return null;
@@ -281,4 +291,49 @@ public class RepositoryVersionResourceProvider extends AbstractResourceProvider
   protected Set<String> getPKPropertyIds() {
     return pkPropertyIds;
   }
+
+  /**
+   * Validates newly created repository versions to contain actual information.
+   *
+   * @param repositoryVersion repository version
+   * @throws AmbariException exception with error message
+   */
+  protected void validateRepositoryVersion(RepositoryVersionEntity repositoryVersion) throws AmbariException {
+    final StackInfo stackInfo = ambariMetaInfo.getStack(repositoryVersion.getStack(), repositoryVersion.getVersion());
+    if (stackInfo == null) {
+      throw new AmbariException("Stack " + repositoryVersion.getStack() + " " + repositoryVersion.getVersion() + " is not found");
+    }
+    final UpgradePack upgradePack = stackInfo.getUpgradePacks().get(repositoryVersion.getUpgradePackage());
+    if (upgradePack == null) {
+      throw new AmbariException("Upgrade pack " + repositoryVersion.getUpgradePackage()
+          + " is not available for stack " + repositoryVersion.getStack() + " " + repositoryVersion.getVersion());
+    }
+    final Set<String> osSupported = new HashSet<String>();
+    for (OperatingSystemInfo osInfo: ambariMetaInfo.getOperatingSystems(repositoryVersion.getStack(), repositoryVersion.getVersion())) {
+      osSupported.add(osInfo.getOsType());
+    }
+    final Set<String> osRepositoryVersion = new HashSet<String>();
+    final Matcher osMatcher = Pattern.compile("\"os\":\\s*\"(.+)\"").matcher(new Gson().fromJson(repositoryVersion.getRepositories(), Object.class).toString());
+    while (osMatcher.find()) {
+      osRepositoryVersion.add(osMatcher.group(1));
+    }
+    if (osRepositoryVersion.isEmpty()) {
+      throw new AmbariException("At least one set of repositories for OS should be provided");
+    }
+    for (String os: osRepositoryVersion) {
+      if (!osSupported.contains(os)) {
+        throw new AmbariException("Operating system type " + os + " is not supported by stack "
+            + repositoryVersion.getStack() + " " + repositoryVersion.getVersion());
+      }
+    }
+    // converting 2.2.*.* -> 2\.2\.\d+\.\d+(-\d+)?
+    String regexPattern = upgradePack.getTarget();
+    regexPattern = regexPattern.replaceAll("\\.", "\\\\.");
+    regexPattern = regexPattern.replaceAll("\\*", "\\\\d+");
+    regexPattern = regexPattern.concat("(-\\d+)?");
+    if (!Pattern.matches(regexPattern, repositoryVersion.getVersion())) {
+      throw new AmbariException("Upgrade pack " + repositoryVersion.getUpgradePackage()
+          + " can't be applied to stack " + repositoryVersion.getStack() + " " + repositoryVersion.getVersion());
+    }
+  }
 }

http://git-wip-us.apache.org/repos/asf/ambari/blob/692d1481/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
index 2debfd3..e8ce2f7 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/controller/internal/RepositoryVersionResourceProviderTest.java
@@ -18,6 +18,8 @@
 
 package org.apache.ambari.server.controller.internal;
 
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.Map;
@@ -25,6 +27,7 @@ import java.util.Set;
 
 import junit.framework.Assert;
 
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.controller.ResourceProviderFactory;
 import org.apache.ambari.server.controller.spi.Predicate;
 import org.apache.ambari.server.controller.spi.Request;
@@ -35,10 +38,19 @@ import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
 import org.apache.ambari.server.orm.dao.RepositoryVersionDAO;
 import org.apache.ambari.server.orm.entities.RepositoryVersionEntity;
+import org.apache.ambari.server.state.OperatingSystemInfo;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.stack.UpgradePack;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
 
+import com.google.common.collect.Sets;
+import com.google.gson.Gson;
+import com.google.inject.AbstractModule;
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
@@ -51,8 +63,71 @@ public class RepositoryVersionResourceProviderTest {
   private static Injector injector;
 
   @Before
-  public void before() {
-    injector = Guice.createInjector(new InMemoryDefaultTestModule());
+  public void before() throws Exception {
+    final Set<String> validVersions = Sets.newHashSet("1.1.1.1", "1.1.343432.2", "1.1.343432.2-234234324");
+    final AmbariMetaInfo ambariMetaInfo = Mockito.mock(AmbariMetaInfo.class);
+    final AbstractModule injectorModule = new InMemoryDefaultTestModule() {
+      protected void configure() {
+        super.configure();
+        bind(AmbariMetaInfo.class).toInstance(ambariMetaInfo);
+      };
+    };
+    injector = Guice.createInjector(injectorModule);
+
+    final StackInfo stackInfo = new StackInfo() {
+      @Override
+      public Map<String, UpgradePack> getUpgradePacks() {
+        final Map<String, UpgradePack> map = new HashMap<String, UpgradePack>();
+        final UpgradePack pack1 = new UpgradePack() {
+          @Override
+          public String getTarget() {
+            return "1.1.*.*";
+          }
+        };
+        final UpgradePack pack2 = new UpgradePack() {
+          @Override
+          public String getTarget() {
+            return "1.1.*.*";
+          }
+        };
+        map.put("pack1", pack1);
+        map.put("pack2", pack2);
+        return map;
+      }
+    };
+    Mockito.when(ambariMetaInfo.getStack(Mockito.anyString(), Mockito.anyString())).thenAnswer(new Answer<StackInfo>() {
+
+      @Override
+      public StackInfo answer(InvocationOnMock invocation) throws Throwable {
+        final String stack = invocation.getArguments()[0].toString();
+        final String version = invocation.getArguments()[1].toString();
+        if (stack.equals("HDP") && validVersions.contains(version)) {
+          return stackInfo;
+        } else {
+          throw new Exception("error");
+        }
+      }
+
+    });
+
+    final HashSet<OperatingSystemInfo> osInfos = new HashSet<OperatingSystemInfo>();
+    osInfos.add(new OperatingSystemInfo("redhat6"));
+    osInfos.add(new OperatingSystemInfo("redhat7"));
+    Mockito.when(ambariMetaInfo.getOperatingSystems(Mockito.anyString(), Mockito.anyString())).thenAnswer(new Answer<Set<OperatingSystemInfo>>() {
+
+      @Override
+      public Set<OperatingSystemInfo> answer(InvocationOnMock invocation)
+          throws Throwable {
+        final String stack = invocation.getArguments()[0].toString();
+        final String version = invocation.getArguments()[1].toString();
+        if (stack.equals("HDP") && validVersions.contains(version)) {
+          return osInfos;
+        } else {
+          return new HashSet<OperatingSystemInfo>();
+        }
+      }
+    });
+
     injector.getInstance(GuiceJpaInitializer.class);
   }
 
@@ -63,10 +138,10 @@ public class RepositoryVersionResourceProviderTest {
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
     final Map<String, Object> properties = new LinkedHashMap<String, Object>();
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "repositories");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "stack");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "version");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "[{\"os\":\"redhat6\"}]");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "HDP");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack1");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "1.1.1.1");
     propertySet.add(properties);
 
     final Request getRequest = PropertyHelper.getReadRequest(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID);
@@ -84,10 +159,10 @@ public class RepositoryVersionResourceProviderTest {
     final RepositoryVersionDAO repositoryVersionDAO = injector.getInstance(RepositoryVersionDAO.class);
     final RepositoryVersionEntity entity = new RepositoryVersionEntity();
     entity.setDisplayName("name");
-    entity.setRepositories("repositories");
-    entity.setStack("stack");
-    entity.setUpgradePackage("upgrade");
-    entity.setVersion("version");
+    entity.setRepositories("[{\"os\":\"redhat6\"}]");
+    entity.setStack("HDP");
+    entity.setUpgradePackage("pack1");
+    entity.setVersion("1.1.1.1");
 
     final Request getRequest = PropertyHelper.getReadRequest(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID);
     Assert.assertEquals(0, provider.getResources(getRequest, null).size());
@@ -98,16 +173,65 @@ public class RepositoryVersionResourceProviderTest {
   }
 
   @Test
+  public void testValidateRepositoryVersion() throws Exception {
+    final RepositoryVersionResourceProvider provider = (RepositoryVersionResourceProvider)
+        injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionProvider();
+
+    final RepositoryVersionEntity entity = new RepositoryVersionEntity();
+    entity.setDisplayName("name");
+    entity.setStack("HDP");
+    entity.setUpgradePackage("pack1");
+    entity.setVersion("1.1.1.1");
+    entity.setRepositories(new Gson().toJson("[{\"os\":\"redhat6\"}]"));
+
+    // test valid usecases
+    provider.validateRepositoryVersion(entity);
+    entity.setVersion("1.1.343432.2");
+    provider.validateRepositoryVersion(entity);
+    entity.setVersion("1.1.343432.2-234234324");
+    provider.validateRepositoryVersion(entity);
+
+    // test invalid usecases
+    entity.setRepositories("[{\"os\":\"redhat8\"}]");
+    try {
+      provider.validateRepositoryVersion(entity);
+      Assert.fail("Should throw exception");
+    } catch (Exception ex) {
+    }
+
+    entity.setRepositories("");
+    try {
+      provider.validateRepositoryVersion(entity);
+      Assert.fail("Should throw exception");
+    } catch (Exception ex) {
+    }
+
+    entity.setUpgradePackage("pack2");
+    try {
+      provider.validateRepositoryVersion(entity);
+      Assert.fail("Should throw exception");
+    } catch (Exception ex) {
+    }
+
+    entity.setStack("BIGTOP");
+    try {
+      provider.validateRepositoryVersion(entity);
+      Assert.fail("Should throw exception");
+    } catch (Exception ex) {
+    }
+  }
+
+  @Test
   public void testDeleteResources() throws Exception {
     final ResourceProvider provider = injector.getInstance(ResourceProviderFactory.class).getRepositoryVersionProvider();
 
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
     final Map<String, Object> properties = new LinkedHashMap<String, Object>();
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "repositories");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "stack");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "version");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "[{\"os\":\"redhat6\"}]");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "HDP");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack1");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "1.1.1.1");
     propertySet.add(properties);
 
     final Request getRequest = PropertyHelper.getReadRequest(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID);
@@ -131,10 +255,10 @@ public class RepositoryVersionResourceProviderTest {
     final Set<Map<String, Object>> propertySet = new LinkedHashSet<Map<String, Object>>();
     final Map<String, Object> properties = new LinkedHashMap<String, Object>();
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "repositories");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "stack");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "version");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "[{\"os\":\"redhat6\"}]");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_STACK_PROPERTY_ID, "HDP");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack1");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_VERSION_PROPERTY_ID, "1.1.1.1");
     propertySet.add(properties);
 
     final Request getRequest = PropertyHelper.getReadRequest(
@@ -151,14 +275,14 @@ public class RepositoryVersionResourceProviderTest {
 
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_ID_PROPERTY_ID, "1");
     properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID, "name2");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "repositories2");
-    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "upgrade2");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID, "[{\"os\":\"redhat7\"}]");
+    properties.put(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID, "pack2");
     final Request updateRequest = PropertyHelper.getUpdateRequest(properties, null);
     provider.updateResources(updateRequest, null);
 
     Assert.assertEquals("name2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_DISPLAY_NAME_PROPERTY_ID));
-    Assert.assertEquals("repositories2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID));
-    Assert.assertEquals("upgrade2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID));
+    Assert.assertEquals("[{\"os\":\"redhat7\"}]", new Gson().toJson(provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_REPOSITORIES_PROPERTY_ID)));
+    Assert.assertEquals("pack2", provider.getResources(getRequest, null).iterator().next().getPropertyValue(RepositoryVersionResourceProvider.REPOSITORY_VERSION_UPGRADE_PACK_PROPERTY_ID));
   }
 
   @After