Browse Source

AMBARI-2542. Fix custom repo URL cannot be set when non-root (ncole)

git-svn-id: https://svn.apache.org/repos/asf/incubator/ambari/trunk@1499146 13f79535-47bb-0310-9956-ffa450edef68
Nate Cole 12 years ago
parent
commit
8d0d34dbb6

+ 70 - 137
ambari-server/src/main/java/org/apache/ambari/server/api/services/AmbariMetaInfo.java

@@ -32,16 +32,13 @@ import java.util.Set;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ObjectNotFoundException;
 import org.apache.ambari.server.StackAccessException;
 import org.apache.ambari.server.configuration.Configuration;
+import org.apache.ambari.server.orm.dao.MetainfoDAO;
+import org.apache.ambari.server.orm.entities.MetainfoEntity;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.OperatingSystemInfo;
 import org.apache.ambari.server.state.PropertyInfo;
@@ -49,7 +46,6 @@ import org.apache.ambari.server.state.RepositoryInfo;
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.Stack;
 import org.apache.ambari.server.state.StackInfo;
-import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
@@ -84,7 +80,6 @@ public class AmbariMetaInfo {
   private static final String REPOSITORY_XML_ATTRIBUTE_OS_TYPE = "type";
   private static final String REPOSITORY_XML_REPO_BLOCK_NAME = "repo";
   private static final String REPOSITORY_XML_PROPERTY_BASEURL = "baseurl";
-  private static final String REPOSITORY_XML_PROPERTY_DEFAULT_BASEURL = "default_baseurl";
   private static final String REPOSITORY_XML_PROPERTY_REPOID = "repoid";
   private static final String REPOSITORY_XML_PROPERTY_REPONAME = "reponame";
   private static final String REPOSITORY_XML_PROPERTY_MIRRORSLIST = "mirrorslist";
@@ -112,6 +107,9 @@ public class AmbariMetaInfo {
   private List<StackInfo> stacksResult = new ArrayList<StackInfo>();
   private File stackRoot;
   private File serverVersionFile;
+  
+  @Inject
+  private MetainfoDAO metainfoDAO;
 
   /**
    * Ambari Meta Info Object
@@ -127,12 +125,11 @@ public class AmbariMetaInfo {
     this.serverVersionFile = new File(serverVersionFilePath);
   }
 
-  @Inject
   public AmbariMetaInfo(File stackRoot, File serverVersionFile) throws Exception {
     this.stackRoot = stackRoot;
     this.serverVersionFile = serverVersionFile;
   }
-
+  
   /**
    * Initialize the Ambari Meta Info
    *
@@ -272,125 +269,6 @@ public class AmbariMetaInfo {
     return repoResult;
   }
   
-  public synchronized void updateRepository(String stackName, String stackVersion,
-      String osType, String repoId, String baseUrl) throws AmbariException {
-    
-    // validate existing
-    RepositoryInfo ri = getRepository(stackName, stackVersion, osType, repoId);
-    
-    if (!stackRoot.exists())
-      throw new StackAccessException("Stack root does not exist.");
-    
-    String repoFileName = stackRoot.getAbsolutePath() + File.separator +
-        stackName + File.separator + stackVersion + File.separator +
-        REPOSITORY_FOLDER_NAME + File.separator + REPOSITORY_FILE_NAME;
-    
-    File repoFile = new File(repoFileName);
-    if (!repoFile.exists())
-      throw new StackAccessException("Stack repo file does not exist.");
-    
-    try {
-      // backup
-      File newFile = new File(repoFileName + "." + System.currentTimeMillis());
-      FileUtils.copyFile(repoFile, newFile, false);
-
-      // read/update/persist
-      DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
-      DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
-      Document doc = dBuilder.parse(repoFile);
-      
-      NodeList osNodes = doc.getElementsByTagName(REPOSITORY_XML_MAIN_BLOCK_NAME);
-
-      List<Node> newOsNodes = new ArrayList<Node>();
-      
-      for (int i = 0; i < osNodes.getLength(); i++) {
-        Node osNode = osNodes.item(i);
-        if (osNode.getNodeType() != Node.ELEMENT_NODE) {
-          continue;
-        }
-        
-        NamedNodeMap attrs = osNode.getAttributes();
-        Node osAttr = attrs.getNamedItem(REPOSITORY_XML_ATTRIBUTE_OS_TYPE);
-        if (osAttr == null) {
-          continue;
-        }
-        
-        String xmlOsValue = osAttr.getNodeValue();
-        
-        if (-1 == xmlOsValue.indexOf(osType)) {
-          continue;
-        }
-        
-        Node template = osNode.cloneNode(true);
-        
-        // many os'es can be defined
-        String[] allOsTypes = osAttr.getNodeValue().split(",");
-        
-        for (String xmlOsType : allOsTypes) {
-          Node newOsNode = template.cloneNode(true);
-          NamedNodeMap newAttrs = newOsNode.getAttributes();
-          Node newOsAttr = newAttrs.getNamedItem(REPOSITORY_XML_ATTRIBUTE_OS_TYPE);
-          newOsAttr.setTextContent(xmlOsType);
-
-          if (xmlOsType.equals(osType)) {
-            NodeList newOsNodeChildren = newOsNode.getChildNodes();
-            
-            for (int j = 0; j < newOsNodeChildren.getLength(); j++) {
-              Node repoNode = newOsNodeChildren.item(j);
-              if (repoNode.getNodeName().equals(REPOSITORY_XML_REPO_BLOCK_NAME)) {
-
-                Element property = (Element) repoNode;
-                String xmlRepoId = getTagValue(REPOSITORY_XML_PROPERTY_REPOID, property);
-                
-                if (xmlRepoId.equals(repoId)) {
-                  NodeList nl = property.getElementsByTagName(REPOSITORY_XML_PROPERTY_BASEURL);
-                  if (null != nl && nl.getLength() > 0) {
-                    String defaultBaseUrl = getTagValue(REPOSITORY_XML_PROPERTY_DEFAULT_BASEURL, property);
-                    if (null == defaultBaseUrl) {
-                      Node n = doc.createElement(REPOSITORY_XML_PROPERTY_DEFAULT_BASEURL);
-                      n.setTextContent(nl.item(0).getTextContent());
-                      if (null != ri)
-                        ri.setDefaultBaseUrl(nl.item(0).getTextContent());
-                      property.appendChild(n);
-                    }
-                    nl.item(0).setTextContent(baseUrl);
-                  }
-                }
-              }
-            }
-            doc.getDocumentElement().replaceChild(newOsNode, osNode);
-          } else {
-            newOsNodes.add(newOsNode);
-          }
-        }
-      }
-      
-      for (Node n : newOsNodes) {
-        doc.getDocumentElement().appendChild(n);
-      }
-
-      TransformerFactory tf = TransformerFactory.newInstance();
-      Transformer t = tf.newTransformer();
-      t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
-      t.setOutputProperty(OutputKeys.METHOD, "xml");
-      t.setOutputProperty(OutputKeys.INDENT, "yes");
-      t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
-      t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount",  "2");
-      doc.setXmlStandalone(true);
-      
-      t.transform(new DOMSource(doc), new StreamResult(repoFile));      
-    }
-    catch (Exception e) {
-      throw new AmbariException (e.getMessage(), e);
-    }
-    
-    // modify existing definition currently in-memory (must be valid to get here)
-    if (null != ri) {
-      ri.setBaseUrl(baseUrl);
-    }
-    
-  }
-
   /*
    * function for given a stack name and version, is it a supported stack
    */
@@ -766,7 +644,7 @@ public class AmbariMetaInfo {
                 + ", stackVersion=" + stack.getName()
                 + ", repoFolder=" + repositoryFolder.getPath());
           }
-          List<RepositoryInfo> repositoryInfoList = getRepository(repositoryFolder);
+          List<RepositoryInfo> repositoryInfoList = getRepository(repositoryFolder, stackInfo.getVersion());
           stackInfo.getRepositories().addAll(repositoryInfoList);
         }
 
