You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/06/14 21:19:42 UTC
[11/26] ambari git commit: AMBARI-20853. Service Advisor - Allow
Service to define its Advisor Type as Python or Java (alejandro)
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/serviceadvisor/pom.xml
----------------------------------------------------------------------
diff --git a/serviceadvisor/pom.xml b/serviceadvisor/pom.xml
new file mode 100644
index 0000000..ecf6d8b
--- /dev/null
+++ b/serviceadvisor/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <!-- Can compile this project independently, cd serviceadvisor ; mvn clean package install
+
+ To test independently without needing the rest of Ambari, simply compile and run as,
+ java -jar serviceadvisor-$VERSION.jar [ACTION] [HOSTS_FILE.json] [SERVICES_FILE.json]
+ -->
+ <groupId>serviceadvisor</groupId>
+ <artifactId>serviceadvisor</artifactId>
+ <name>Service Advisor</name>
+ <version>1.0.0.0-SNAPSHOT</version>
+ <description>Service Advisor</description>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-assembly-plugin</artifactId>
+ <version>2.6</version>
+ </dependency>
+
+ <!-- Log Factory logging
+ The main class is expected to write to stdout and stderr appropriately.
+ -->
+ <dependency>
+ <groupId>commons-logging</groupId>
+ <artifactId>commons-logging</artifactId>
+ <version>1.2</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
+ <version>1.7.20</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ <version>3.0</version>
+ </dependency>
+
+ <dependency>
+ <groupId>commons-lang</groupId>
+ <artifactId>commons-lang</artifactId>
+ <version>2.4</version>
+ </dependency>
+ </dependencies>
+
+ <pluginRepositories>
+ <pluginRepository>
+ <id>oss.sonatype.org</id>
+ <name>OSS Sonatype Staging</name>
+ <url>https://oss.sonatype.org/content/groups/staging</url>
+ </pluginRepository>
+ </pluginRepositories>
+
+ <packaging>jar</packaging>
+ <!-- Run with mvn clean package .
+ Execute as, java -jar serviceadvisor-$VERSION.jar
+ -->
+ <build>
+ <plugins>
+ <!--
+ The next 2 plugins are to include the main class in the Jar and to create a single jar with all of the dependencies.
+ It conflicts with the maven-compiler-plugin since the jar created is different.
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <mainClass>org.apache.ambari.stackadvisor.StackAdvisor</mainClass>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-shade-plugin</artifactId>
+ <version>1.6</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>shade</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ -->
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <version>3.2</version>
+ <configuration>
+ <source>1.7</source>
+ <target>1.7</target>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+</project>
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisor.java
----------------------------------------------------------------------
diff --git a/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisor.java b/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisor.java
new file mode 100644
index 0000000..77c482a
--- /dev/null
+++ b/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisor.java
@@ -0,0 +1,147 @@
+/**
+ * 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.serviceadvisor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.lang3.EnumUtils;
+import org.apache.commons.lang.StringUtils;
+
+/**
+ * Class that can be called either through its jar or using its run method.
+ * The goal is to invoke a Service Advisor.
+ * Right now, it is backward compatible by invoking the python script and does not know which service is affected.
+ */
+public class ServiceAdvisor {
+ protected static Log LOG = LogFactory.getLog(ServiceAdvisor.class);
+
+ private static String USAGE = "Usage: java -jar serviceadvisor.jar [ACTION] [HOSTS_FILE.json] [SERVICES_FILE.json] [OUTPUT.txt] [ERRORS.txt]";
+ private static String PYTHON_STACK_ADVISOR_SCRIPT = "/var/lib/ambari-server/resources/scripts/stack_advisor.py";
+
+ /**
+ * Entry point for calling this class through its jar.
+ * @param args
+ */
+ public static void main(String[] args) {
+ if (args.length != 5) {
+ System.err.println(String.format("Wrong number of arguments. %s", USAGE));
+ System.exit(1);
+ }
+
+ String action = args[0];
+ String hostsFile = args[1];
+ String servicesFile = args[2];
+ String outputFile = args[3];
+ String errorFile = args[4];
+
+ int exitCode = run(action, hostsFile, servicesFile, outputFile, errorFile);
+ System.exit(exitCode);
+ }
+
+ public static int run(String action, String hostsFile, String servicesFile, String outputFile, String errorFile) {
+ LOG.info(String.format("ServiceAdvisor. Received arguments. Action: %s, Hosts File: %s, Services File: %s", action, hostsFile, servicesFile));
+ int returnCode = -1;
+
+ try {
+ ServiceAdvisorCommandType commandType = ServiceAdvisorCommandType.getEnum(action);
+
+ // TODO, load each Service's Service Advisor at Start Time and call it instead of Python command below.
+
+ ProcessBuilder builder = preparePythonShellCommand(commandType, hostsFile, servicesFile, outputFile, errorFile);
+ returnCode = launchProcess(builder);
+ } catch (IllegalArgumentException e) {
+ List<ServiceAdvisorCommandType> values = EnumUtils.getEnumList(ServiceAdvisorCommandType.class);
+ List<String> stringValues = new ArrayList<String>();
+ for (ServiceAdvisorCommandType value : values) {
+ stringValues.add(value.toString());
+ }
+ LOG.error("ServiceAdvisor. Illegal Argument. Action must be one of " + StringUtils.join(stringValues.toArray(), ", "));
+ return -1;
+ } catch (Exception e) {
+ LOG.error("ServiceAdvisor. Failed with " + e.getMessage());
+ return -1;
+ }
+ return returnCode;
+ }
+
+ /**
+ * Generate a process to invoke a Python command for the old-style Stack Advisor.
+ * @param commandType Command Type
+ * @param hostsFile hosts.json file
+ * @param servicesFile services.json file
+ * @param outputFile output.txt
+ * @param errorFile error.txt
+ * @return Process that can launch.
+ */
+ private static ProcessBuilder preparePythonShellCommand(ServiceAdvisorCommandType commandType, String hostsFile, String servicesFile, String outputFile, String errorFile) {
+ List<String> builderParameters = new ArrayList<String>();
+
+ if (System.getProperty("os.name").contains("Windows")) {
+ builderParameters.add("cmd");
+ builderParameters.add("/c");
+ } else {
+ builderParameters.add("sh");
+ builderParameters.add("-c");
+ }
+
+ StringBuilder commandString = new StringBuilder();
+ commandString.append(PYTHON_STACK_ADVISOR_SCRIPT + " ");
+
+ commandString.append(commandType.toString()).append(" ");
+ commandString.append(hostsFile).append(" ");
+ commandString.append(servicesFile).append(" ");
+ commandString.append("1> ");
+ commandString.append(outputFile).append(" ");
+ commandString.append("2>");
+ commandString.append(errorFile).append(" ");
+
+ builderParameters.add(commandString.toString());
+
+ LOG.info("ServiceAdvisor. Python command is: " + builderParameters.toString());
+
+ return new ProcessBuilder(builderParameters);
+ }
+
+ /**
+ * Launch a process, wait for it to finish, and return its exit code.
+ * @param builder Process Builder
+ * @return Exit Code
+ * @throws Exception
+ */
+ private static int launchProcess(ProcessBuilder builder) throws Exception {
+ int exitCode = -1;
+ Process process = null;
+ try {
+ process = builder.start();
+ exitCode = process.waitFor();
+ } catch (Exception ioe) {
+ String message = "Error executing Service Advisor: ";
+ LOG.error(message, ioe);
+ throw new Exception(message + ioe.getMessage());
+ } finally {
+ if (process != null) {
+ process.destroy();
+ }
+ }
+ return exitCode;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisorCommandType.java
----------------------------------------------------------------------
diff --git a/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisorCommandType.java b/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisorCommandType.java
new file mode 100644
index 0000000..f067668
--- /dev/null
+++ b/serviceadvisor/src/main/java/org/apache/ambari/serviceadvisor/ServiceAdvisorCommandType.java
@@ -0,0 +1,63 @@
+/**
+ * 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.serviceadvisor;
+
+
+// TODO, use this class instead of org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommandType
+public enum ServiceAdvisorCommandType {
+
+ RECOMMEND_COMPONENT_LAYOUT("recommend-component-layout"),
+
+ VALIDATE_COMPONENT_LAYOUT("validate-component-layout"),
+
+ RECOMMEND_CONFIGURATIONS("recommend-configurations"),
+
+ RECOMMEND_CONFIGURATION_DEPENDENCIES("recommend-configuration-dependencies"),
+
+ VALIDATE_CONFIGURATIONS("validate-configurations");
+ private final String name;
+
+ private ServiceAdvisorCommandType(String name) {
+ this.name = name;
+ }
+
+ public String getValue() {
+ return this.name.toLowerCase();
+ }
+
+ @Override
+ public String toString() {
+ return this.name;
+ }
+
+ /**
+ * Instead of Enum.valueOf("value"), use this method instead to map the string to the correct Enum.
+ * @param name Name with lowercase and dashes.
+ * @return Enum that matches the string.
+ */
+ public static ServiceAdvisorCommandType getEnum(String name) {
+ for (ServiceAdvisorCommandType v : values()) {
+ if (v.getValue().equalsIgnoreCase(name.replace("_", "-"))) {
+ return v;
+ }
+ }
+ throw new IllegalArgumentException();
+ }
+}
\ No newline at end of file