You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by am...@apache.org on 2018/08/03 14:11:56 UTC

[ambari] branch branch-2.7 updated: AMBARI-24401. Ambari doesn't replace Timeline Reader localhost address with corresponding host in fresh and upgrade installation (amagyar) (#1955) (#1960)

This is an automated email from the ASF dual-hosted git repository.

amagyar pushed a commit to branch branch-2.7
in repository https://gitbox.apache.org/repos/asf/ambari.git


The following commit(s) were added to refs/heads/branch-2.7 by this push:
     new 1661b4e  AMBARI-24401. Ambari doesn't replace Timeline Reader localhost address with corresponding host in fresh and upgrade installation (amagyar) (#1955) (#1960)
1661b4e is described below

commit 1661b4e07ba0c37c608f8ef2c5f0e4e8028824a9
Author: Attila Magyar <m....@gmail.com>
AuthorDate: Fri Aug 3 16:11:52 2018 +0200

    AMBARI-24401. Ambari doesn't replace Timeline Reader localhost address with corresponding host in fresh and upgrade installation (amagyar) (#1955) (#1960)
---
 .../upgrades/AbstractUpgradeServerAction.java      |   2 +-
 .../upgrades/FixTimelineReaderAddress.java         | 107 +++++++++++++++++++++
 .../upgrades/FixTimelineReaderAddressTest.java     |  92 ++++++++++++++++++
 3 files changed, 200 insertions(+), 1 deletion(-)

diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
index abbf6b3..78d6da8 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/AbstractUpgradeServerAction.java
@@ -40,7 +40,7 @@ public abstract class AbstractUpgradeServerAction extends AbstractServerAction {
   }
 
   @Inject