@@ -866,11 +744,10 @@ public class AmbariMetaInfo {
     return stackInfo;
   }
 
-  private List<RepositoryInfo> getRepository(File repositoryFile)
+  private List<RepositoryInfo> getRepository(File repositoryFile, String stackVersion)
       throws ParserConfigurationException, IOException, SAXException {
 
     List<RepositoryInfo> repositorysInfo = new ArrayList<RepositoryInfo>();
-//    try {
 
     DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
     DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
@@ -906,7 +783,6 @@ public class AmbariMetaInfo {
           String repoName = getTagValue(REPOSITORY_XML_PROPERTY_REPONAME, property);
           String baseUrl = getTagValue(REPOSITORY_XML_PROPERTY_BASEURL, property);
           String mirrorsList = getTagValue(REPOSITORY_XML_PROPERTY_MIRRORSLIST, property);
-          String defaultBaseUrl = getTagValue(REPOSITORY_XML_PROPERTY_DEFAULT_BASEURL, property);
 
           String[] osTypes = osType.split(",");
 
@@ -916,21 +792,29 @@ public class AmbariMetaInfo {
             repositoryInfo.setRepoId(repoId);
             repositoryInfo.setRepoName(repoName);
             repositoryInfo.setBaseUrl(baseUrl);
+            repositoryInfo.setDefaultBaseUrl(baseUrl);
             repositoryInfo.setMirrorsList(mirrorsList);
-            repositoryInfo.setDefaultBaseUrl(defaultBaseUrl);
-
+            
             if (LOG.isDebugEnabled()) {
               LOG.debug("Adding repo to stack"
                   + ", repoInfo=" + repositoryInfo.toString());
             }
+
+            if (null != metainfoDAO) {
+              LOG.debug("Checking for override for base_url");
+              String key = generateRepoMetaKey(repoName, stackVersion, os, repoId, REPOSITORY_XML_PROPERTY_BASEURL);
+              MetainfoEntity entity = metainfoDAO.findByKey(key);
+              if (null != entity) {
+                repositoryInfo.setBaseUrl(entity.getMetainfoValue());
+              }
+              
+            }            
+            
             repositorysInfo.add(repositoryInfo);
           }
         }
       }
     }
