Skip to content

Commit

Permalink
XD-2298 Prototype for a gpload tasklet implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Risberg committed Mar 12, 2015
1 parent c0ca114 commit 602c1b7
Show file tree
Hide file tree
Showing 11 changed files with 487 additions and 50 deletions.
Expand Up @@ -61,8 +61,6 @@ public abstract class AbstractProcessBuilderTasklet implements Tasklet, Environm

protected final Logger logger = LoggerFactory.getLogger(this.getClass());

private static final String XD_CONFIG_HOME = "xd.config.home";

protected ConfigurableEnvironment environment;

/**
Expand All @@ -84,11 +82,17 @@ public abstract class AbstractProcessBuilderTasklet implements Tasklet, Environm

private SystemProcessExitCodeMapper systemProcessExitCodeMapper = new SimpleSystemProcessExitCodeMapper();

private List<EnvironmentProvider> environmentProviders = new ArrayList<EnvironmentProvider>();

@Override
public void setEnvironment(Environment environment) {
this.environment = (ConfigurableEnvironment) environment;
}

public void addEnvironmentProvider(EnvironmentProvider environmentProvider) {
this.environmentProviders.add(environmentProvider);
}

@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

Expand All @@ -102,16 +106,16 @@ public RepeatStatus execute(StepContribution contribution, ChunkContext chunkCon

List<String> command = createCommand();

String commandClassPath = createClassPath(this.getClass());

File out = File.createTempFile(commandName + "-", ".out");
stepExecution.getExecutionContext().putString(commandName.toLowerCase() + ".system.out", out.getAbsolutePath());
logger.info(commandName + " system.out: " + out.getAbsolutePath());
File err = File.createTempFile(commandName + "-", ".err");
stepExecution.getExecutionContext().putString(commandName.toLowerCase() + ".system.err", err.getAbsolutePath());
ProcessBuilder pb = new ProcessBuilder(command).redirectOutput(out).redirectError(err);
Map<String, String> env = pb.environment();
env.put("CLASSPATH", commandClassPath);
for (EnvironmentProvider envProvider : environmentProviders) {
envProvider.setEnvironment(env);
}
String msg = commandDescription + " is being launched";
stepExecution.getExecutionContext().putString(commandName.toLowerCase() + ".command", commandDisplayString.trim());
List<String> commandOut = new ArrayList<String>();
Expand Down Expand Up @@ -243,58 +247,14 @@ public ExitStatus afterStep(StepExecution stepExecution) {

protected abstract boolean isStoppable();

protected abstract List<String> createCommand();
protected abstract List<String> createCommand() throws Exception;

protected abstract String getCommandDisplayString();

protected abstract String getCommandName();

protected abstract String getCommandDescription();

protected String createClassPath(Class taskletClass) {
URLClassLoader serverClassLoader;
URLClassLoader taskletClassLoader;
try {
serverClassLoader = (URLClassLoader) Class.forName("org.springframework.xd.dirt.core.Job").getClassLoader();
taskletClassLoader = (URLClassLoader) taskletClass.getClassLoader();
}
catch (Exception e) {
throw new IllegalStateException("Unable to determine classpath from ClassLoader.", e);
}
if (serverClassLoader == null) {
throw new IllegalStateException("Unable to access ClassLoader for " + taskletClass + ".");
}
if (taskletClassLoader == null) {
throw new IllegalStateException("Unable to access Context ClassLoader.");
}
List<String> classPath = new ArrayList<String>();
String configHome = environment.getProperty(XD_CONFIG_HOME);
if (StringUtils.hasText(configHome)) {
classPath.add(configHome);
}
for (URL url : serverClassLoader.getURLs()) {
String file = url.getFile().split("\\!/", 2)[0];
if (file.endsWith(".jar")) {
classPath.add(file);
}
}
for (URL url : taskletClassLoader.getURLs()) {
String file = url.getFile().split("\\!/", 2)[0];
if (file.endsWith(".jar") && !classPath.contains(file)) {
classPath.add(file);
}
}
StringBuilder classPathBuilder = new StringBuilder();
String separator = System.getProperty("path.separator");
for (String url : classPath) {
if (classPathBuilder.length() > 0) {
classPathBuilder.append(separator);
}
classPathBuilder.append(url);
}
return classPathBuilder.toString();
}

protected List<String> getProcessOutput(File f) {
List<String> lines = new ArrayList<String>();
if (f == null) {
Expand Down
@@ -0,0 +1,94 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.batch.step.tasklet.x;

import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.util.StringUtils;

import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
*/
public class ClasspathEnvironmentProvider implements EnvironmentProvider {

private static final String XD_CONFIG_HOME = "xd.config.home";

ConfigurableEnvironment environment;

Class taskletClass;


public ClasspathEnvironmentProvider(ConfigurableEnvironment environment, Class taskletClass) {
this.environment = environment;
this.taskletClass = taskletClass;
}

@Override
public void setEnvironment(Map<String, String> env) {
String classPath = createClassPath();
env.put("CLASSPATH", classPath);
}

protected String createClassPath() {
URLClassLoader serverClassLoader;
URLClassLoader taskletClassLoader;
try {
serverClassLoader = (URLClassLoader) Class.forName("org.springframework.xd.dirt.core.Job").getClassLoader();
taskletClassLoader = (URLClassLoader) taskletClass.getClassLoader();
}
catch (Exception e) {
throw new IllegalStateException("Unable to determine classpath from ClassLoader.", e);
}
if (serverClassLoader == null) {
throw new IllegalStateException("Unable to access ClassLoader for " + taskletClass + ".");
}
if (taskletClassLoader == null) {
throw new IllegalStateException("Unable to access Context ClassLoader.");
}
List<String> classPath = new ArrayList<String>();
String configHome = environment.getProperty(XD_CONFIG_HOME);
if (StringUtils.hasText(configHome)) {
classPath.add(configHome);
}
for (URL url : serverClassLoader.getURLs()) {
String file = url.getFile().split("\\!/", 2)[0];
if (file.endsWith(".jar")) {
classPath.add(file);
}
}
for (URL url : taskletClassLoader.getURLs()) {
String file = url.getFile().split("\\!/", 2)[0];
if (file.endsWith(".jar") && !classPath.contains(file)) {
classPath.add(file);
}
}
StringBuilder classPathBuilder = new StringBuilder();
String separator = System.getProperty("path.separator");
for (String url : classPath) {
if (classPathBuilder.length() > 0) {
classPathBuilder.append(separator);
}
classPathBuilder.append(url);
}
return classPathBuilder.toString();
}

}
@@ -0,0 +1,27 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.batch.step.tasklet.x;

