001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase;
019
020import static org.junit.Assert.assertTrue;
021import java.io.IOException;
022import java.util.HashMap;
023import java.util.Map;
024import org.apache.hadoop.conf.Configuration;
025import org.apache.hadoop.hbase.ClusterManager.ServiceType;
026import org.apache.hadoop.hbase.RESTApiClusterManager.Service;
027import org.apache.hadoop.hbase.testclassification.SmallTests;
028import org.junit.Before;
029import org.junit.BeforeClass;
030import org.junit.ClassRule;
031import org.junit.Rule;
032import org.junit.Test;
033import org.junit.experimental.categories.Category;
034import org.junit.rules.TestName;
035
036@Category(SmallTests.class)
037public class TestRESTApiClusterManager {
038
039  @ClassRule
040  public static final HBaseClassTestRule testRule =
041    HBaseClassTestRule.forClass(TestRESTApiClusterManager.class);
042
043  @ClassRule
044  public static MockHttpApiRule mockHttpApi = new MockHttpApiRule();
045
046  @Rule
047  public final TestName testName = new TestName();
048
049  private static HBaseCommonTestingUtil testingUtility;
050  private ClusterManager clusterManager;
051
052  @BeforeClass
053  public static void beforeClass() {
054    testingUtility = new HBaseCommonTestingUtil();
055    configureClusterManager(testingUtility.getConfiguration());
056  }
057
058  @Before
059  public void before() {
060    mockHttpApi.clearRegistrations();
061    final Configuration methodConf = new Configuration(testingUtility.getConfiguration());
062    methodConf.set("hbase.it.clustermanager.restapi.clustername", testName.getMethodName());
063    clusterManager = new RESTApiClusterManager();
064    clusterManager.setConf(methodConf);
065  }
066
067  @Test
068  public void isRunningPositive() throws IOException {
069    final String clusterName = testName.getMethodName();
070    final String hostName = "somehost";
071    final String serviceName = "hbase";
072    final String hostId = "some-id";
073    registerServiceName(clusterName, Service.HBASE, serviceName);
074    registerHost(hostName, hostId);
075    final Map<String, String> hostProperties = new HashMap<>();
076    hostProperties.put("roleState", "STARTED");
077    hostProperties.put("healthSummary", "GOOD");
078    registerHostProperties(
079      clusterName, serviceName, hostId, ServiceType.HBASE_MASTER, hostProperties);
080    assertTrue(clusterManager.isRunning(ServiceType.HBASE_MASTER, hostName, -1));
081  }
082
083  private static void configureClusterManager(final Configuration conf) {
084    conf.set("hbase.it.clustermanager.restapi.hostname", mockHttpApi.getURI().toString());
085  }
086
087  private static void registerServiceName(
088    final String clusterName,
089    final Service service,
090    final String serviceName
091  ) {
092    final String target = String.format("^/api/v6/clusters/%s/services", clusterName);
093    final String response = String.format(
094      "{ \"items\": [ { \"type\": \"%s\", \"name\": \"%s\" } ] }", service, serviceName);
095    mockHttpApi.registerOk(target, response);
096  }
097
098  private static void registerHost(final String hostName, final String hostId) {
099    final String target = "^/api/v6/hosts";
100    final String response = String.format(
101      "{ \"items\": [ { \"hostname\": \"%s\", \"hostId\": \"%s\" } ] }", hostName, hostId);
102    mockHttpApi.registerOk(target, response);
103  }
104
105  private static void registerHostProperties(
106    final String clusterName,
107    final String serviceName,
108    final String hostId,
109    final ServiceType serviceType,
110    final Map<String, String> properties
111  ) {
112    final String target = String.format(
113      "^/api/v6/clusters/%s/services/%s/roles", clusterName, serviceName);
114    final StringBuilder builder = new StringBuilder()
115      .append("{ \"items\": [ ")
116      .append("{ \"hostRef\": { \"hostId\": \"")
117      .append(hostId)
118      .append("\" }, \"type\": \"")
119      .append(serviceType)
120      .append("\"");
121    properties.forEach((k, v) -> builder
122      .append(", \"")
123      .append(k)
124      .append("\": \"")
125      .append(v)
126      .append("\""));
127    builder.append(" } ] }");
128    mockHttpApi.registerOk(target, builder.toString());
129  }
130}