-//    } catch (Exception e) {
-//      e.printStackTrace();
-//    }
 
     return repositorysInfo;
   }
@@ -1060,5 +944,54 @@ public class AmbariMetaInfo {
             osType.equals("oraclelinux6") ||
             osType.equals("suse11") || osType.equals("sles11");
   }
+  
+  private String generateRepoMetaKey(String stackName, String stackVersion,
+      String osType, String repoId, String field) {
+    
+    StringBuilder sb = new StringBuilder("repo:/");
+    sb.append(stackName).append('/');
+    sb.append(stackVersion).append('/');
+    sb.append(osType).append('/');
+    sb.append(repoId);
+    sb.append(':').append(field);
+    
+    return sb.toString();
+  }
+
+  /**
+   * @param stackName the stack name
+   * @param stackVersion the stack version
+   * @param osType the os
+   * @param repoId the repo id
+   * @param newBaseUrl the new base url
+   */
+  public void updateRepoBaseURL(String stackName,
+      String stackVersion, String osType, String repoId, String newBaseUrl) throws AmbariException {
+
+    // validate existing
+    RepositoryInfo ri = getRepository(stackName, stackVersion, osType, repoId);
+    
+    if (!stackRoot.exists())
+      throw new StackAccessException("Stack root does not exist.");
+    
+    ri.setBaseUrl(newBaseUrl);
+    
+    if (null != metainfoDAO) {
+      String metaKey = generateRepoMetaKey(stackName, stackVersion, osType,
+          repoId, REPOSITORY_XML_PROPERTY_BASEURL);
+      
+      MetainfoEntity entity = new MetainfoEntity();
+      entity.setMetainfoName(metaKey);
+      entity.setMetainfoValue(newBaseUrl);
+      
+      if (null != ri.getDefaultBaseUrl() && newBaseUrl.equals(ri.getDefaultBaseUrl())) {
+        metainfoDAO.remove(entity);
+      } else {
+        metainfoDAO.merge(entity);
+      }
+    }
+    
+  }
+
  
 }

