AMBARI-20853. Service Advisor - Allow Service to define its Advisor Type as Python or Java (alejandro)
Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/f1ca09c0 Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/f1ca09c0 Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/f1ca09c0 Branch: refs/heads/trunk Commit: f1ca09c03a2fe316129aa5623c675b62d3177112 Parents: acc12fb Author: Alejandro Fernandez <afernan...@hortonworks.com> Authored: Mon Jun 5 15:24:49 2017 -0700 Committer: Alejandro Fernandez <afernan...@hortonworks.com> Committed: Mon Jun 12 13:02:59 2017 -0700 ---------------------------------------------------------------------- ambari-client/groovy-client/pom.xml | 2 + ambari-funtest/pom.xml | 2 + ambari-infra/ambari-infra-solr-client/pom.xml | 2 + .../ambari-logsearch-config-api/pom.xml | 2 +- .../ambari-logsearch-config-zookeeper/pom.xml | 2 +- ambari-logsearch/ambari-logsearch-it/pom.xml | 4 +- .../ambari-logsearch-logfeeder/pom.xml | 4 +- .../ambari-metrics-timelineservice/pom.xml | 4 +- ambari-project/pom.xml | 4 +- ambari-server/checkstyle.xml | 4 + ambari-server/pom.xml | 25 ++- .../stackadvisor/StackAdvisorHelper.java | 74 +++++-- .../stackadvisor/StackAdvisorRunner.java | 207 ++++++++++++------- .../ComponentLayoutRecommendationCommand.java | 5 +- .../ComponentLayoutValidationCommand.java | 11 +- ...rationDependenciesRecommendationCommand.java | 11 +- .../ConfigurationRecommendationCommand.java | 11 +- .../ConfigurationValidationCommand.java | 11 +- .../commands/StackAdvisorCommand.java | 15 +- .../ambari/server/stack/ServiceModule.java | 4 + .../apache/ambari/server/state/ServiceInfo.java | 26 ++- .../stackadvisor/StackAdvisorHelperTest.java | 63 ++++-- .../stackadvisor/StackAdvisorRunnerTest.java | 10 +- .../ConfigurationRecommendationCommandTest.java | 3 +- .../commands/StackAdvisorCommandTest.java | 47 ++--- .../ambari/server/stack/ServiceModuleTest.java | 31 +++ ambari-views/examples/weather-view/pom.xml | 2 +- contrib/views/hawq/pom.xml | 2 +- contrib/views/hive-next/pom.xml | 4 +- contrib/views/hive20/pom.xml | 4 +- contrib/views/pig/pom.xml | 2 +- contrib/views/tez/pom.xml | 3 +- contrib/views/wfmanager/pom.xml | 1 + pom.xml | 17 +- serviceadvisor/pom.xml | 103 +++++++++ .../ambari/serviceadvisor/ServiceAdvisor.java | 147 +++++++++++++ .../ServiceAdvisorCommandType.java | 63 ++++++ 37 files changed, 756 insertions(+), 176 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-client/groovy-client/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-client/groovy-client/pom.xml b/ambari-client/groovy-client/pom.xml index fa89a73..8fafdec 100644 --- a/ambari-client/groovy-client/pom.xml +++ b/ambari-client/groovy-client/pom.xml @@ -29,10 +29,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.codehaus.groovy</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-funtest/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-funtest/pom.xml b/ambari-funtest/pom.xml index 66678c2..3738106 100644 --- a/ambari-funtest/pom.xml +++ b/ambari-funtest/pom.xml @@ -266,10 +266,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>log4j</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-infra/ambari-infra-solr-client/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-infra/ambari-infra-solr-client/pom.xml b/ambari-infra/ambari-infra-solr-client/pom.xml index 8cb2248..d103003 100644 --- a/ambari-infra/ambari-infra-solr-client/pom.xml +++ b/ambari-infra/ambari-infra-solr-client/pom.xml @@ -60,10 +60,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>log4j</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-logsearch/ambari-logsearch-config-api/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-config-api/pom.xml b/ambari-logsearch/ambari-logsearch-config-api/pom.xml index 5355906..59286a6 100644 --- a/ambari-logsearch/ambari-logsearch-config-api/pom.xml +++ b/ambari-logsearch/ambari-logsearch-config-api/pom.xml @@ -43,7 +43,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>1.7.20</version> </dependency> </dependencies> </project> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-logsearch/ambari-logsearch-config-zookeeper/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-config-zookeeper/pom.xml b/ambari-logsearch/ambari-logsearch-config-zookeeper/pom.xml index 7ecda60..4e9964c 100644 --- a/ambari-logsearch/ambari-logsearch-config-zookeeper/pom.xml +++ b/ambari-logsearch/ambari-logsearch-config-zookeeper/pom.xml @@ -73,7 +73,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-logsearch/ambari-logsearch-it/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-it/pom.xml b/ambari-logsearch/ambari-logsearch-it/pom.xml index 81af9e8..db3e09f 100644 --- a/ambari-logsearch/ambari-logsearch-it/pom.xml +++ b/ambari-logsearch/ambari-logsearch-it/pom.xml @@ -81,12 +81,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>1.7.10</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>com.flipkart.zjsonpatch</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml index ddef52f..ce784cb 100644 --- a/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml +++ b/ambari-logsearch/ambari-logsearch-logfeeder/pom.xml @@ -99,12 +99,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.7</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>1.7.10</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-metrics/ambari-metrics-timelineservice/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-metrics/ambari-metrics-timelineservice/pom.xml b/ambari-metrics/ambari-metrics-timelineservice/pom.xml index f9d7e19..3419f16 100644 --- a/ambari-metrics/ambari-metrics-timelineservice/pom.xml +++ b/ambari-metrics/ambari-metrics-timelineservice/pom.xml @@ -568,13 +568,13 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.2</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>1.7.2</version> + <version>1.7.20</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-project/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-project/pom.xml b/ambari-project/pom.xml index 64d1416..9bb2e26 100644 --- a/ambari-project/pom.xml +++ b/ambari-project/pom.xml @@ -210,12 +210,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.2</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> - <version>1.7.2</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.eclipse.persistence</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/checkstyle.xml ---------------------------------------------------------------------- diff --git a/ambari-server/checkstyle.xml b/ambari-server/checkstyle.xml index 6b4824a..97fdc2a 100644 --- a/ambari-server/checkstyle.xml +++ b/ambari-server/checkstyle.xml @@ -11,6 +11,10 @@ "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> <module name="Checker"> + <!-- Checkstyle binds to phase "validate" by default. + Run independently as, cd ambari-server ; mvn checkstyle:checkstyle + Or can skip as, mvn ... -Dcheckstyle.skip + --> <module name="TreeWalker"> <module name="AvoidTransactionalOnPrivateMethodsCheck"/> <!-- <module name="UndocumentedRestApiOperationCheck"/> Swagger - uncomment when API documentation is done --> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-server/pom.xml b/ambari-server/pom.xml index d2b65af..a1cd239 100644 --- a/ambari-server/pom.xml +++ b/ambari-server/pom.xml @@ -837,6 +837,10 @@ <artifactId>jetty-maven-plugin</artifactId> <version>${jetty.version}</version> </plugin> + <!-- Checkstyle binds to phase "validate" by default. + Run independently as, cd ambari-server ; mvn checkstyle:checkstyle + Or can skip as, mvn ... -Dcheckstyle.skip + --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-checkstyle-plugin</artifactId> @@ -1287,10 +1291,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>log4j</groupId> @@ -1354,6 +1360,12 @@ <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> + <version>2.6</version> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + <version>3.1</version> </dependency> <dependency> <groupId>commons-net</groupId> @@ -1641,7 +1653,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> - <version>1.7.2</version> + <version>1.7.20</version> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>io.dropwizard.metrics</groupId> @@ -1653,6 +1670,12 @@ <artifactId>metrics-jvm</artifactId> <version>3.1.0</version> </dependency> + + <dependency> + <groupId>serviceadvisor</groupId> + <artifactId>serviceadvisor</artifactId> + <version>1.0.0.0-SNAPSHOT</version> + </dependency> <!-- Dependency in order to annotate unit tests with a category. --> <dependency> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java index 3083d9f..3e5599c 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelper.java @@ -21,6 +21,7 @@ package org.apache.ambari.server.api.services.stackadvisor; import java.io.File; import java.io.IOException; +import org.apache.ambari.server.AmbariException; import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest.StackAdvisorRequestType; import org.apache.ambari.server.api.services.stackadvisor.commands.ComponentLayoutRecommendationCommand; @@ -33,16 +34,23 @@ import org.apache.ambari.server.api.services.stackadvisor.recommendations.Recomm import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse; import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.state.ServiceInfo; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + import com.google.inject.Inject; import com.google.inject.Singleton; + @Singleton public class StackAdvisorHelper { + protected static Log LOG = LogFactory.getLog(StackAdvisorHelper.class); + private File recommendationsDir; private String recommendationsArtifactsLifetime; private int recommendationsArtifactsRolloverMax; - private String stackAdvisorScript; + public static String pythonStackAdvisorScript; private final AmbariMetaInfo metaInfo; /* Monotonically increasing requestid */ @@ -55,7 +63,8 @@ public class StackAdvisorHelper { this.recommendationsDir = conf.getRecommendationsDir(); this.recommendationsArtifactsLifetime = conf.getRecommendationsArtifactsLifetime(); this.recommendationsArtifactsRolloverMax = conf.getRecommendationsArtifactsRolloverMax(); - this.stackAdvisorScript = conf.getStackAdvisorScript(); + + this.pythonStackAdvisorScript = conf.getStackAdvisorScript(); this.saRunner = saRunner; this.metaInfo = metaInfo; } @@ -72,20 +81,26 @@ public class StackAdvisorHelper { throws StackAdvisorException { requestId = generateRequestId(); - StackAdvisorCommand<ValidationResponse> command = createValidationCommand(request - .getRequestType()); + // TODO, need frontend to pass the Service Name that was modified. + // For now, hardcode. + // Once fixed, change StackAdvisorHelperTest.java to use the actual service name. + String serviceName = "ZOOKEEPER"; + ServiceInfo.ServiceAdvisorType serviceAdvisorType = getServiceAdvisorType(request.getStackName(), request.getStackVersion(), serviceName); + StackAdvisorCommand<ValidationResponse> command = createValidationCommand(serviceName, request); - return command.invoke(request); + return command.invoke(request, serviceAdvisorType); } - StackAdvisorCommand<ValidationResponse> createValidationCommand( - StackAdvisorRequestType requestType) throws StackAdvisorException { + StackAdvisorCommand<ValidationResponse> createValidationCommand(String serviceName, StackAdvisorRequest request) throws StackAdvisorException { + StackAdvisorRequestType requestType = request.getRequestType(); + ServiceInfo.ServiceAdvisorType serviceAdvisorType = getServiceAdvisorType(request.getStackName(), request.getStackVersion(), serviceName); + StackAdvisorCommand<ValidationResponse> command; if (requestType == StackAdvisorRequestType.HOST_GROUPS) { - command = new ComponentLayoutValidationCommand(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, + command = new ComponentLayoutValidationCommand(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } else if (requestType == StackAdvisorRequestType.CONFIGURATIONS) { - command = new ConfigurationValidationCommand(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, + command = new ConfigurationValidationCommand(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } else { throw new StackAdvisorRequestException(String.format("Unsupported request type, type=%s", @@ -107,23 +122,29 @@ public class StackAdvisorHelper { throws StackAdvisorException { requestId = generateRequestId(); - StackAdvisorCommand<RecommendationResponse> command = createRecommendationCommand(request - .getRequestType()); + // TODO, need to pass the service Name that was modified. + // For now, hardcode + String serviceName = "ZOOKEEPER"; + + ServiceInfo.ServiceAdvisorType serviceAdvisorType = getServiceAdvisorType(request.getStackName(), request.getStackVersion(), serviceName); + StackAdvisorCommand<RecommendationResponse> command = createRecommendationCommand(serviceName, request); - return command.invoke(request); + return command.invoke(request, serviceAdvisorType); } - StackAdvisorCommand<RecommendationResponse> createRecommendationCommand( - StackAdvisorRequestType requestType) throws StackAdvisorException { + StackAdvisorCommand<RecommendationResponse> createRecommendationCommand(String serviceName, StackAdvisorRequest request) throws StackAdvisorException { + StackAdvisorRequestType requestType = request.getRequestType(); + ServiceInfo.ServiceAdvisorType serviceAdvisorType = getServiceAdvisorType(request.getStackName(), request.getStackVersion(), serviceName); + StackAdvisorCommand<RecommendationResponse> command; if (requestType == StackAdvisorRequestType.HOST_GROUPS) { - command = new ComponentLayoutRecommendationCommand(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, + command = new ComponentLayoutRecommendationCommand(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } else if (requestType == StackAdvisorRequestType.CONFIGURATIONS) { - command = new ConfigurationRecommendationCommand(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, + command = new ConfigurationRecommendationCommand(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } else if (requestType == StackAdvisorRequestType.CONFIGURATION_DEPENDENCIES) { - command = new ConfigurationDependenciesRecommendationCommand(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, + command = new ConfigurationDependenciesRecommendationCommand(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } else { throw new StackAdvisorRequestException(String.format("Unsupported request type, type=%s", @@ -134,6 +155,25 @@ public class StackAdvisorHelper { } /** + * Get the Service Advisor type that the service defines for the specified stack and version. If an error, return null. + * @param stackName Stack Name + * @param stackVersion Stack Version + * @param serviceName Service Name + * @return Service Advisor type for that Stack, Version, and Service + */ + private ServiceInfo.ServiceAdvisorType getServiceAdvisorType(String stackName, String stackVersion, String serviceName) { + try { + ServiceInfo service = metaInfo.getService(stackName, stackVersion, serviceName); + ServiceInfo.ServiceAdvisorType serviceAdvisorType = service.getServiceAdvisorType(); + + return serviceAdvisorType; + } catch (AmbariException e) { + ; + } + return null; + } + + /** * Returns an incremented requestId. Rollsover back to 0 in case the requestId >= recommendationsArtifactsrollovermax * @return {int requestId} */ http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunner.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunner.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunner.java index a4b7915..90b95b3 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunner.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunner.java @@ -24,123 +24,190 @@ import java.util.ArrayList; import java.util.List; import org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommandType; +import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.state.ServiceInfo; import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.google.inject.Inject; import com.google.inject.Singleton; + @Singleton public class StackAdvisorRunner { private final static Logger LOG = LoggerFactory.getLogger(StackAdvisorRunner.class); + @Inject + private Configuration configs; + /** * Runs stack_advisor.py script in the specified {@code actionDirectory}. * - * @param script stack advisor script + * @param serviceAdvisorType PYTHON or JAVA * @param saCommandType {@link StackAdvisorCommandType} to run. * @param actionDirectory directory for the action */ - public void runScript(String script, StackAdvisorCommandType saCommandType, File actionDirectory) + public void runScript(ServiceInfo.ServiceAdvisorType serviceAdvisorType, StackAdvisorCommandType saCommandType, File actionDirectory) throws StackAdvisorException { - LOG.info(String.format("Script=%s, actionDirectory=%s, command=%s", script, actionDirectory, + LOG.info(String.format("StackAdvisorRunner. serviceAdvisorType=%s, actionDirectory=%s, command=%s", serviceAdvisorType.toString(), actionDirectory, saCommandType)); String outputFile = actionDirectory + File.separator + "stackadvisor.out"; String errorFile = actionDirectory + File.separator + "stackadvisor.err"; - ProcessBuilder builder = prepareShellCommand(script, saCommandType, - actionDirectory, outputFile, - errorFile); + String hostsFile = actionDirectory + File.separator + "hosts.json"; + String servicesFile = actionDirectory + File.separator + "services.json"; + + LOG.info("StackAdvisorRunner. Expected files: hosts.json={}, services.json={}, output={}, error={}", hostsFile, servicesFile, outputFile, errorFile); + + int stackAdvisorReturnCode = -1; + + switch (serviceAdvisorType) { + case JAVA: + org.apache.ambari.serviceadvisor.ServiceAdvisor serviceAdvisor = new org.apache.ambari.serviceadvisor.ServiceAdvisor(); + + LOG.info("StackAdvisorRunner.runScript(): Calling Java ServiceAdvisor's run method."); + stackAdvisorReturnCode = serviceAdvisor.run(saCommandType.toString(), hostsFile, servicesFile, outputFile, errorFile); + LOG.info(String.format("StackAdvisorRunner.runScript(): Java ServiceAdvisor's return code: %d", stackAdvisorReturnCode)); + break; + case PYTHON: + LOG.info("StackAdvisorRunner.runScript(): Calling Python Stack Advisor."); + ProcessBuilder builder = prepareShellCommand(ServiceInfo.ServiceAdvisorType.PYTHON, StackAdvisorHelper.pythonStackAdvisorScript, saCommandType, + actionDirectory, outputFile, + errorFile); + stackAdvisorReturnCode = launchProcess(builder); + break; + } + + // For both Python and Java, need to process log files for now. + processLogs(stackAdvisorReturnCode, outputFile, errorFile); + } + /** + * Launch a process, wait for it to finish, and return its exit code. + * @param builder Process Builder + * @return + * @throws StackAdvisorException + */ + private int launchProcess(ProcessBuilder builder) throws StackAdvisorException { + int exitCode = -1; + Process process = null; try { - Process process = builder.start(); - - try { - LOG.info("Stack-advisor output={}, error={}", outputFile, errorFile); - - int exitCode = process.waitFor(); - String outMessage; - String errMessage = null; - try { - outMessage = FileUtils.readFileToString(new File(outputFile)).trim(); - errMessage = FileUtils.readFileToString(new File(errorFile)).trim(); - LOG.info("Stack advisor output files"); - LOG.info(" advisor script stdout: {}", outMessage); - LOG.info(" advisor script stderr: {}", errMessage); - } catch (IOException io) { - LOG.error("Error in reading script log files", io); - } - if (exitCode > 0) { - String errorMessage; - if (errMessage != null) { - // We want to get the last line. - int index = errMessage.lastIndexOf("\n"); - if (index > 0 && index == (errMessage.length() - 1)) { - index = errMessage.lastIndexOf("\n", index - 1); // sentence ended with newline - } - if (index > -1) { - errMessage = errMessage.substring(index + 1).trim(); - } - errorMessage = "Stack Advisor reported an error: " + errMessage; - } else { - errorMessage = "Error occurred during stack advisor execution"; + process = builder.start(); + exitCode = process.waitFor(); + } catch (Exception ioe) { + String message = "Error executing Stack Advisor: "; + LOG.error(message, ioe); + throw new StackAdvisorException(message + ioe.getMessage()); + } finally { + if (process != null) { + process.destroy(); + } + } + return exitCode; + } + + /** + * Process the exit code and logs. If non-zero then parse the log files and raise the appropriate exception. + * @param exitCode Process exit code + * @param outputFile Path to output file + * @param errorFile Path to error file + * @throws StackAdvisorException + */ + private void processLogs(int exitCode, String outputFile, String errorFile) throws StackAdvisorException { + String outMessage = printMessage("stdout", outputFile); + String errMessage = printMessage("stderr", errorFile); + + try { + if (exitCode != 0) { + String errorMessage; + if (errMessage != null) { + // We want to get the last line. + int index = errMessage.lastIndexOf("\n"); + if (index > 0 && index == (errMessage.length() - 1)) { + index = errMessage.lastIndexOf("\n", index - 1); // sentence ended with newline } - errorMessage += "\nStdOut file: " + outputFile + "\n"; - errorMessage += "\nStdErr file: " + errorFile; - switch (exitCode) { - case 1: - throw new StackAdvisorRequestException(errorMessage); - case 2: - throw new StackAdvisorException(errorMessage); + if (index > -1) { + errMessage = errMessage.substring(index + 1).trim(); } + errorMessage = String.format("Stack Advisor reported an error. Exit Code: %s. Error: %s ", exitCode, errMessage); + } else { + errorMessage = String.format("Error occurred during Stack Advisor execution. Exit Code: %s", exitCode); + } + errorMessage += "\nStdOut file: " + outputFile + "\n"; + errorMessage += "\nStdErr file: " + errorFile; + switch (exitCode) { + case 1: + throw new StackAdvisorRequestException(errorMessage); + case 2: + throw new StackAdvisorException(errorMessage); } - } finally { - process.destroy(); } } catch (StackAdvisorException ex) { throw ex; - } catch (Exception ioe) { - String message = "Error executing stack advisor: "; - LOG.error(message, ioe); - throw new StackAdvisorException(message + ioe.getMessage()); } } /** + * Logs messages from the output/error file. + * @param type Severity type, stdout or stderr + * @param file File path + * @return File to a String + */ + private String printMessage(String type, String file) { + String message = null; + try { + message = FileUtils.readFileToString(new File(file)).trim(); + LOG.info(" Advisor script {}: {}", type, message); + } catch (IOException io) { + LOG.error("Error in reading script log files", io); + } + return message; + } + + /** * Gets an instance of a {@link ProcessBuilder} that's ready to execute the * shell command to run the stack advisor script. This will take the * environment variables from the current process. * - * @param script - * @param saCommandType - * @param actionDirectory - * @param outputFile - * @param errorFile - * @return + * @param serviceAdvisorType Python or Java + * @param script Python script or jar path + * @param saCommandType command type such as validate, configure + * @param actionDirectory Directory that contains hosts.json, services.json, and output files + * @param outputFile Output file path + * @param errorFile Error file path + * @return Process that can launch */ - ProcessBuilder prepareShellCommand(String script, - StackAdvisorCommandType saCommandType, - File actionDirectory, String outputFile, String errorFile) { + ProcessBuilder prepareShellCommand(ServiceInfo.ServiceAdvisorType serviceAdvisorType, String script, + StackAdvisorCommandType saCommandType, + File actionDirectory, String outputFile, String errorFile) { String hostsFile = actionDirectory + File.separator + "hosts.json"; String servicesFile = actionDirectory + File.separator + "services.json"; // includes the original command plus the arguments for it - List<String> builderParameters = new ArrayList<>(); - if (System.getProperty("os.name").contains("Windows")) { - builderParameters.add("cmd"); - builderParameters.add("/c"); - } else { - builderParameters.add("sh"); - builderParameters.add("-c"); + List<String> builderParameters = new ArrayList<String>(); + + switch (serviceAdvisorType) { + case PYTHON: + case JAVA: + if (System.getProperty("os.name").contains("Windows")) { + builderParameters.add("cmd"); + builderParameters.add("/c"); + } else { + builderParameters.add("sh"); + builderParameters.add("-c"); + } + break; + default: + break; } // for the 3rd argument, build a single parameter since we use -c // ProcessBuilder doesn't support output redirection until JDK 1.7 - String commandStringParameters[] = new String[] { script, - saCommandType.toString(), hostsFile, - servicesFile, "1>", outputFile, "2>", errorFile }; + String commandStringParameters[] = new String[] {script, saCommandType.toString(), hostsFile, servicesFile, "1>", outputFile, "2>", errorFile}; StringBuilder commandString = new StringBuilder(); for (String command : commandStringParameters) { @@ -149,7 +216,7 @@ public class StackAdvisorRunner { builderParameters.add(commandString.toString()); - LOG.debug("Stack advisor command is {}", builderParameters); + LOG.debug("StackAdvisorRunner. Stack advisor command is {}", StringUtils.join(" ", builderParameters)); return new ProcessBuilder(builderParameters); } http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java index ca1d95f2..6a0c4d6 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutRecommendationCommand.java @@ -25,6 +25,7 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; +import org.apache.ambari.server.state.ServiceInfo; /** * {@link StackAdvisorCommand} implementation for component-layout @@ -35,11 +36,11 @@ public class ComponentLayoutRecommendationCommand extends public ComponentLayoutRecommendationCommand(File recommendationsDir, String recommendationsArtifactsLifetime, - String stackAdvisorScript, + ServiceInfo.ServiceAdvisorType serviceAdvisorType, int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { - super(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo); + super(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java index 91d8f9c..feba22e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ComponentLayoutValidationCommand.java @@ -25,15 +25,20 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse; +import org.apache.ambari.server.state.ServiceInfo; /** * {@link StackAdvisorCommand} implementation for component-layout validation. */ public class ComponentLayoutValidationCommand extends StackAdvisorCommand<ValidationResponse> { - public ComponentLayoutValidationCommand(File recommendationsDir, String recommendationsArtifactsLifetime, String stackAdvisorScript, - int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { - super(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo); + public ComponentLayoutValidationCommand(File recommendationsDir, + String recommendationsArtifactsLifetime, + ServiceInfo.ServiceAdvisorType serviceAdvisorType, + int requestId, + StackAdvisorRunner saRunner, + AmbariMetaInfo metaInfo) { + super(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java index fae0b16..83a6306 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationDependenciesRecommendationCommand.java @@ -32,6 +32,7 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; +import org.apache.ambari.server.state.ServiceInfo; /** * {@link StackAdvisorCommand} implementation for @@ -40,9 +41,13 @@ import org.apache.ambari.server.api.services.stackadvisor.recommendations.Recomm public class ConfigurationDependenciesRecommendationCommand extends StackAdvisorCommand<RecommendationResponse> { - public ConfigurationDependenciesRecommendationCommand(File recommendationsDir, String recommendationsArtifactsLifetime, String stackAdvisorScript, int requestId, - StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { - super(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo); + public ConfigurationDependenciesRecommendationCommand(File recommendationsDir, + String recommendationsArtifactsLifetime, + ServiceInfo.ServiceAdvisorType serviceAdvisorType, + int requestId, + StackAdvisorRunner saRunner, + AmbariMetaInfo metaInfo) { + super(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java index e25e39b..7ac3fdb 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommand.java @@ -32,6 +32,7 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; +import org.apache.ambari.server.state.ServiceInfo; /** * {@link org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand} implementation for @@ -40,9 +41,13 @@ import org.apache.ambari.server.api.services.stackadvisor.recommendations.Recomm public class ConfigurationRecommendationCommand extends StackAdvisorCommand<RecommendationResponse> { - public ConfigurationRecommendationCommand(File recommendationsDir, String recommendationsArtifactsLifetime, String stackAdvisorScript, int requestId, - StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { - super(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo); + public ConfigurationRecommendationCommand(File recommendationsDir, + String recommendationsArtifactsLifetime, + ServiceInfo.ServiceAdvisorType serviceAdvisorType, + int requestId, + StackAdvisorRunner saRunner, + AmbariMetaInfo metaInfo) { + super(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java index 1892a82..1b6b703 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationValidationCommand.java @@ -25,15 +25,20 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorException; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse; +import org.apache.ambari.server.state.ServiceInfo; /** * {@link StackAdvisorCommand} implementation for configuration validation. */ public class ConfigurationValidationCommand extends StackAdvisorCommand<ValidationResponse> { - public ConfigurationValidationCommand(File recommendationsDir, String recommendationsArtifactsLifetime, String stackAdvisorScript, - int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { - super(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo); + public ConfigurationValidationCommand(File recommendationsDir, + String recommendationsArtifactsLifetime, + ServiceInfo.ServiceAdvisorType serviceAdvisorType, + int requestId, + StackAdvisorRunner saRunner, + AmbariMetaInfo metaInfo) { + super(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java index c2895d9..356754d 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommand.java @@ -67,7 +67,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend /** * Type of response object provided by extending classes when - * {@link #invoke(StackAdvisorRequest)} is called. + * {@link #invoke(StackAdvisorRequest, ServiceInfo.ServiceAdvisorType)} is called. */ private Class<T> type; @@ -98,7 +98,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend private File recommendationsDir; private String recommendationsArtifactsLifetime; - private String stackAdvisorScript; + private ServiceInfo.ServiceAdvisorType serviceAdvisorType; private int requestId; private File requestDirectory; @@ -109,7 +109,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend private final AmbariMetaInfo metaInfo; @SuppressWarnings("unchecked") - public StackAdvisorCommand(File recommendationsDir, String recommendationsArtifactsLifetime, String stackAdvisorScript, int requestId, + public StackAdvisorCommand(File recommendationsDir, String recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType serviceAdvisorType, int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { this.type = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]; @@ -119,7 +119,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend this.recommendationsDir = recommendationsDir; this.recommendationsArtifactsLifetime = recommendationsArtifactsLifetime; - this.stackAdvisorScript = stackAdvisorScript; + this.serviceAdvisorType = serviceAdvisorType; this.requestId = requestId; this.saRunner = saRunner; this.metaInfo = metaInfo; @@ -278,7 +278,7 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend } } - public synchronized T invoke(StackAdvisorRequest request) throws StackAdvisorException { + public synchronized T invoke(StackAdvisorRequest request, ServiceInfo.ServiceAdvisorType serviceAdvisorType) throws StackAdvisorException { validate(request); String hostsJSON = getHostsInformation(request); String servicesJSON = getServicesInformation(request); @@ -289,10 +289,9 @@ public abstract class StackAdvisorCommand<T extends StackAdvisorResponse> extend createRequestDirectory(); FileUtils.writeStringToFile(new File(requestDirectory, "hosts.json"), adjusted.hostsJSON); - FileUtils.writeStringToFile(new File(requestDirectory, "services.json"), - adjusted.servicesJSON); + FileUtils.writeStringToFile(new File(requestDirectory, "services.json"), adjusted.servicesJSON); - saRunner.runScript(stackAdvisorScript, getCommandType(), requestDirectory); + saRunner.runScript(serviceAdvisorType, getCommandType(), requestDirectory); String result = FileUtils.readFileToString(new File(requestDirectory, getResultFileName())); T response = this.mapper.readValue(result, this.type); http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java index e41d3b2..2b4398b 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ServiceModule.java @@ -205,6 +205,10 @@ public class ServiceModule extends BaseModule<ServiceModule, ServiceInfo> implem if (serviceInfo.getDisplayName() == null) { serviceInfo.setDisplayName(parent.getDisplayName()); } + if (serviceInfo.getServiceAdvisorType() == null) { + ServiceInfo.ServiceAdvisorType serviceAdvisorType = parent.getServiceAdvisorType(); + serviceInfo.setServiceAdvisorType(serviceAdvisorType == null ? ServiceInfo.ServiceAdvisorType.PYTHON : serviceAdvisorType); + } if (serviceInfo.getVersion() == null) { serviceInfo.setVersion(parent.getVersion()); } http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java index 97490e0..325434e 100644 --- a/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java +++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ServiceInfo.java @@ -36,6 +36,8 @@ import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlElements; +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlEnumValue; import javax.xml.bind.annotation.XmlTransient; import org.apache.ambari.server.api.services.AmbariMetaInfo; @@ -72,6 +74,20 @@ public class ServiceInfo implements Validable{ private String serviceType; private Selection selection; + /** + * Default to Python if not specified. + */ + + @XmlEnum + public enum ServiceAdvisorType { + @XmlEnumValue("PYTHON") + PYTHON, + @XmlEnumValue("JAVA") + JAVA + } + @XmlElement(name="service_advisor_type") + private ServiceAdvisorType serviceAdvisorType = null; + @XmlTransient private List<PropertyInfo> properties; @@ -341,6 +357,14 @@ public class ServiceInfo implements Validable{ this.displayName = displayName; } + public void setServiceAdvisorType(ServiceAdvisorType type) { + this.serviceAdvisorType = type; + } + + public ServiceAdvisorType getServiceAdvisorType() { + return serviceAdvisorType; + } + public String getServiceType() { return serviceType; } @@ -349,7 +373,7 @@ public class ServiceInfo implements Validable{ this.serviceType = serviceType; } -public String getVersion() { + public String getVersion() { return version; } http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java index e331ddd..cedf3a2 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorHelperTest.java @@ -38,12 +38,15 @@ import org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorC import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; import org.apache.ambari.server.api.services.stackadvisor.validations.ValidationResponse; import org.apache.ambari.server.configuration.Configuration; +import org.apache.ambari.server.state.ServiceInfo; import org.junit.Test; +import org.mockito.Mockito; /** * StackAdvisorHelper unit tests. */ public class StackAdvisorHelperTest { + @Test @SuppressWarnings("unchecked") public void testValidate_returnsCommandResult() throws StackAdvisorException, IOException { @@ -51,19 +54,21 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = spy(new StackAdvisorHelper(configuration, saRunner, metaInfo)); StackAdvisorCommand<ValidationResponse> command = mock(StackAdvisorCommand.class); ValidationResponse expected = mock(ValidationResponse.class); + StackAdvisorRequestType requestType = StackAdvisorRequestType.HOST_GROUPS; StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .ofType(requestType).build(); - when(command.invoke(request)).thenReturn(expected); - doReturn(command).when(helper).createValidationCommand(requestType); - + when(command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON)).thenReturn(expected); + doReturn(command).when(helper).createValidationCommand("ZOOKEEPER", request); ValidationResponse response = helper.validate(request); - assertEquals(expected, response); } @@ -75,6 +80,9 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = spy(new StackAdvisorHelper(configuration, saRunner, metaInfo)); StackAdvisorCommand<ValidationResponse> command = mock(StackAdvisorCommand.class); @@ -82,8 +90,8 @@ public class StackAdvisorHelperTest { StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .ofType(requestType).build(); - when(command.invoke(request)).thenThrow(new StackAdvisorException("message")); - doReturn(command).when(helper).createValidationCommand(requestType); + when(command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON)).thenThrow(new StackAdvisorException("message")); + doReturn(command).when(helper).createValidationCommand("ZOOKEEPER", request); helper.validate(request); assertTrue(false); @@ -96,6 +104,9 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = spy(new StackAdvisorHelper(configuration, saRunner, metaInfo)); StackAdvisorCommand<RecommendationResponse> command = mock(StackAdvisorCommand.class); @@ -104,8 +115,8 @@ public class StackAdvisorHelperTest { StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .ofType(requestType).build(); - when(command.invoke(request)).thenReturn(expected); - doReturn(command).when(helper).createRecommendationCommand(requestType); + when(command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON)).thenReturn(expected); + doReturn(command).when(helper).createRecommendationCommand("ZOOKEEPER", request); RecommendationResponse response = helper.recommend(request); assertEquals(expected, response); @@ -119,6 +130,9 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = spy(new StackAdvisorHelper(configuration, saRunner, metaInfo)); StackAdvisorCommand<RecommendationResponse> command = mock(StackAdvisorCommand.class); @@ -126,8 +140,8 @@ public class StackAdvisorHelperTest { StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .ofType(requestType).build(); - when(command.invoke(request)).thenThrow(new StackAdvisorException("message")); - doReturn(command).when(helper).createRecommendationCommand(requestType); + when(command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON)).thenThrow(new StackAdvisorException("message")); + doReturn(command).when(helper).createRecommendationCommand("ZOOKEEPER", request); helper.recommend(request); assertTrue(false); @@ -140,11 +154,16 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = new StackAdvisorHelper(configuration, saRunner, metaInfo); StackAdvisorRequestType requestType = StackAdvisorRequestType.HOST_GROUPS; + StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") + .ofType(requestType).build(); StackAdvisorCommand<RecommendationResponse> command = helper - .createRecommendationCommand(requestType); + .createRecommendationCommand("ZOOKEEPER", request); assertEquals(ComponentLayoutRecommendationCommand.class, command.getClass()); } @@ -156,10 +175,15 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = new StackAdvisorHelper(configuration, saRunner, metaInfo); StackAdvisorRequestType requestType = StackAdvisorRequestType.HOST_GROUPS; + StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") + .ofType(requestType).build(); - StackAdvisorCommand<ValidationResponse> command = helper.createValidationCommand(requestType); + StackAdvisorCommand<ValidationResponse> command = helper.createValidationCommand("ZOOKEEPER", request); assertEquals(ComponentLayoutValidationCommand.class, command.getClass()); } @@ -171,10 +195,15 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = new StackAdvisorHelper(configuration, saRunner, metaInfo); StackAdvisorRequestType requestType = StackAdvisorRequestType.CONFIGURATIONS; + StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") + .ofType(requestType).build(); - StackAdvisorCommand<ValidationResponse> command = helper.createValidationCommand(requestType); + StackAdvisorCommand<ValidationResponse> command = helper.createValidationCommand("ZOOKEEPER", request); assertEquals(ConfigurationValidationCommand.class, command.getClass()); } @@ -186,12 +215,16 @@ public class StackAdvisorHelperTest { when(configuration.getRecommendationsArtifactsRolloverMax()).thenReturn(100); StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); + ServiceInfo service = mock(ServiceInfo.class); + when(metaInfo.getService(Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn(service); + when(service.getServiceAdvisorType()).thenReturn(ServiceInfo.ServiceAdvisorType.PYTHON); StackAdvisorHelper helper = new StackAdvisorHelper(configuration, saRunner, metaInfo); StackAdvisorRequestType requestType = StackAdvisorRequestType.CONFIGURATION_DEPENDENCIES; + StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") + .ofType(requestType).build(); - StackAdvisorCommand<RecommendationResponse> command = helper.createRecommendationCommand(requestType); + StackAdvisorCommand<RecommendationResponse> command = helper.createRecommendationCommand("ZOOKEEPER", request); assertEquals(ConfigurationDependenciesRecommendationCommand.class, command.getClass()); } - } http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunnerTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunnerTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunnerTest.java index 8d104ea..7eb9fb4 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunnerTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/StackAdvisorRunnerTest.java @@ -28,6 +28,7 @@ import java.io.File; import java.io.IOException; import org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommandType; +import org.apache.ambari.server.state.ServiceInfo; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -68,7 +69,7 @@ public class StackAdvisorRunnerTest { .toReturn(processBuilder); expect(processBuilder.start()).andThrow(new IOException()); replay(processBuilder); - saRunner.runScript(script, saCommandType, actionDirectory); + saRunner.runScript(ServiceInfo.ServiceAdvisorType.PYTHON, saCommandType, actionDirectory); } @Test(expected = StackAdvisorRequestException.class) @@ -85,7 +86,7 @@ public class StackAdvisorRunnerTest { expect(processBuilder.start()).andReturn(process); expect(process.waitFor()).andReturn(1); replay(processBuilder, process); - saRunner.runScript(script, saCommandType, actionDirectory); + saRunner.runScript(ServiceInfo.ServiceAdvisorType.PYTHON, saCommandType, actionDirectory); } @Test(expected = StackAdvisorException.class) @@ -102,7 +103,7 @@ public class StackAdvisorRunnerTest { expect(processBuilder.start()).andReturn(process); expect(process.waitFor()).andReturn(2); replay(processBuilder, process); - saRunner.runScript(script, saCommandType, actionDirectory); + saRunner.runScript(ServiceInfo.ServiceAdvisorType.PYTHON, saCommandType, actionDirectory); } @Test @@ -120,10 +121,9 @@ public class StackAdvisorRunnerTest { expect(process.waitFor()).andReturn(0); replay(processBuilder, process); try { - saRunner.runScript(script, saCommandType, actionDirectory); + saRunner.runScript(ServiceInfo.ServiceAdvisorType.PYTHON, saCommandType, actionDirectory); } catch (StackAdvisorException ex) { fail("Should not fail with StackAdvisorException"); } } - } http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java index 17293eb..5e373c0 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/ConfigurationRecommendationCommandTest.java @@ -34,6 +34,7 @@ import org.apache.ambari.server.api.services.AmbariMetaInfo; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequest; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.recommendations.RecommendationResponse; +import org.apache.ambari.server.state.ServiceInfo; import org.junit.Test; public class ConfigurationRecommendationCommandTest { @@ -43,7 +44,7 @@ public class ConfigurationRecommendationCommandTest { StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); File file = mock(File.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); - ConfigurationRecommendationCommand command = new ConfigurationRecommendationCommand(file, "1w", "script", 1, saRunner, metaInfo); + ConfigurationRecommendationCommand command = new ConfigurationRecommendationCommand(file, "1w", ServiceInfo.ServiceAdvisorType.PYTHON, 1, saRunner, metaInfo); StackAdvisorRequest request = mock(StackAdvisorRequest.class); Map<String, Set<String>> componentHostGroupMap = new HashMap<>(); http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java index 46552a3..eaa4716 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/api/services/stackadvisor/commands/StackAdvisorCommandTest.java @@ -46,6 +46,7 @@ import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRequestExc import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorResponse; import org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner; import org.apache.ambari.server.api.services.stackadvisor.commands.StackAdvisorCommand.StackAdvisorData; +import org.apache.ambari.server.state.ServiceInfo; import org.apache.commons.io.FileUtils; import org.codehaus.jackson.JsonNode; import org.codehaus.jackson.annotate.JsonProperty; @@ -78,19 +79,18 @@ public class StackAdvisorCommandTest { public void testInvoke_invalidRequest_throwsException() throws StackAdvisorException { File recommendationsDir = temp.newFolder("recommendationDir"); String recommendationsArtifactsLifetime = "1w"; - String stackAdvisorScript = "echo"; int requestId = 0; StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString()); - StackAdvisorCommand<TestResource> command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime, - stackAdvisorScript, requestId, saRunner, metaInfo)); + StackAdvisorCommand<TestResource> command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime, + ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo)); StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .build(); doThrow(new StackAdvisorException("message")).when(command).validate(request); - command.invoke(request); + command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON); assertTrue(false); } @@ -98,14 +98,13 @@ public class StackAdvisorCommandTest { @Test(expected = StackAdvisorException.class) public void testInvoke_saRunnerNotSucceed_throwsException() throws StackAdvisorException { File recommendationsDir = temp.newFolder("recommendationDir"); - String stackAdvisorScript = "echo"; String recommendationsArtifactsLifetime = "1w"; int requestId = 0; StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString()); StackAdvisorCommand<TestResource> command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime, - stackAdvisorScript, requestId, saRunner, metaInfo)); + ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo)); StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .build(); @@ -117,24 +116,23 @@ public class StackAdvisorCommandTest { doReturn(servicesJSON).when(command).getServicesInformation(request); doReturn(data).when(command) .adjust(any(StackAdvisorData.class), any(StackAdvisorRequest.class)); - doThrow(new StackAdvisorRequestException("error")).when(saRunner) - .runScript(any(String.class), any(StackAdvisorCommandType.class), any(File.class)); - command.invoke(request); + doThrow(new StackAdvisorRequestException("error")).when(saRunner) + .runScript(any(ServiceInfo.ServiceAdvisorType.class), any(StackAdvisorCommandType.class), any(File.class)); + command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON); assertTrue(false); } @Test(expected = WebApplicationException.class) public void testInvoke_adjustThrowsException_throwsException() throws StackAdvisorException { File recommendationsDir = temp.newFolder("recommendationDir"); - String stackAdvisorScript = "echo"; String recommendationsArtifactsLifetime = "1w"; int requestId = 0; StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString()); StackAdvisorCommand<TestResource> command = spy(new TestStackAdvisorCommand(recommendationsDir, recommendationsArtifactsLifetime, - stackAdvisorScript, requestId, saRunner, metaInfo)); + ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo)); StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .build(); @@ -143,9 +141,11 @@ public class StackAdvisorCommandTest { doReturn("{\"services\" : \"HDFS\"").when(command).getServicesInformation(request); doThrow(new WebApplicationException()).when(command).adjust(any(StackAdvisorData.class), any(StackAdvisorRequest.class)); + doThrow(new StackAdvisorException("error")).when(saRunner) - .runScript(any(String.class), any(StackAdvisorCommandType.class), any(File.class)); - command.invoke(request); + .runScript(any(ServiceInfo.ServiceAdvisorType.class), any(StackAdvisorCommandType.class), any(File.class)); + command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON); + assertTrue(false); } @@ -155,14 +155,13 @@ public class StackAdvisorCommandTest { String expected = "success"; final String testResourceString = String.format("{\"type\": \"%s\"}", expected); final File recommendationsDir = temp.newFolder("recommendationDir"); - String stackAdvisorScript = "echo"; String recommendationsArtifactsLifetime = "1w"; final int requestId = 2; StackAdvisorRunner saRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo metaInfo = mock(AmbariMetaInfo.class); doReturn(Collections.emptyList()).when(metaInfo).getStackParentVersions(anyString(), anyString()); final StackAdvisorCommand<TestResource> command = spy(new TestStackAdvisorCommand( - recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo)); + recommendationsDir, recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType.PYTHON, requestId, saRunner, metaInfo)); StackAdvisorRequest request = StackAdvisorRequestBuilder.forStack("stackName", "stackVersion") .build(); @@ -174,6 +173,7 @@ public class StackAdvisorCommandTest { doReturn(servicesJSON).when(command).getServicesInformation(request); doReturn(data).when(command) .adjust(any(StackAdvisorData.class), any(StackAdvisorRequest.class)); + doAnswer(new Answer() { public Object answer(InvocationOnMock invocation) throws Throwable { String resultFilePath = String.format("%s/%s", requestId, command.getResultFileName()); @@ -182,8 +182,9 @@ public class StackAdvisorCommandTest { FileUtils.writeStringToFile(resultFile, testResourceString); return null; } - }).when(saRunner).runScript(any(String.class), any(StackAdvisorCommandType.class), any(File.class)); - TestResource result = command.invoke(request); + }).when(saRunner).runScript(any(ServiceInfo.ServiceAdvisorType.class), any(StackAdvisorCommandType.class), any(File.class)); + + TestResource result = command.invoke(request, ServiceInfo.ServiceAdvisorType.PYTHON); assertEquals(expected, result.getType()); assertEquals(requestId, result.getId()); @@ -195,7 +196,7 @@ public class StackAdvisorCommandTest { String recommendationsArtifactsLifetime = "1w"; StackAdvisorRunner stackAdvisorRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo ambariMetaInfo = mock(AmbariMetaInfo.class); - StackAdvisorCommand<TestResource> cmd = new TestStackAdvisorCommand(file, recommendationsArtifactsLifetime, "test", 1, + StackAdvisorCommand<TestResource> cmd = new TestStackAdvisorCommand(file, recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType.PYTHON, 1, stackAdvisorRunner, ambariMetaInfo); ObjectNode objectNode = (ObjectNode) cmd.mapper.readTree("{\"Versions\": " + "{\"stack_name\": \"stack\", \"stack_version\":\"1.0.0\"}}"); @@ -223,7 +224,7 @@ public class StackAdvisorCommandTest { String recommendationsArtifactsLifetime = "1w"; StackAdvisorRunner stackAdvisorRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo ambariMetaInfo = mock(AmbariMetaInfo.class); - StackAdvisorCommand<TestResource> cmd = new TestStackAdvisorCommand(file, recommendationsArtifactsLifetime, "test", 1, + StackAdvisorCommand<TestResource> cmd = new TestStackAdvisorCommand(file, recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType.PYTHON, 1, stackAdvisorRunner, ambariMetaInfo); ObjectNode objectNode = (ObjectNode) cmd.mapper.readTree("{\"Versions\": " + "{\"stack_name\": \"stack\", \"stack_version\":\"1.0.0\"}}"); @@ -245,7 +246,7 @@ public class StackAdvisorCommandTest { String recommendationsArtifactsLifetime = "1w"; StackAdvisorRunner stackAdvisorRunner = mock(StackAdvisorRunner.class); AmbariMetaInfo ambariMetaInfo = mock(AmbariMetaInfo.class); - StackAdvisorCommand<TestResource> cmd = new TestStackAdvisorCommand(file, recommendationsArtifactsLifetime, "test", 1, + StackAdvisorCommand<TestResource> cmd = new TestStackAdvisorCommand(file, recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType.PYTHON, 1, stackAdvisorRunner, ambariMetaInfo); ObjectNode objectNode = (ObjectNode) cmd.mapper.readTree("{\"Versions\": " + "{\"stack_name\": \"stack\", \"stack_version\":\"1.0.0\"}}"); @@ -265,9 +266,9 @@ public class StackAdvisorCommandTest { } class TestStackAdvisorCommand extends StackAdvisorCommand<TestResource> { - public TestStackAdvisorCommand(File recommendationsDir, String recommendationsArtifactsLifetime, String stackAdvisorScript, - int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { - super(recommendationsDir, recommendationsArtifactsLifetime, stackAdvisorScript, requestId, saRunner, metaInfo); + public TestStackAdvisorCommand(File recommendationsDir, String recommendationsArtifactsLifetime, ServiceInfo.ServiceAdvisorType serviceAdvisorType, + int requestId, StackAdvisorRunner saRunner, AmbariMetaInfo metaInfo) { + super(recommendationsDir, recommendationsArtifactsLifetime, serviceAdvisorType, requestId, saRunner, metaInfo); } @Override http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java ---------------------------------------------------------------------- diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java index 20d2168..784d884 100644 --- a/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java +++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ServiceModuleTest.java @@ -439,6 +439,37 @@ public class ServiceModuleTest { } @Test + public void testResolveServiceAdvisor() throws Exception { + ServiceInfo info = new ServiceInfo(); + ServiceInfo parentInfo = new ServiceInfo(); + ServiceModule child = createServiceModule(info); + ServiceModule parent = createServiceModule(parentInfo); + + // Parent is NULL, Child is NULL => Child defaults to PYTHON + parent.getModuleInfo().setServiceAdvisorType(null); + child.getModuleInfo().setServiceAdvisorType(null); + resolveService(child, parent); + assertEquals(ServiceInfo.ServiceAdvisorType.PYTHON, child.getModuleInfo().getServiceAdvisorType()); + + // Parent is NULL, Child is JAVA => Child is JAVA + child.getModuleInfo().setServiceAdvisorType(ServiceInfo.ServiceAdvisorType.JAVA); + resolveService(child, parent); + assertEquals(ServiceInfo.ServiceAdvisorType.JAVA, child.getModuleInfo().getServiceAdvisorType()); + + // Parent is JAVA, Child is NULL => Child inherits JAVA + parent.getModuleInfo().setServiceAdvisorType(ServiceInfo.ServiceAdvisorType.JAVA); + child.getModuleInfo().setServiceAdvisorType(null); + resolveService(child, parent); + assertEquals(ServiceInfo.ServiceAdvisorType.JAVA, child.getModuleInfo().getServiceAdvisorType()); + + // Parent is JAVA, Child is PYTHON => Child overrides and keeps PYTHON + parent.getModuleInfo().setServiceAdvisorType(null); + child.getModuleInfo().setServiceAdvisorType(ServiceInfo.ServiceAdvisorType.PYTHON); + resolveService(child, parent); + assertEquals(ServiceInfo.ServiceAdvisorType.PYTHON, child.getModuleInfo().getServiceAdvisorType()); + } + + @Test public void testResolve_UpgradeCheckDirectory() throws Exception { File checks = new File("checks"); http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/ambari-views/examples/weather-view/pom.xml ---------------------------------------------------------------------- diff --git a/ambari-views/examples/weather-view/pom.xml b/ambari-views/examples/weather-view/pom.xml index abed017..d339fbb 100644 --- a/ambari-views/examples/weather-view/pom.xml +++ b/ambari-views/examples/weather-view/pom.xml @@ -81,7 +81,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.6</version> + <version>1.7.20</version> </dependency> </dependencies> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/contrib/views/hawq/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/hawq/pom.xml b/contrib/views/hawq/pom.xml index 0c6591e..5a6e525 100644 --- a/contrib/views/hawq/pom.xml +++ b/contrib/views/hawq/pom.xml @@ -68,7 +68,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>c3p0</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/contrib/views/hive-next/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/hive-next/pom.xml b/contrib/views/hive-next/pom.xml index 578a82c..9a6c65d 100644 --- a/contrib/views/hive-next/pom.xml +++ b/contrib/views/hive-next/pom.xml @@ -92,12 +92,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> <scope>test</scope> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/contrib/views/hive20/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/hive20/pom.xml b/contrib/views/hive20/pom.xml index 7ea95ad..0da3c88 100644 --- a/contrib/views/hive20/pom.xml +++ b/contrib/views/hive20/pom.xml @@ -93,12 +93,12 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> <scope>test</scope> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/contrib/views/pig/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/pig/pom.xml b/contrib/views/pig/pom.xml index 5239cc2..1430f69 100644 --- a/contrib/views/pig/pom.xml +++ b/contrib/views/pig/pom.xml @@ -80,7 +80,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/contrib/views/tez/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/tez/pom.xml b/contrib/views/tez/pom.xml index 170b89a..fa1a773 100644 --- a/contrib/views/tez/pom.xml +++ b/contrib/views/tez/pom.xml @@ -236,11 +236,10 @@ <groupId>com.google.inject</groupId> <artifactId>guice</artifactId> </dependency> - <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.7.5</version> + <version>1.7.20</version> </dependency> <dependency> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/contrib/views/wfmanager/pom.xml ---------------------------------------------------------------------- diff --git a/contrib/views/wfmanager/pom.xml b/contrib/views/wfmanager/pom.xml index a38cae5..1363a93 100644 --- a/contrib/views/wfmanager/pom.xml +++ b/contrib/views/wfmanager/pom.xml @@ -74,6 +74,7 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> + <version>1.7.20</version> </dependency> <dependency> <groupId>javax.inject</groupId> http://git-wip-us.apache.org/repos/asf/ambari/blob/f1ca09c0/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 8faec29..4e27ca6 100644 --- a/pom.xml +++ b/pom.xml @@ -264,7 +264,9 @@ <exclude>pass.txt</exclude> <exclude>ambari-metrics/ambari-metrics-host-monitoring/conf/unix/metric_groups.conf</exclude> <exclude>ambari-metrics/ambari-metrics-host-monitoring/conf/windows/metric_groups.conf</exclude> - <exclude>contrib/addons/test/dataServices/jmx/data/cluster_configuration.json.nohbase</exclude> + <exclude>ambari-metrics/ambari-metrics-host-monitoring/conf/unix/metric_groups.conf</exclude> + <exclude>stack-advisor/target/maven-status/maven-compiler-plugin/compile/default-compile/createdFiles.lst</exclude> + <exclude>stack-advisor/target/maven-status/maven-compiler-plugin/compile/default-compile/inputFiles.lst</exclude> <exclude>contrib/ambari-scom/msi/src/GUI_Ambari.sln</exclude> <exclude>contrib/fast-hdfs-resource/dependency-reduced-pom.xml</exclude> <exclude>contrib/agent-simulator/docker_image/package_list.txt</exclude> @@ -457,6 +459,7 @@ </property> </activation> <modules> + <module>serviceadvisor</module> <module>ambari-web</module> <module>ambari-project</module> <module>ambari-views</module> @@ -480,6 +483,7 @@ </property> </activation> <modules> + <module>serviceadvisor</module> <module>ambari-web</module> <module>ambari-project</module> <module>ambari-views</module> @@ -507,6 +511,7 @@ <module>ambari-shell</module> <module>ambari-logsearch</module> <module>ambari-infra</module> + <module>serviceadvisor</module> </modules> </profile> <profile> @@ -529,6 +534,7 @@ <module>ambari-shell</module> <module>ambari-logsearch</module> <module>ambari-infra</module> + <module>serviceadvisor</module> </modules> </profile> <profile> @@ -538,6 +544,12 @@ </modules> </profile> <profile> + <id>serviceadvisor</id> + <modules> + <module>serviceadvisor</module> + </modules> + </profile> + <profile> <id>windows</id> <activation> <os> @@ -545,6 +557,7 @@ </os> </activation> <modules> + <module>serviceadvisor</module> <module>ambari-web</module> <module>ambari-project</module> <module>ambari-views</module> @@ -555,7 +568,7 @@ <module>ambari-agent</module> <module>ambari-client</module> <module>ambari-shell</module> - </modules> + </modules> </profile> <profile> <id>clover</id>