Skip to content

Commit

Permalink
Apploader: Introduce app loader for downloading release jars
Browse files Browse the repository at this point in the history
Keeps repo smaller than having to check each release jar in.


Former-commit-id: 22e5960
  • Loading branch information
damienbiggs committed May 14, 2021
1 parent e48927c commit 1e5785e
Show file tree
Hide file tree
Showing 16 changed files with 185 additions and 37 deletions.
39 changes: 39 additions & 0 deletions appLoader/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<project>
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.vmware</groupId>
<artifactId>workflow</artifactId>
<version>1.0</version>
</parent>
<artifactId>appLoader</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>false</appendAssemblyId>
<finalName>appLoader</finalName>
<archive>
<manifest>
<mainClass>com.vmware.WorkflowAppLoader</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- bind to the packaging phase -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
102 changes: 102 additions & 0 deletions appLoader/src/main/java/com/vmware/WorkflowAppLoader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.vmware;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class WorkflowAppLoader {
private static final String RELEASE_DATE = "May_13_2021";
private static final String RELEASE_URL = "https://github.com/vmware/workflowTools/releases/download/" + RELEASE_DATE + "/workflow.jar";
private static final String RELEASE_NAME = "workflow-" + RELEASE_DATE + ".jar";

private final String tempDirectory;
private final List<String> argValues;
private final boolean debugLog;
private final File expectedReleaseJar;

public static void main(String[] args) {
WorkflowAppLoader loader = new WorkflowAppLoader(args);
loader.downloadJarFileIfNeeded();
loader.executeWorkflowJar();
}

public WorkflowAppLoader(String[] args) {
this.tempDirectory = getTempDirectory();
this.argValues = Arrays.asList(args);
this.debugLog = Stream.of("-d", "--debug", "-t", "--trace").anyMatch(argValues::contains);
this.expectedReleaseJar = new File(tempDirectory + File.separator + RELEASE_NAME);
}

public void executeWorkflowJar() {
if (debugLog) {
System.out.println("Launching workflow jar with args " + argValues);
}
try {
URLClassLoader urlClassLoader = new URLClassLoader(
new URL[] {expectedReleaseJar.toURI().toURL()},
this.getClass().getClassLoader()
);
Class classToLoad = Class.forName("com.vmware.WorkflowRunner", true, urlClassLoader);
Method method = classToLoad.getDeclaredMethod("runWorkflow", ClassLoader.class, List.class);
Object instance = classToLoad.newInstance();
method.invoke(instance, urlClassLoader, argValues);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

public void downloadJarFileIfNeeded() {
if (debugLog) {
System.out.println("Expected release jar is " + expectedReleaseJar.getPath());
}
if (expectedReleaseJar.exists()) {
if (debugLog) {
System.out.println("Jar file " + expectedReleaseJar.getPath() + " already exists");
}
return;
}
URL releaseURL = createReleaseUrl();
System.out.println("Downloading workflow release jar " + releaseURL.toString() + " to temp directory " + tempDirectory);

try {
ReadableByteChannel readableByteChannel = Channels.newChannel(releaseURL.openStream());
FileOutputStream fileOutputStream = new FileOutputStream(expectedReleaseJar);
fileOutputStream.getChannel().transferFrom(readableByteChannel, 0, Long.MAX_VALUE);
} catch (IOException e) {
throw new RuntimeException(e);
}

}

private URL createReleaseUrl() {
URL releaseURL;
try {
releaseURL = URI.create(RELEASE_URL).toURL();
} catch (MalformedURLException e) {
throw new RuntimeException(e);
}
return releaseURL;
}

private String getTempDirectory() {
try {
File tempFile = File.createTempFile("sample", "txt");
String directory = tempFile.getParent();
tempFile.delete();
return directory;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2 changes: 2 additions & 0 deletions config/src/main/java/com/vmware/config/WorkflowConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class WorkflowConfig {
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
private static final SimpleDateFormat timeFormat = new SimpleDateFormat("HHmmss");

public static ClassLoader realClassLoader;

@SectionConfig
public LoggingConfig loggingConfig;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,32 @@ public class CommandLineArgumentsParser {

private StringBuilder argumentsText;

public void generateArgumentMap(final String[] args) {
log.debug("Command line arguments; {}", Arrays.toString(args));
public void generateArgumentMap(final List<String> args) {
log.debug("Command line arguments; {}", args);
argumentsText = new StringBuilder();

argumentMap.clear();

for (int i = 0; i < args.length; i ++) {
for (int i = 0; i < args.size(); i ++) {
String arg = args.get(i);
if (i > 0) {
argumentsText.append(" ");
}
if (!args[i].startsWith("-")) {
argumentsText.append(args[i]);
if (!arg.startsWith("-")) {
argumentsText.append(arg);
continue;
}
String[] paramPieces = StringUtils.splitOnlyOnce(args[i], "=");
String[] paramPieces = StringUtils.splitOnlyOnce(arg, "=");
String paramName = paramPieces[0];
argumentsText.append(paramName);
String paramValue = null;

if (paramPieces.length == 1 && args[i].endsWith("=")) {
if (paramPieces.length == 1 && arg.endsWith("=")) {
paramValue = "";
} else if (paramPieces.length == 2) {
paramValue = paramPieces[1];
} else if (i < args.length - 1 && !args[i+1].startsWith("-")) {
paramValue = args[++i];
} else if (i < args.size() - 1 && !args.get(i+1).startsWith("-")) {
paramValue = args.get(++i);
}
if (paramValue != null) {
argumentsText.append("=").append(paramValue.contains(" ") ? "\"" + paramValue + "\"" : paramValue);
Expand All @@ -62,8 +63,8 @@ public void generateArgumentMap(final String[] args) {
argumentMap.put(paramName, paramValue);
}
// add first variable as a possible workflow value if it does not start with -
if (args.length > 0 && !args[0].startsWith("-")) {
argumentMap.put("--possible-workflow", args[0]);
if (args.size() > 0 && !args.get(0).startsWith("-")) {
argumentMap.put("--possible-workflow", args.get(0));
}
}

Expand Down
17 changes: 9 additions & 8 deletions core/src/main/java/com/vmware/Workflow.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,10 @@ public class Workflow {
private boolean firstTime = true;
private boolean displayedShellInfoMessage = false;
private String username = null;
private final String[] args;
private final List<String> args;

public Workflow(String[] args) {
public Workflow(ClassLoader classLoader, List<String> args) {
WorkflowConfig.realClassLoader = classLoader;
this.args = args;
}

Expand Down Expand Up @@ -154,7 +155,7 @@ private void askForWorkflow(boolean firstTime) {
log.debug("Quitting");
System.exit(0);
}
String[] workflowTextPieces = splitWorkflowTextIntoArguments(workFlowText);
List<String> workflowTextPieces = splitWorkflowTextIntoArguments(workFlowText);
configParser.updateWithRuntimeArguments(config, workflowTextPieces);
}

Expand All @@ -165,7 +166,7 @@ private void displayShellInfoMessageIfNeeded() {
}
}

private String[] splitWorkflowTextIntoArguments(String workFlowText) {
private List<String> splitWorkflowTextIntoArguments(String workFlowText) {
String[] quotedTextPieces = workFlowText.split("[\"]");
List<String> workflowTextPieces = new ArrayList<>();
for (int i = 0; i < quotedTextPieces.length; i ++) {
Expand All @@ -183,7 +184,7 @@ private String[] splitWorkflowTextIntoArguments(String workFlowText) {
workflowTextPieces.add(quotedTextPieces[i]);
}
}
return workflowTextPieces.toArray(new String[0]);
return workflowTextPieces;
}

private ArgumentCompleter createWorkflowCompleter() {
Expand All @@ -197,7 +198,7 @@ private ArgumentCompleter createWorkflowCompleter() {
autocompleteList.add(workflow);
}
}
WorkflowActions workflowActions = new WorkflowActions(config);
WorkflowActions workflowActions = new WorkflowActions(config, WorkflowConfig.realClassLoader);
// ! means that it won't show up if nothing is entered
autocompleteList.addAll(workflowActions.getWorkflowActionClasses()
.stream().map(workflowAction -> "!" + workflowAction.getSimpleName()).collect(Collectors.toList()));
Expand Down Expand Up @@ -231,7 +232,7 @@ public void runWorkflow() {
return;
}

WorkflowActions workflowActions = new WorkflowActions(config);
WorkflowActions workflowActions = new WorkflowActions(config, WorkflowConfig.realClassLoader);
List<WorkflowAction> actions = workflowActions.determineActions(workflowToRun);
// update history file after all the workflow has been determined to be valid
updateWorkflowHistoryFile();
Expand Down Expand Up @@ -287,7 +288,7 @@ private void outputTotalExecutionTime(Date startingDate) {

private void checkAllActionsCanBeInstantiated(boolean runAllHelperMethods) {
log.info("Checking that each action value in the workflows is valid");
WorkflowActions workflowActions = new WorkflowActions(config);
WorkflowActions workflowActions = new WorkflowActions(config, WorkflowConfig.realClassLoader);
List<WorkflowAction> actions =
workflowActions.determineActions(StringUtils.join(config.workflows.keySet()));
WorkflowActionValues actionValues = new WorkflowActionValues();
Expand Down
9 changes: 8 additions & 1 deletion core/src/main/java/com/vmware/WorkflowRunner.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.vmware;

import java.util.Arrays;
import java.util.List;
import java.util.logging.ConsoleHandler;
import java.util.logging.Level;
import java.util.logging.LogManager;
Expand All @@ -12,11 +14,16 @@
public class WorkflowRunner {

public static void main(String[] args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
new WorkflowRunner().runWorkflow(classLoader, Arrays.asList(args));
}

public void runWorkflow(ClassLoader classLoader, List<String> args) {
LogManager.getLogManager().reset();
java.util.logging.Logger globalLogger = java.util.logging.Logger.getLogger("com.vmware");
globalLogger.addHandler(createHandler());

Workflow workflow = new Workflow(args);
Workflow workflow = new Workflow(classLoader, args);
workflow.runWorkflow();
}

Expand Down
1 change: 0 additions & 1 deletion core/src/main/java/com/vmware/action/BaseAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import com.vmware.util.CommandLineUtils;
import com.vmware.util.StringUtils;
import com.vmware.util.exception.CancelException;
import com.vmware.util.exception.FatalException;
import com.vmware.util.exception.SkipActionException;
import com.vmware.util.logging.LogLevel;
import com.vmware.util.scm.Git;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void process() {

private Map<String, List<Class<? extends BaseAction>>> generateClassMap() {
Map<String, List<Class<? extends BaseAction>>> classes = new TreeMap<String, List<Class<? extends BaseAction>>>();
List<Class<? extends BaseAction>> workflowActions = new WorkflowActions(config).getWorkflowActionClasses();
List<Class<? extends BaseAction>> workflowActions = new WorkflowActions(config, WorkflowConfig.realClassLoader).getWorkflowActionClasses();
for (Class<? extends BaseAction> action : workflowActions) {
String[] pieces = action.getName().split("\\.");
String packageName = pieces[pieces.length - 2];
Expand Down
10 changes: 2 additions & 8 deletions core/src/main/java/com/vmware/config/WorkflowActionLister.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,8 @@
*/
public class WorkflowActionLister {

public List<Class<? extends BaseAction>> findWorkflowActions() {
public List<Class<? extends BaseAction>> findWorkflowActions(ClassLoader classLoader) {
try {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
URL actionDirectoryUrl = classLoader.getResource("com/vmware/action");
List<Class<? extends BaseAction>> actionsList = new ArrayList<Class<? extends BaseAction>>();
if (actionDirectoryUrl.getFile().contains(".jar!")) {
Expand All @@ -39,12 +38,7 @@ public List<Class<? extends BaseAction>> findWorkflowActions() {
addClassesFromDirectory(directoryFile, actionsList, "com.vmware");
}

Collections.sort(actionsList, new Comparator<Class<? extends BaseAction>>() {
@Override
public int compare(Class<? extends BaseAction> o1, Class<? extends BaseAction> o2) {
return o1.getSimpleName().compareTo(o2.getSimpleName());
}
});
Collections.sort(actionsList, Comparator.comparing(Class::getSimpleName));
return actionsList;
} catch (IOException e) {
throw new RuntimeIOException(e);
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/com/vmware/config/WorkflowActions.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public class WorkflowActions {
private WorkflowConfig workflowConfig;
private List<Class<? extends BaseAction>> workflowActionClasses;

public WorkflowActions(WorkflowConfig workflowConfig) {
public WorkflowActions(WorkflowConfig workflowConfig, ClassLoader classLoader) {
this.workflowConfig = workflowConfig;
workflowActionClasses = new WorkflowActionLister().findWorkflowActions();
workflowActionClasses = new WorkflowActionLister().findWorkflowActions(classLoader);
}

public List<Class<? extends BaseAction>> getWorkflowActionClasses() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.Reader;
import java.util.List;
import java.util.Map;

import com.google.gson.Gson;
Expand All @@ -30,7 +31,7 @@ public class WorkflowConfigParser {
private final Gson gson = new ConfiguredGsonBuilder().setPrettyPrinting().build();
private final CommandLineArgumentsParser argsParser = new CommandLineArgumentsParser();

public WorkflowConfig parseWorkflowConfig(String username, String[] args) {
public WorkflowConfig parseWorkflowConfig(String username, List<String> args) {
argsParser.generateArgumentMap(args);

WorkflowConfig config = readInternalConfig();
Expand Down Expand Up @@ -106,7 +107,7 @@ private void parseUsernameIfBlank(WorkflowConfig config) {
}
}

public void updateWithRuntimeArguments(WorkflowConfig config, String[] args) {
public void updateWithRuntimeArguments(WorkflowConfig config, List<String> args) {
argsParser.generateArgumentMap(args);
applyRuntimeArguments(config);
config.setupLogging();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import java.util.SortedSet;
import java.util.TreeSet;

import com.vmware.Workflow;
import com.vmware.action.BaseAction;
import com.vmware.config.ReplacementVariables;
import com.vmware.config.WorkflowAction;
Expand Down Expand Up @@ -40,7 +41,7 @@ public class ConfigValuesCompleter extends ImprovedStringsCompleter implements C
public ConfigValuesCompleter(WorkflowConfig config) {
this.configMappings = new ConfigMappings();
this.config = config;
this.workflowActions = new WorkflowActions(config).getWorkflowActionClasses();
this.workflowActions = new WorkflowActions(config, WorkflowConfig.realClassLoader).getWorkflowActionClasses();
super.values.addAll(configMappings.allConfigValues());
}

Expand Down
Loading

0 comments on commit 1e5785e

Please sign in to comment.