+ 7 - 13
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java

@@ -56,6 +56,8 @@ import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.controller.internal.URLStreamProvider;
 import org.apache.ambari.server.metadata.ActionMetadata;
 import org.apache.ambari.server.metadata.RoleCommandOrder;
+import org.apache.ambari.server.orm.dao.MetainfoDAO;
+import org.apache.ambari.server.orm.entities.MetainfoEntity;
 import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 import org.apache.ambari.server.security.authorization.User;
 import org.apache.ambari.server.security.authorization.Users;
@@ -4303,7 +4305,7 @@ public class AmbariManagementControllerImpl implements
       RepositoryInfo repository = this.ambariMetaInfo.getRepository(stackName, stackVersion, osType, repoId);
       response = Collections.singleton(repository.convertToResponse());
     }
-
+    
     return response;
   }
   
@@ -4323,18 +4325,9 @@ public class AmbariManagementControllerImpl implements
         throw new AmbariException("Repo ID must be specified.");
       
       if (null != rr.getBaseUrl()) {
-        // verify url is accessible
-        URLStreamProvider usp = new URLStreamProvider(
-            REPO_URL_CONNECT_TIMEOUT, REPO_URL_READ_TIMEOUT);
-        try {
-          IOUtils.readLines(usp.readFrom(rr.getBaseUrl()));
-          ambariMetaInfo.updateRepository(rr.getStackName(),
-              rr.getStackVersion(), rr.getOsType(), rr.getRepoId(),
-              rr.getBaseUrl());
-        }
-        catch (IOException ioe) {
-          throw new IllegalArgumentException("Could not access base_url '" + rr.getBaseUrl(), ioe);
-        }
+        ambariMetaInfo.updateRepoBaseURL(rr.getStackName(),
+            rr.getStackVersion(), rr.getOsType(), rr.getRepoId(),
+            rr.getBaseUrl());
       }
     }
   }
@@ -4548,4 +4541,5 @@ public class AmbariManagementControllerImpl implements
   private String getAuthName() {
     return AuthorizationHelper.getAuthenticatedName(configs.getAnonymousAuditName());
   }
+  
 }

+ 8 - 5
ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariServer.java

@@ -24,8 +24,6 @@ import javax.crypto.BadPaddingException;
 import java.net.BindException;
 import java.util.Map;
 
-import com.google.inject.persist.PersistFilter;
-import com.google.gson.Gson;
 import org.apache.ambari.eventdb.webservice.WorkflowJsonService;
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.ActionManager;
@@ -33,7 +31,11 @@ import org.apache.ambari.server.agent.HeartBeatHandler;
 import org.apache.ambari.server.agent.rest.AgentResource;
 import org.apache.ambari.server.api.AmbariPersistFilter;
 import org.apache.ambari.server.api.rest.BootStrapResource;
-import org.apache.ambari.server.api.services.*;
+import org.apache.ambari.server.api.services.AmbariMetaInfo;
+import org.apache.ambari.server.api.services.AmbariMetaService;
+import org.apache.ambari.server.api.services.KeyService;
+import org.apache.ambari.server.api.services.PersistKeyValueImpl;
+import org.apache.ambari.server.api.services.PersistKeyValueService;
 import org.apache.ambari.server.bootstrap.BootStrapImpl;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
@@ -69,6 +71,7 @@ import org.springframework.web.context.WebApplicationContext;
 import org.springframework.web.context.support.GenericWebApplicationContext;
 import org.springframework.web.filter.DelegatingFilterProxy;
 