import java.util.Map;

/**
*/
public interface EnvironmentProvider {

void setEnvironment(Map<String, String> env);

}
@@ -0,0 +1,37 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.xd.gpload;

import org.springframework.batch.step.tasklet.x.EnvironmentProvider;

import java.util.Map;

/**
*/
public class GploadEnvironmentProvider implements EnvironmentProvider {

String gploadHome;

public GploadEnvironmentProvider(String gploadHome) {
this.gploadHome = gploadHome;
}

@Override
public void setEnvironment(Map<String, String> env) {
env.put("GPHOME_LOADERS", gploadHome);
}
}
@@ -0,0 +1,64 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.xd.gpload;

import org.hibernate.validator.constraints.NotBlank;
import org.springframework.xd.module.options.spi.ModuleOption;

/**
* Module options for Gpload batch job module.
*
* @author Thomas Risberg
*/
public class GploadOptionsMetadata {

private String gploadHome;

private String controlFile;

private String options;


@NotBlank
public String getGploadHome() {
return gploadHome;
}

@ModuleOption("the gpload home location")
public void setGploadHome(String gploadHome) {
this.gploadHome = gploadHome;
}

public String getControlFile() {
return controlFile;
}

@ModuleOption("path to the gpload control file")
public void setControlFile(String controlFile) {
this.controlFile = controlFile;
}

public String getOptions() {
return options;
}

@ModuleOption("the gpload options to use")
public void setOptions(String options) {
this.options = options;
}

}

0 comments on commit 602c1b7

Please sign in to comment.