-  private Clusters m_clusters;
+  protected Clusters m_clusters;
 
   /**
    * Used to move desired repo versions forward.
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixTimelineReaderAddress.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixTimelineReaderAddress.java
new file mode 100644
index 0000000..c7ddaa8
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/upgrades/FixTimelineReaderAddress.java
@@ -0,0 +1,107 @@
+/*
+ *
+ *  * 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.serveraction.upgrades;
+
+import static java.util.stream.Collectors.toList;
+import static org.apache.commons.lang.StringUtils.join;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentMap;
+
+import org.apache.ambari.server.AmbariException;
+import org.apache.ambari.server.ObjectNotFoundException;
+import org.apache.ambari.server.actionmanager.HostRoleStatus;
+import org.apache.ambari.server.agent.CommandReport;
+import org.apache.ambari.server.state.Cluster;
+import org.apache.ambari.server.state.Config;
+import org.apache.ambari.server.state.Host;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The timeline reader bind address is initialized to localhost by default.
+ * This upgrade action updates localhost to the current hostname of the timeline reader.
+ */
+public class FixTimelineReaderAddress extends AbstractUpgradeServerAction {
+  private static final Logger LOG = LoggerFactory.getLogger(CreateAndConfigureAction.class);
+  private static final String YARN_SITE = "yarn-site";
+  private static final String TIMELINE_READER = "TIMELINE_READER";
+  private static final String[] HOST_PROPERTIES = new String[] {
+    "yarn.timeline-service.reader.webapp.address",
+    "yarn.timeline-service.reader.webapp.https.address"
+  };
+
+  @Override
+  public CommandReport execute(ConcurrentMap<String, Object> requestSharedDataContext) throws AmbariException, InterruptedException {
+    Cluster cluster = getClusters().getCluster(getExecutionCommand().getClusterName());
+    List<String> updatedHosts = new ArrayList<>();
+    try {
+      for (String propertyName : HOST_PROPERTIES) {
+        Config config = cluster.getDesiredConfigByType(YARN_SITE);
+        if (config == null) {
+          continue;
+        }
+        String oldHost = config.getProperties().get(propertyName);
+        if (oldHost == null) {
+          continue;
+        }
+        String newHost = oldHost.replace("localhost", hostNameOf(cluster, "YARN", TIMELINE_READER));
+        updatedHosts.add(newHost);
+        updateConfig(cluster, propertyName, newHost, config);
+      }
+      return commandReport(String.format("Updated %s hosts to: %s", TIMELINE_READER, join(updatedHosts, ", ")));
+    } catch (ObjectNotFoundException e) {
+      return commandReport("Skipping " + this.getClass().getSimpleName() + ". Reason: " + e.getMessage());
+    }
+  }
+
+  private void updateConfig(Cluster cluster, String propertyName, String propertyValue, Config config) throws AmbariException {
+    Map<String, String> newProperties = new HashMap<>();
+    newProperties.put(propertyName, propertyValue);
+    config.updateProperties(newProperties);
+    config.save();
+    agentConfigsHolder.updateData(cluster.getClusterId(), cluster.getHosts().stream().map(Host::getHostId).collect(toList()));
+  }
+
+  /**
+   * @return the host name of a given service component. One instance is expected.
+   */
+  private String hostNameOf(Cluster cluster, String serviceName, String componentName) throws AmbariException {
+    ServiceComponent timelineReader = cluster.getService(serviceName).getServiceComponent(componentName);
+    Set<String> allHosts = timelineReader.getServiceComponentHosts().keySet();
+    if (allHosts.isEmpty()) {
+      throw new ObjectNotFoundException("No " + componentName + " hosts found.");
+    }
+    if (allHosts.size() > 1) {
+      LOG.warn("Expected one " + componentName + " host, found " + allHosts.size() + ". Using the first host.");
+    }
+    return allHosts.iterator().next();
+  }
+
+  private CommandReport commandReport(String message) {
+    return createCommandReport(0, HostRoleStatus.COMPLETED, "{}", message, "");
+  }
+}
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/FixTimelineReaderAddressTest.java b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/FixTimelineReaderAddressTest.java
new file mode 100644
index 0000000..14bd0f7
--- /dev/null
+++ b/ambari-server/src/test/java/org/apache/ambari/server/serveraction/upgrades/FixTimelineReaderAddressTest.java
@@ -0,0 +1,92 @@
+/*
+ *
+ *  * 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.serveraction.upgrades;
+
+import static java.util.Collections.emptyList;
+import static org.easymock.EasyMock.anyString;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+
+import java.util.HashMap;
+
+import org.apache.ambari.server.agent.ExecutionCommand;
+import org.apache.ambari.server.agent.stomp.AgentConfigsHolder;
+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.Service;
+import org.apache.ambari.server.state.ServiceComponent;
+import org.apache.ambari.server.state.ServiceComponentHost;
+import org.easymock.EasyMockRunner;
+import org.easymock.EasyMockSupport;
+import org.easymock.Mock;
+import org.easymock.MockType;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(EasyMockRunner.class)
+public class FixTimelineReaderAddressTest extends EasyMockSupport {
+  @Mock(type = MockType.NICE)
+  private Cluster cluster;
+  @Mock(type = MockType.NICE)
+  private Config config;
+  @Mock
+  private Service yarn;
+  @Mock
+  private ServiceComponent timelineReader;
+  private FixTimelineReaderAddress action;
+
+  @Before
+  public void setup() throws Exception {
+    action = new FixTimelineReaderAddress();
+    action.m_clusters = createMock(Clusters.class);
+    action.agentConfigsHolder = createNiceMock(AgentConfigsHolder.class);
+    action.setExecutionCommand(new ExecutionCommand());
+    expect(action.m_clusters.getCluster(anyString())).andReturn(cluster).anyTimes();
+    expect(cluster.getService("YARN")).andReturn(yarn).anyTimes();
+    expect(cluster.getHosts()).andReturn(emptyList()).anyTimes();
+    expect(cluster.getDesiredConfigByType("yarn-site")).andReturn(config).anyTimes();
+    expect(config.getProperties()).andReturn(new HashMap<String, String>() {{
+      put("yarn.timeline-service.reader.webapp.address", "localhost:8080");
+      put("yarn.timeline-service.reader.webapp.https.address", "localhost:8081");
+    }}).anyTimes();
+    expect(yarn.getServiceComponent("TIMELINE_READER")).andReturn(timelineReader).anyTimes();
+    expect(timelineReader.getServiceComponentHosts()).andReturn(new HashMap<String, ServiceComponentHost>(){{
+      put("newhost", null);
+    }}).anyTimes();
+  }
+
+  @Test
+  public void testReplaceTimelineReaderHost() throws Exception {
+    config.updateProperties(new HashMap<String, String>() {{
+      put("yarn.timeline-service.reader.webapp.address", "newhost:8080");
+    }});
+    expectLastCall();
+    config.updateProperties(new HashMap<String, String>() {{
+      put("yarn.timeline-service.reader.webapp.https.address", "newhost:8081");
+    }});
+    expectLastCall();
+    replayAll();
+    action.execute(null);
+    verifyAll();
+  }
+}
\ No newline at end of file