+import com.google.gson.Gson;
 import com.google.inject.Guice;
 import com.google.inject.Inject;
 import com.google.inject.Injector;
@@ -432,12 +435,12 @@ public class AmbariServer {
     BootStrapResource.init(injector.getInstance(BootStrapImpl.class));
     StageUtils.setGson(injector.getInstance(Gson.class));
     WorkflowJsonService.setDBProperties(
-        injector.getInstance(Configuration.class)
-    );
+        injector.getInstance(Configuration.class));
   }
 
   public static void main(String[] args) throws Exception {
     Injector injector = Guice.createInjector(new ControllerModule());
+    
     AmbariServer server = null;
     try {
       LOG.info("Getting the controller");

+ 0 - 4
ambari-server/src/main/java/org/apache/ambari/server/controller/ControllerModule.java

@@ -51,18 +51,15 @@ import java.util.Properties;
 public class ControllerModule extends AbstractModule {
 
   private final Configuration configuration;
-  private final AmbariMetaInfo ambariMetaInfo;
   private final HostsMap hostsMap;
 
   public ControllerModule() throws Exception {
     configuration = new Configuration();
-    ambariMetaInfo = new AmbariMetaInfo(configuration);
     hostsMap = new HostsMap(configuration);
   }
 
   public ControllerModule(Properties properties) throws Exception {
     configuration = new Configuration(properties);
-    ambariMetaInfo = new AmbariMetaInfo(configuration);
     hostsMap = new HostsMap(configuration);
   }
 
@@ -71,7 +68,6 @@ public class ControllerModule extends AbstractModule {
     installFactories();
 
     bind(Configuration.class).toInstance(configuration);
-    bind(AmbariMetaInfo.class).toInstance(ambariMetaInfo);
     bind(HostsMap.class).toInstance(hostsMap);
     bind(PasswordEncoder.class).toInstance(new StandardPasswordEncoder());
 

+ 0 - 56
ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaInfoTest.java

@@ -429,60 +429,4 @@ public class AmbariMetaInfoTest {
     Assert.assertFalse(metaInfo.isOsSupported("windows"));
   }
   
-  @Test
-  public void testRepoBaseUrl() throws Exception {
-    File stackRoot = new File("src/test/resources/stacks");
-    
-    File tmp = new File(FileUtils.getTempDirectoryPath() + File.separator + "stacks" + System.currentTimeMillis());
-    FileUtils.copyDirectory(stackRoot, tmp);
-
-    AmbariMetaInfo metaInfo = new AmbariMetaInfo(tmp, new File("target/version"));
-    metaInfo.init();
-
-    String TMP_URL1 = "http://foo.com";
-    String TMP_URL2 = "http://bar.com";
-    
-    try {
-      RepositoryInfo repository = metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, REPO_ID);
-      String defaultBaseUrl = repository.getDefaultBaseUrl();
-      Assert.assertNull(defaultBaseUrl);
-      
-      // what it will expected to be
-      defaultBaseUrl = repository.getBaseUrl();
-      
-      metaInfo.updateRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, REPO_ID, TMP_URL1);
-      repository = metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, REPO_ID);
-      Assert.assertEquals(TMP_URL1, repository.getBaseUrl());
-      Assert.assertEquals(defaultBaseUrl, repository.getDefaultBaseUrl());
-      
-      // reload from disk
-      AmbariMetaInfo metaInfo1 = new AmbariMetaInfo(tmp, new File("target/version"));
-      metaInfo1.init();
-      
-      RepositoryInfo repository1 = metaInfo.getRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, REPO_ID);
-      Assert.assertEquals(TMP_URL1, repository1.getBaseUrl());
-      
-      try {
-        metaInfo1.updateRepository(NON_EXT_VALUE, STACK_VERSION_HDP, OS_TYPE, REPO_ID, TMP_URL2);
-        Assert.fail("Expect StackAccessException on name");
-
-        metaInfo1.updateRepository(STACK_NAME_HDP, NON_EXT_VALUE, OS_TYPE, REPO_ID, TMP_URL2);
-        Assert.fail("Expect StackAccessException on version");
-        
-        metaInfo1.updateRepository(STACK_NAME_HDP, STACK_VERSION_HDP, NON_EXT_VALUE, REPO_ID, TMP_URL2);
-        Assert.fail("Expect StackAccessException on OS");
-        
-        metaInfo1.updateRepository(STACK_NAME_HDP, STACK_VERSION_HDP, OS_TYPE, NON_EXT_VALUE, TMP_URL2);
-        Assert.fail("Expect StackAccessException on repo id");
-        
-      } catch (Exception e) {
-        // expecting failure
-      }
-      
-    } finally {
-      FileUtils.deleteDirectory(tmp);
-    }
-  }
-
-  
 }

