Package org.apache.ambari.server.state.svccomphost

Source Code of org.apache.ambari.server.state.svccomphost.ServiceComponentHostTest

/**
* 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.svccomphost;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;

import org.apache.ambari.server.AmbariException;
import org.apache.ambari.server.ServiceComponentNotFoundException;
import org.apache.ambari.server.ServiceNotFoundException;
import org.apache.ambari.server.api.services.AmbariMetaInfo;
import org.apache.ambari.server.controller.ServiceComponentHostResponse;
import org.apache.ambari.server.orm.GuiceJpaInitializer;
import org.apache.ambari.server.orm.InMemoryDefaultTestModule;
import org.apache.ambari.server.orm.dao.HostComponentDesiredStateDAO;
import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntity;
import org.apache.ambari.server.orm.entities.HostComponentDesiredStateEntityPK;
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.Host;
import org.apache.ambari.server.state.HostConfig;
import org.apache.ambari.server.state.MaintenanceState;
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.ServiceComponentHostEvent;
import org.apache.ambari.server.state.ServiceComponentHostEventType;
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.State;
import org.apache.ambari.server.state.configgroup.ConfigGroup;
import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
import org.apache.ambari.server.state.fsm.InvalidStateTransitionException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Provider;
import com.google.inject.persist.PersistService;

public class ServiceComponentHostTest {
  private static Logger LOG = LoggerFactory.getLogger(ServiceComponentHostTest.class);
  @Inject
  private Injector injector;
  @Inject
  private Clusters clusters;
  @Inject
  private ServiceFactory serviceFactory;
  @Inject
  private ServiceComponentFactory serviceComponentFactory;
  @Inject
  private ServiceComponentHostFactory serviceComponentHostFactory;
  @Inject
  private AmbariMetaInfo metaInfo;
  @Inject
  Provider<EntityManager> entityManagerProvider;
  @Inject
  private ConfigFactory configFactory;
  @Inject
  private ConfigGroupFactory configGroupFactory;

  @Before
  public void setup() throws Exception {
    injector = Guice.createInjector(new InMemoryDefaultTestModule());
    injector.getInstance(GuiceJpaInitializer.class);
    injector.injectMembers(this);
    clusters.addCluster("C1");
    clusters.addHost("h1");
    clusters.getHost("h1").setOsType("centos5");
    clusters.getHost("h1").persist();
    clusters.getCluster("C1").setDesiredStackVersion(
        new StackId("HDP-0.1"));
    metaInfo.init();
    clusters.mapHostToCluster("h1","C1");
  }

  @After
  public void teardown() {
    injector.getInstance(PersistService.class).stop();
  }
 
  private ServiceComponentHost createNewServiceComponentHost(
      String svc,
      String svcComponent,
      String hostName, boolean isClient) throws AmbariException{
    Cluster c = clusters.getCluster("C1");
   
    return createNewServiceComponentHost(c, svc, svcComponent, hostName);
  }
  private ServiceComponentHost createNewServiceComponentHost(
      Cluster c,
      String svc,
      String svcComponent,
      String hostName) throws AmbariException{

    Service s = null;

    try {
      s = c.getService(svc);
    } catch (ServiceNotFoundException e) {
      LOG.debug("Calling service create"
          + ", serviceName=" + svc);
      s = serviceFactory.createNew(c, svc);
      c.addService(s);
      s.persist();
    }

    ServiceComponent sc = null;
    try {
      sc = s.getServiceComponent(svcComponent);
    } catch (ServiceComponentNotFoundException e) {
      sc = serviceComponentFactory.createNew(s, svcComponent);
      s.addServiceComponent(sc);
      sc.persist();
    }

    ServiceComponentHost impl = serviceComponentHostFactory.createNew(
        sc, hostName);
    impl.persist();
    Assert.assertEquals(State.INIT,
        impl.getState());
    Assert.assertEquals(State.INIT,
        impl.getDesiredState());
    Assert.assertEquals(c.getClusterName(), impl.getClusterName());
    Assert.assertEquals(c.getClusterId(), impl.getClusterId());
    Assert.assertEquals(s.getName(), impl.getServiceName());
    Assert.assertEquals(sc.getName(), impl.getServiceComponentName());
    Assert.assertEquals(hostName, impl.getHostName());
    Assert.assertFalse(
        impl.getDesiredStackVersion().getStackId().isEmpty());
    Assert.assertTrue(impl.getStackVersion().getStackId().isEmpty());

    return impl;
  }

  @Test
  public void testNewServiceComponentHost() throws AmbariException{
    createNewServiceComponentHost("HDFS", "NAMENODE", "h1", false);
    createNewServiceComponentHost("HDFS", "HDFS_CLIENT", "h1", true);
  }

  private ServiceComponentHostEvent createEvent(ServiceComponentHostImpl impl,
      long timestamp, ServiceComponentHostEventType eventType)
      throws AmbariException {
    Map<String, String> configs = new HashMap<String, String>();

    Cluster c = clusters.getCluster("C1");
    if (c.getConfig("time", "" + timestamp) == null) {
      Config config = configFactory.createNew (c, "time",
          new HashMap<String, String>());
      config.setVersionTag("" + timestamp);
      c.addConfig(config);
      config.persist();
    }

    configs.put("time", "" + timestamp);
    switch (eventType) {
      case HOST_SVCCOMP_INSTALL:
        return new ServiceComponentHostInstallEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp,
            impl.getDesiredStackVersion().getStackId());
      case HOST_SVCCOMP_START:
        return new ServiceComponentHostStartEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_STOP:
        return new ServiceComponentHostStopEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_UNINSTALL:
        return new ServiceComponentHostUninstallEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_OP_FAILED:
        return new ServiceComponentHostOpFailedEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_OP_SUCCEEDED:
        return new ServiceComponentHostOpSucceededEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_OP_IN_PROGRESS:
        return new ServiceComponentHostOpInProgressEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_OP_RESTART:
        return new ServiceComponentHostOpRestartedEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      case HOST_SVCCOMP_WIPEOUT:
        return new ServiceComponentHostWipeoutEvent(
            impl.getServiceComponentName(), impl.getHostName(), timestamp);
      default:
        return null;
    }
  }

  private void runStateChanges(ServiceComponentHostImpl impl,
      ServiceComponentHostEventType startEventType,
      State startState,
      State inProgressState,
      State failedState,
      State completedState)
    throws Exception {
    long timestamp = 0;

    boolean checkStack = false;
    if (startEventType == ServiceComponentHostEventType.HOST_SVCCOMP_INSTALL) {
      checkStack = true;
      impl.setStackVersion(null);
    }

    Assert.assertEquals(startState,
        impl.getState());
    ServiceComponentHostEvent startEvent = createEvent(impl, ++timestamp,
        startEventType);

    long startTime = timestamp;
    impl.handleEvent(startEvent);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());
    if (checkStack) {
      Assert.assertNotNull(impl.getStackVersion());
      Assert.assertEquals(impl.getDesiredStackVersion().getStackId(),
          impl.getStackVersion().getStackId());
    }

    ServiceComponentHostEvent installEvent2 = createEvent(impl, ++timestamp,
        startEventType);
  
    boolean exceptionThrown = false;
    LOG.info("Transitioning from " + impl.getState() + " " + installEvent2.getType());
    try {
      impl.handleEvent(installEvent2);
    } catch (Exception e) {
      exceptionThrown = true;
    }
    if (impl.getState() == State.INSTALLING || impl.getState() == State.STARTING
      || impl.getState() == State.UNINSTALLING
        || impl.getState() == State.WIPING_OUT
        || impl.getState() == State.STARTED
        ) {
      startTime = timestamp;
    // Exception is not expected on valid event
      Assert.assertTrue("Exception not thrown on invalid event", !exceptionThrown);
    }
    else {
      Assert.assertTrue("Exception not thrown on invalid event", exceptionThrown);
    }
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());

    ServiceComponentHostOpInProgressEvent inProgressEvent1 = new
        ServiceComponentHostOpInProgressEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    impl.handleEvent(inProgressEvent1);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());

    ServiceComponentHostOpInProgressEvent inProgressEvent2 = new
        ServiceComponentHostOpInProgressEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    impl.handleEvent(inProgressEvent2);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());


    ServiceComponentHostOpFailedEvent failEvent = new
        ServiceComponentHostOpFailedEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    long endTime = timestamp;
    impl.handleEvent(failEvent);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(endTime, impl.getLastOpEndTime());
    Assert.assertEquals(failedState,
        impl.getState());

    ServiceComponentHostOpRestartedEvent restartEvent = new
        ServiceComponentHostOpRestartedEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    startTime = timestamp;
    impl.handleEvent(restartEvent);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());

    ServiceComponentHostOpInProgressEvent inProgressEvent3 = new
        ServiceComponentHostOpInProgressEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    impl.handleEvent(inProgressEvent3);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());

    ServiceComponentHostOpFailedEvent failEvent2 = new
        ServiceComponentHostOpFailedEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    endTime = timestamp;
    impl.handleEvent(failEvent2);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(endTime, impl.getLastOpEndTime());
    Assert.assertEquals(failedState,
        impl.getState());

    ServiceComponentHostEvent startEvent2 = createEvent(impl, ++timestamp,
        startEventType);
    startTime = timestamp;
    impl.handleEvent(startEvent2);
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());

    ServiceComponentHostOpInProgressEvent inProgressEvent4 = new
        ServiceComponentHostOpInProgressEvent(impl.getServiceComponentName(),
            impl.getHostName(), ++timestamp);
    impl.handleEvent(inProgressEvent4);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(inProgressState,
        impl.getState());

    ServiceComponentHostEvent succeededEvent;
    if (startEventType == ServiceComponentHostEventType.HOST_SVCCOMP_START) {
      succeededEvent = new ServiceComponentHostStartedEvent(impl.getServiceComponentName(),
          impl.getHostName(), ++timestamp);
    } else if (startEventType == ServiceComponentHostEventType.HOST_SVCCOMP_STOP) {
      succeededEvent = new ServiceComponentHostStoppedEvent(impl.getServiceComponentName(),
          impl.getHostName(), ++timestamp);
    } else {
      succeededEvent = new
          ServiceComponentHostOpSucceededEvent(impl.getServiceComponentName(),
          impl.getHostName(), ++timestamp);
    }

    endTime = timestamp;
    impl.handleEvent(succeededEvent);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(timestamp, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(endTime, impl.getLastOpEndTime());
    Assert.assertEquals(completedState,
        impl.getState());

  }

  @Test
  public void testClientStateFlow() throws Exception {
    ServiceComponentHostImpl impl = (ServiceComponentHostImpl)
        createNewServiceComponentHost("HDFS", "HDFS_CLIENT", "h1", true);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_INSTALL,
        State.INIT,
        State.INSTALLING,
        State.INSTALL_FAILED,
        State.INSTALLED);

    boolean exceptionThrown = false;
    try {
      runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_START,
        State.INSTALLED,
        State.STARTING,
        State.INSTALLED,
        State.STARTED);
    }
    catch (Exception e) {
      exceptionThrown = true;
    }
    Assert.assertTrue("Exception not thrown on invalid event", exceptionThrown);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_UNINSTALL,
        State.INSTALLED,
        State.UNINSTALLING,
        State.UNINSTALLING,
        State.UNINSTALLED);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_WIPEOUT,
        State.UNINSTALLED,
        State.WIPING_OUT,
        State.WIPING_OUT,
        State.INIT);

  }

  @Test
  public void testDaemonStateFlow() throws Exception {
    ServiceComponentHostImpl impl = (ServiceComponentHostImpl)
        createNewServiceComponentHost("HDFS", "DATANODE", "h1", false);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_INSTALL,
        State.INIT,
        State.INSTALLING,
        State.INSTALL_FAILED,
        State.INSTALLED);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_START,
      State.INSTALLED,
      State.STARTING,
      State.INSTALLED,
      State.STARTED);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_STOP,
      State.STARTED,
      State.STOPPING,
      State.STARTED,
      State.INSTALLED);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_UNINSTALL,
        State.INSTALLED,
        State.UNINSTALLING,
        State.UNINSTALLING,
        State.UNINSTALLED);

    runStateChanges(impl, ServiceComponentHostEventType.HOST_SVCCOMP_WIPEOUT,
        State.UNINSTALLED,
        State.WIPING_OUT,
        State.WIPING_OUT,
        State.INIT);
  }

  @Test
  public void testJobHandling() {
    // TODO fix once jobs are handled
  }


  @Test
  public void testGetAndSetConfigs() {
    // FIXME config handling
    /*
    public Map<String, Config> getDesiredConfigs();
    public void updateDesiredConfigs(Map<String, Config> configs);
    public Map<String, Config> getConfigs();
    public void updateConfigs(Map<String, Config> configs);
    */
  }

  @Test
  public void testGetAndSetBasicInfo() throws AmbariException {
    ServiceComponentHost sch =
        createNewServiceComponentHost("HDFS", "NAMENODE", "h1", false);
    sch.setDesiredState(State.INSTALLED);
    sch.setState(State.INSTALLING);
    sch.setStackVersion(new StackId("HDP-1.0.0"));
    sch.setDesiredStackVersion(new StackId("HDP-1.1.0"));

    Assert.assertEquals(State.INSTALLING, sch.getState());
    Assert.assertEquals(State.INSTALLED, sch.getDesiredState());
    Assert.assertEquals("HDP-1.0.0",
        sch.getStackVersion().getStackId());
    Assert.assertEquals("HDP-1.1.0",
        sch.getDesiredStackVersion().getStackId());
  }
 
  @Test
  public void testActualConfigs() throws Exception {
    ServiceComponentHost sch =
        createNewServiceComponentHost("HDFS", "NAMENODE", "h1", false);
    sch.setDesiredState(State.INSTALLED);
    sch.setState(State.INSTALLING);
    sch.setStackVersion(new StackId("HDP-1.0.0"));
    sch.setDesiredStackVersion(new StackId("HDP-1.1.0"));

    Cluster cluster = clusters.getCluster("C1");

    final ConfigGroup configGroup = configGroupFactory.createNew(cluster,
      "cg1", "t1", "", new HashMap<String, Config>(), new HashMap<String, Host>());

    configGroup.persist();
    cluster.addConfigGroup(configGroup);
   
    Map<String, Map<String,String>> actual =
        new HashMap<String, Map<String, String>>() {{
          put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
          put("core-site", new HashMap<String,String>() {{ put("tag", "version1");
            put(configGroup.getId().toString(), "version2"); }});
        }};
       
    sch.updateActualConfigs(actual);
   
    Map<String, HostConfig> confirm = sch.getActualConfigs();
   
    Assert.assertEquals(2, confirm.size());
    Assert.assertTrue(confirm.containsKey("global"));
    Assert.assertTrue(confirm.containsKey("core-site"));
    Assert.assertEquals(1, confirm.get("core-site").getConfigGroupOverrides().size());

  }
 
  @Test
  public void testConvertToResponse() throws AmbariException {
    ServiceComponentHost sch =
        createNewServiceComponentHost("HDFS", "DATANODE", "h1", false);
    sch.setDesiredState(State.INSTALLED);
    sch.setState(State.INSTALLING);
    sch.setStackVersion(new StackId("HDP-1.0.0"));
    ServiceComponentHostResponse r =
        sch.convertToResponse();
    Assert.assertEquals("HDFS", r.getServiceName());
    Assert.assertEquals("DATANODE", r.getComponentName());
    Assert.assertEquals("h1", r.getHostname());
    Assert.assertEquals("C1", r.getClusterName());
    Assert.assertEquals(State.INSTALLED.toString(), r.getDesiredState());
    Assert.assertEquals(State.INSTALLING.toString(), r.getLiveState());
    Assert.assertEquals("HDP-1.0.0", r.getStackVersion());
   
    Assert.assertFalse(r.isStaleConfig());

    // TODO check configs

    StringBuilder sb = new StringBuilder();
    sch.debugDump(sb);
    Assert.assertFalse(sb.toString().isEmpty());
  }

  @Test
  public void testStopInVariousStates() throws AmbariException,
      InvalidStateTransitionException {
    ServiceComponentHost sch =
        createNewServiceComponentHost("HDFS", "DATANODE", "h1", false);
    ServiceComponentHostImpl impl =  (ServiceComponentHostImpl) sch;

    sch.setDesiredState(State.STARTED);
    sch.setState(State.INSTALLED);

    long timestamp = 0;

    ServiceComponentHostEvent stopEvent = createEvent(impl, ++timestamp,
        ServiceComponentHostEventType.HOST_SVCCOMP_STOP);

    long startTime = timestamp;
    impl.handleEvent(stopEvent);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(State.STOPPING,
        impl.getState());

    sch.setState(State.INSTALL_FAILED);

    boolean exceptionThrown = false;
    try {
      impl.handleEvent(stopEvent);
    } catch (Exception e) {
      exceptionThrown = true;
    }
    Assert.assertTrue("Exception not thrown on invalid event", exceptionThrown);

    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());

    sch.setState(State.INSTALLED);
    ServiceComponentHostEvent stopEvent2 = createEvent(impl, ++timestamp,
        ServiceComponentHostEventType.HOST_SVCCOMP_STOP);

    startTime = timestamp;
    impl.handleEvent(stopEvent2);
    Assert.assertEquals(startTime, impl.getLastOpStartTime());
    Assert.assertEquals(-1, impl.getLastOpLastUpdateTime());
    Assert.assertEquals(-1, impl.getLastOpEndTime());
    Assert.assertEquals(State.STOPPING,
        impl.getState());
  }

  @Test
  public void testCanBeRemoved() throws Exception{
    ServiceComponentHostImpl impl = (ServiceComponentHostImpl)
        createNewServiceComponentHost("HDFS", "HDFS_CLIENT", "h1", true);

    for (State state : State.values()) {
      impl.setState(state);

      if (state.isRemovableState()) {
        Assert.assertTrue(impl.canBeRemoved());
      }
      else {
        Assert.assertFalse(impl.canBeRemoved());
      }
    }
  }
 
  @Test
  public void testStaleConfigs() throws Exception {
    String stackVersion="HDP-2.0.6";
    String clusterName = "c2";
    String hostName = "h3";
   
    clusters.addCluster(clusterName);
    clusters.addHost(hostName);
    clusters.getHost(hostName).setOsType("centos5");
    clusters.getHost(hostName).persist();
    clusters.getCluster(clusterName).setDesiredStackVersion(
        new StackId(stackVersion));
    metaInfo.init();
    clusters.mapHostToCluster(hostName, clusterName);   
   
    Cluster cluster = clusters.getCluster(clusterName);
   
    ServiceComponentHost sch1 = createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", hostName);
    ServiceComponentHost sch2 = createNewServiceComponentHost(cluster, "HDFS", "DATANODE", hostName);
    ServiceComponentHost sch3 = createNewServiceComponentHost(cluster, "MAPREDUCE2", "HISTORYSERVER", hostName);
   
    sch1.setDesiredState(State.INSTALLED);
    sch1.setState(State.INSTALLING);
    sch1.setStackVersion(new StackId(stackVersion));

    sch2.setDesiredState(State.INSTALLED);
    sch2.setState(State.INSTALLING);
    sch2.setStackVersion(new StackId(stackVersion));
   
    sch3.setDesiredState(State.INSTALLED);
    sch3.setState(State.INSTALLING);
    sch3.setStackVersion(new StackId(stackVersion));   

    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());

    makeConfig(cluster, "global", "version1",
        new HashMap<String,String>() {{
          put("a", "b");
          put("dfs_namenode_name_dir", "/foo1"); // HDFS only
          put("mapred_log_dir_prefix", "/foo2"); // MR2 only
        }});

    Map<String, Map<String, String>> actual = new HashMap<String, Map<String, String>>() {{
      put("global", new HashMap<String,String>() {{ put("tag", "version1"); }});
    }};
   
    sch1.updateActualConfigs(actual);
    sch2.updateActualConfigs(actual);
    sch3.updateActualConfigs(actual);

    makeConfig(cluster, "foo", "version1",
        new HashMap<String,String>() {{ put("a", "c"); }});

    // HDP-x/HDFS does not define type 'foo', so changes do not count to stale
    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
   
    makeConfig(cluster, "hdfs-site", "version1",
        new HashMap<String,String>() {{ put("a", "b"); }});
   
    // HDP-x/HDFS/hdfs-site is not on the actual, but it is defined, so it is stale
    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());

    actual.put("hdfs-site", new HashMap<String, String>() {{ put ("tag", "version1"); }});
   
    sch1.updateActualConfigs(actual);
    // HDP-x/HDFS/hdfs-site up to date, only for sch1
    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
   
    sch2.updateActualConfigs(actual);
    // HDP-x/HDFS/hdfs-site up to date for both
    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
   
    makeConfig(cluster, "hdfs-site", "version2",
        new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://foo"); }});

    // HDP-x/HDFS/hdfs-site updated to changed property
    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
   
    actual.get("hdfs-site").put("tag", "version2");
    sch1.updateActualConfigs(actual);
    sch2.updateActualConfigs(actual);
    // HDP-x/HDFS/hdfs-site updated to changed property
    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
   
    // make a host override
    final Host host = clusters.getHostsForCluster(cluster.getClusterName()).get(hostName);
    Assert.assertNotNull(host);
   
    final Config c = configFactory.createNew(cluster, "hdfs-site",
        new HashMap<String, String>() {{ put("dfs.journalnode.http-address", "http://goo"); }});
    c.setVersionTag("version3");
    c.persist();
    cluster.addConfig(c);
    //host.addDesiredConfig(cluster.getClusterId(), true, "user", c);
    ConfigGroup configGroup = configGroupFactory.createNew(cluster, "g1",
      "t1", "", new HashMap<String, Config>() {{ put("hdfs-site", c); }},
      new HashMap<String, Host>() {{ put("h3", host); }});
    configGroup.persist();
    cluster.addConfigGroup(configGroup);
   
    // HDP-x/HDFS/hdfs-site updated host to changed property
    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
   
    actual.get("hdfs-site").put(configGroup.getId().toString(), "version3");
    sch2.updateActualConfigs(actual);
    // HDP-x/HDFS/hdfs-site updated host to changed property
    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
   
    sch1.updateActualConfigs(actual);
    // HDP-x/HDFS/hdfs-site updated host to changed property
    Assert.assertFalse(sch1.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch2.convertToResponse().isStaleConfig());
   
    // change 'global' property only affecting global/HDFS
    makeConfig(cluster, "global", "version2",
      new HashMap<String,String>() {{
        put("a", "b");
        put("dfs_namenode_name_dir", "/foo3"); // HDFS only
        put("mapred_log_dir_prefix", "/foo2"); // MR2 only
      }});
   
    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());

    // Change core-site property, only HDFS property
    makeConfig(cluster, "core-site", "version1",
      new HashMap<String,String>() {{
        put("a", "b");
        put("fs.trash.interval", "360"); // HDFS only
      }});

    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());

    actual.put("core-site", new HashMap<String, String>() {{
      put("tag", "version1");
    }});

    sch1.updateActualConfigs(actual);

    final Config c1 = configFactory.createNew(cluster, "core-site",
      new HashMap<String, String>() {{ put("fs.trash.interval", "400"); }});
    c1.setVersionTag("version2");
    c1.persist();
    cluster.addConfig(c1);
    configGroup = configGroupFactory.createNew(cluster, "g2",
      "t2", "", new HashMap<String, Config>() {{ put("core-site", c1); }},
      new HashMap<String, Host>() {{ put("h3", host); }});
    configGroup.persist();
    cluster.addConfigGroup(configGroup);

    Assert.assertTrue(sch1.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch2.convertToResponse().isStaleConfig());
    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());

    // Test actual configs are updated for deleted config group
    Long id = configGroup.getId();
    HashMap<String, String> tags = new HashMap<String, String>();
    tags.put("tag", "version1");
    tags.put(id.toString(), "version2");
    actual.put("core-site", tags);
    sch3.updateActualConfigs(actual);

    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());

    cluster.deleteConfigGroup(id);
    Assert.assertNull(cluster.getConfigGroups().get(id));

    sch3.updateActualConfigs(actual);
    Assert.assertTrue(sch3.convertToResponse().isStaleConfig());

    tags.remove(id.toString());
    sch3.updateActualConfigs(actual);
    Assert.assertFalse(sch3.convertToResponse().isStaleConfig());
  }

  /**
   * Helper method to create a configuration
   * @param cluster the cluster
   * @param type the config type
   * @param tag the config tag
   * @param values the values for the config
   */
  private void makeConfig(Cluster cluster, String type, String tag, Map<String, String> values) {
    Config config = configFactory.createNew(cluster, type, values);
    config.setVersionTag(tag);
    config.persist();
    cluster.addConfig(config);
    cluster.addDesiredConfig("user", config);
  }
 
  @Test
  public void testMaintenance() throws Exception {
    String stackVersion="HDP-2.0.6";
    String clusterName = "c2";
    String hostName = "h3";
   
    clusters.addCluster(clusterName);
    clusters.addHost(hostName);
    clusters.getHost(hostName).setOsType("centos5");
    clusters.getHost(hostName).persist();
    clusters.getCluster(clusterName).setDesiredStackVersion(
        new StackId(stackVersion));
    metaInfo.init();
    clusters.mapHostToCluster(hostName, clusterName);   
   
    Cluster cluster = clusters.getCluster(clusterName);
   
    ServiceComponentHost sch1 = createNewServiceComponentHost(cluster, "HDFS", "NAMENODE", hostName);
    ServiceComponentHost sch2 = createNewServiceComponentHost(cluster, "HDFS", "DATANODE", hostName);
    ServiceComponentHost sch3 = createNewServiceComponentHost(cluster, "MAPREDUCE2", "HISTORYSERVER", hostName);

    HostComponentDesiredStateEntityPK pk = new HostComponentDesiredStateEntityPK();
    pk.setClusterId(Long.valueOf(cluster.getClusterId()));
    pk.setComponentName(sch1.getServiceComponentName());
    pk.setServiceName(sch1.getServiceName());
    pk.setHostName(hostName);
   
    HostComponentDesiredStateDAO dao = injector.getInstance(HostComponentDesiredStateDAO.class);
    HostComponentDesiredStateEntity entity = dao.findByPK(pk);
    Assert.assertEquals(MaintenanceState.OFF, entity.getMaintenanceState());
    Assert.assertEquals(MaintenanceState.OFF, sch1.getMaintenanceState());
   
    sch1.setMaintenanceState(MaintenanceState.ON);
    Assert.assertEquals(MaintenanceState.ON, sch1.getMaintenanceState());
   
    entity = dao.findByPK(pk);
    Assert.assertEquals(MaintenanceState.ON, entity.getMaintenanceState());

  }

 
 
}
TOP

Related Classes of org.apache.ambari.server.state.svccomphost.ServiceComponentHostTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.