+ 5 - 23
ambari-server/src/test/java/org/apache/ambari/server/api/services/AmbariMetaServiceTest.java

@@ -20,15 +20,12 @@ package org.apache.ambari.server.api.services;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Map;
 
 import junit.framework.Assert;
 
 import org.apache.ambari.server.state.ServiceInfo;
 import org.apache.ambari.server.state.StackInfo;
-import org.apache.ambari.server.utils.StageUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.codehaus.jackson.map.DeserializationConfig;
@@ -37,8 +34,6 @@ import org.codehaus.jackson.type.TypeReference;
 import org.codehaus.jettison.json.JSONException;
 import org.junit.Test;
 
-import com.google.inject.AbstractModule;
-import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.sun.jersey.api.client.Client;
 import com.sun.jersey.api.client.UniformInterfaceException;
@@ -55,34 +50,21 @@ public class AmbariMetaServiceTest extends JerseyTest {
   private static Log LOG = LogFactory.getLog(AmbariMetaService.class);
   Injector injector;
   protected Client client;
-
+  
   public  AmbariMetaServiceTest() {
     super(new WebAppDescriptor.Builder(PACKAGE_NAME).servletClass(ServletContainer.class)
         .initParam("com.sun.jersey.api.json.POJOMappingFeature", "true")
         .build());
   }
 
-  public class MockModule extends AbstractModule {
-    File stackRoot = new File("src/test/resources/stacks");
-    AmbariMetaInfo ambariMetaInfo;
-    
-    public MockModule() throws Exception {
-      this.ambariMetaInfo = new AmbariMetaInfo(stackRoot, new File("target/version"));
-    }
-
-    @Override
-    protected void configure() {
-      bind(AmbariMetaInfo.class).toInstance(ambariMetaInfo);
-      requestStaticInjection(AmbariMetaService.class);     
-    }
-  }
-
   @Override
   public void setUp() throws Exception {
     super.setUp();
-    injector = Guice.createInjector(new MockModule());
-    AmbariMetaInfo metainfo = injector.getInstance(AmbariMetaInfo.class);
+    
+    AmbariMetaInfo metainfo = new AmbariMetaInfo(new File("src/test/resources/stacks"), new File("target/version"));
     metainfo.init();
+    
+    AmbariMetaService.init(metainfo);
   }
 
   @Test

+ 72 - 4
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariManagementControllerTest.java

@@ -18,6 +18,14 @@
 
 package org.apache.ambari.server.controller;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
@@ -26,13 +34,16 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+
 import javax.persistence.EntityManager;
+
 import junit.framework.Assert;
+
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.ClusterNotFoundException;
 import org.apache.ambari.server.DuplicateResourceException;
-import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.ObjectNotFoundException;
+import org.apache.ambari.server.ParentObjectNotFoundException;
 import org.apache.ambari.server.Role;
 import org.apache.ambari.server.RoleCommand;
 import org.apache.ambari.server.StackAccessException;
@@ -46,13 +57,30 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo;
 import org.apache.ambari.server.configuration.Configuration;
 import org.apache.ambari.server.orm.GuiceJpaInitializer;
 import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
+import org.apache.ambari.server.orm.dao.MetainfoDAO;
 import org.apache.ambari.server.orm.dao.RoleDAO;
 import org.apache.ambari.server.orm.entities.RoleEntity;
 import org.apache.ambari.server.security.authorization.Users;
 import org.apache.ambari.server.serveraction.ServerAction;
 import org.apache.ambari.server.serveraction.ServerActionManager;
 import org.apache.ambari.server.serveraction.ServerActionManagerImpl;
-import org.apache.ambari.server.state.*;
+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.ConfigFactory;
+import org.apache.ambari.server.state.ConfigImpl;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.HostState;
+import org.apache.ambari.server.state.RepositoryInfo;
+import org.apache.ambari.server.state.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentFactory;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.apache.ambari.server.state.ServiceComponentHostFactory;
+import org.apache.ambari.server.state.ServiceFactory;
+import org.apache.ambari.server.state.StackId;
+import org.apache.ambari.server.state.StackInfo;
+import org.apache.ambari.server.state.State;
 import org.apache.ambari.server.state.svccomphost.ServiceComponentHostStartEvent;
 import org.apache.ambari.server.utils.StageUtils;
 import org.junit.After;
@@ -62,12 +90,11 @@ import org.junit.Test;
 import org.junit.rules.ExpectedException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+
 import com.google.inject.Guice;
 import com.google.inject.Injector;
 import com.google.inject.persist.PersistService;
 
-import static org.junit.Assert.*;
-
 public class AmbariManagementControllerTest {
 
   private static final Logger LOG =
@@ -6499,4 +6526,45 @@ public class AmbariManagementControllerTest {
     }
   }
   
+  @Test
+  public void testUpdateRepoUrl() throws Exception {
+    String INCORRECT_URL_2 = "http://bar.com/foo";
+    
+    RepositoryInfo repo = ambariMetaInfo.getRepository(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID);
+    assertNotNull(repo);
+    assertNotNull(repo.getBaseUrl());
+    
+    String original = repo.getBaseUrl();
+    
+    repo = ambariMetaInfo.getRepository(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID);
+    assertEquals(original, repo.getBaseUrl());
+    
+    ambariMetaInfo.updateRepoBaseURL(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID, INCORRECT_BASE_URL);
+    
+    repo = ambariMetaInfo.getRepository(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID);
+    assertEquals(INCORRECT_BASE_URL, repo.getBaseUrl());
+    assertEquals(original, repo.getDefaultBaseUrl());
+    
+    ambariMetaInfo.updateRepoBaseURL(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID, INCORRECT_URL_2);
+    repo = ambariMetaInfo.getRepository(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID);
+    assertFalse(INCORRECT_BASE_URL.equals(repo.getBaseUrl()));
+    assertEquals(INCORRECT_URL_2, repo.getBaseUrl());
+    assertEquals(original, repo.getDefaultBaseUrl());
+
+    // verify change with new meta info
+    AmbariMetaInfo ami = new AmbariMetaInfo(new File("src/test/resources/stacks"), new File("target/version"));
+    injector.injectMembers(ami);
+    ami.init();
+    
+    repo = ami.getRepository(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID);
+    assertEquals(INCORRECT_URL_2, repo.getBaseUrl());
+    assertNotNull(repo.getDefaultBaseUrl());
+    assertEquals(original, repo.getDefaultBaseUrl());
+    
+    ami.updateRepoBaseURL(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID, original);
+    repo = ami.getRepository(STACK_NAME, STACK_VERSION, OS_TYPE, REPO_ID);
+    assertEquals(original, repo.getBaseUrl());
+    assertEquals(original, repo.getDefaultBaseUrl());
+  }
+  
 }

+ 1 - 0
ambari-server/src/test/java/org/apache/ambari/server/controller/AmbariServerTest.java

@@ -50,6 +50,7 @@ public class AmbariServerTest {
   @Before
   public void setup() throws Exception {
     injector = Guice.createInjector(new InMemoryDefaultTestModule());
+    injector.getInstance(GuiceJpaInitializer.class);
     injector.injectMembers(this);
   }