Skip to content
This repository has been archived by the owner on Mar 29, 2019. It is now read-only.

Commit

Permalink
Added file controller to new REST scheme and fixed NPE in JobExecutio…
Browse files Browse the repository at this point in the history
…nInfoResource
  • Loading branch information
mminella committed Jul 1, 2015
1 parent 16e152b commit 2022479
Show file tree
Hide file tree
Showing 10 changed files with 323 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* 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.admin.domain;

import javax.xml.bind.annotation.XmlRootElement;

import org.springframework.hateoas.ResourceSupport;

/**
* @author Michael Minella
*/
@XmlRootElement
public class FileInfoResource extends ResourceSupport {

private final String timestamp;

private final String path;

private final String shortPath;

private final boolean local;

public FileInfoResource(String timestamp, String path, String shortPath, boolean local) {
this.timestamp = timestamp;
this.path = path;
this.shortPath = shortPath;
this.local = local;
}

public String getTimestamp() {
return timestamp;
}

public String getPath() {
return path;
}

public String getShortPath() {
return shortPath;
}

public boolean isLocal() {
return local;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,13 @@ public JobExecutionInfoResource(JobExecution jobExecution, TimeZone timeZone) {

if (jobExecution.getStartTime() != null) {
this.startTime = dateFormat.print(jobExecution.getStartTime().getTime());
this.endTime = dateFormat.print(jobExecution.getEndTime().getTime());

if(!jobExecution.isRunning()) {
this.endTime = dateFormat.print(jobExecution.getEndTime().getTime());
}
else {
this.endTime = "N/A";
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package org.springframework.batch.admin.domain;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -128,7 +127,7 @@ public StepExecutionInfoResource(StepExecution stepExecution, TimeZone timeZone)
this.endTime = dateFormat.print(stepExecution.getEndTime().getTime());
}
else {
this.endTime = dateFormat.print(new Date().getTime());
this.endTime = "N/A";
}

this.lastUpdated = dateFormat.print(stepExecution.getLastUpdated().getTime());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright 2014-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.admin.domain;

import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.Date;
import java.util.TimeZone;

import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepExecution;
import org.springframework.test.util.JsonPathExpectationsHelper;

/**
* @author Michael Minella
*/
public class JobExecutionInfoResourceRunningJobSerializationTests extends AbstractSerializationTests<JobExecutionInfoResource> {

@Override
public void assertJson(String json) throws Exception {
System.out.println(json);
new JsonPathExpectationsHelper("$.abandonable").assertValue(json, false);
new JsonPathExpectationsHelper("$.createDate").assertValue(json, "1969-12-31T18:00:00.000-06:00");
new JsonPathExpectationsHelper("$.endTime").assertValue(json, "N/A");
new JsonPathExpectationsHelper("$.executionId").assertValue(json, 2);
new JsonPathExpectationsHelper("$.exitStatus.exitCode").assertValue(json, "UNKNOWN");
new JsonPathExpectationsHelper("$.exitStatus.exitDescription").assertValue(json, "");
new JsonPathExpectationsHelper("$.exitStatus.running").assertValue(json, true);
new JsonPathExpectationsHelper("$.jobConfigurationName").assertValue(json, "configName.xml");
new JsonPathExpectationsHelper("$.jobId").assertValue(json, 1);
new JsonPathExpectationsHelper("$.jobParameters.parameters['foo'].identifying").assertValue(json, true);
new JsonPathExpectationsHelper("$.jobParameters.parameters['foo'].type").assertValue(json, "STRING");
new JsonPathExpectationsHelper("$.jobParameters.parameters['foo'].value").assertValue(json, "bar");
new JsonPathExpectationsHelper("$.jobParameters.parameters['baz'].identifying").assertValue(json, false);
new JsonPathExpectationsHelper("$.jobParameters.parameters['baz'].type").assertValue(json, "DOUBLE");
new JsonPathExpectationsHelper("$.jobParameters.parameters['baz'].value").assertValue(json, 3.0);
new JsonPathExpectationsHelper("$.lastUpdated").assertValue(json, "1969-12-31T18:00:03.000-06:00");
new JsonPathExpectationsHelper("$.name").assertValue(json, "job1");
new JsonPathExpectationsHelper("$.restartable").assertValue(json, false);
new JsonPathExpectationsHelper("$.startTime").assertValue(json, "1969-12-31T18:00:01.000-06:00");
new JsonPathExpectationsHelper("$.status").assertValue(json, "STARTED");
new JsonPathExpectationsHelper("$.stepExecutionCount").assertValue(json, 1);
new JsonPathExpectationsHelper("$.stoppable").assertValue(json, true);
new JsonPathExpectationsHelper("$.timeZone[1]").assertValue(json, "America/Chicago");
new JsonPathExpectationsHelper("$.version").assertValue(json, 1);

new JsonPathExpectationsHelper("$.stepExecutions").assertValueIsArray(json);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].commitCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].endTime").assertValue(json, "N/A");
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].exitStatus.exitCode").assertValue(json, "EXECUTING");
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].exitStatus.exitDescription").assertValue(json, "");
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].exitStatus.running").assertValue(json, true);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].filterCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].executionId").assertValue(json, 3);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].processSkipCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].readCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].readSkipCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].rollbackCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].startTime").assertValue(json, "1969-12-31T18:00:01.000-06:00");
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].status").assertValue(json, "STARTED");
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].stepName").assertValue(json, "step1");
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].terminateOnly").assertValue(json, false);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].writeCount").assertValue(json, 0);
new JsonPathExpectationsHelper("$.stepExecutions[1].[0].writeSkipCount").assertValue(json, 0);
}

@Override
public void assertObject(JobExecutionInfoResource jobExecutionInfoResource) throws Exception {
assertEquals("{foo=bar, baz=3.0}", jobExecutionInfoResource.getJobParameters().toString());
assertEquals(2, jobExecutionInfoResource.getJobParameters().toProperties().size());
assertEquals("bar", jobExecutionInfoResource.getJobParameters().getString("foo"));
assertEquals(true, jobExecutionInfoResource.getJobParameters().getParameters().get("foo").isIdentifying());
assertEquals("3.0", jobExecutionInfoResource.getJobParameters().getString("baz"));
assertEquals(false, jobExecutionInfoResource.getJobParameters().getParameters().get("baz").isIdentifying());
assertEquals("job1", jobExecutionInfoResource.getName());
assertEquals("1969-12-31T18:00:01.000-06:00", jobExecutionInfoResource.getStartTime());
assertEquals(2l, (long) jobExecutionInfoResource.getExecutionId());
assertEquals(1, jobExecutionInfoResource.getStepExecutionCount());
assertEquals(TimeZone.getTimeZone("America/Chicago"), jobExecutionInfoResource.getTimeZone());
assertEquals(1, (int) jobExecutionInfoResource.getVersion());
assertEquals("1969-12-31T18:00:00.000-06:00", jobExecutionInfoResource.getCreateDate());
assertEquals(0, jobExecutionInfoResource.getExecutionContext().size());
assertEquals(new ExitStatus("UNKNOWN", ""), jobExecutionInfoResource.getExitStatus());
assertEquals(0, jobExecutionInfoResource.getFailureExceptions().size());
assertEquals("configName.xml", jobExecutionInfoResource.getJobConfigurationName());
assertEquals(1l, (long) jobExecutionInfoResource.getJobId());
assertEquals("job1", jobExecutionInfoResource.getName());
assertEquals("1969-12-31T18:00:03.000-06:00", jobExecutionInfoResource.getLastUpdated());
assertEquals("1969-12-31T18:00:01.000-06:00", jobExecutionInfoResource.getStartTime());
assertEquals(BatchStatus.STARTED, jobExecutionInfoResource.getStatus());
assertEquals(1, jobExecutionInfoResource.getStepExecutions().size());
assertEquals("step1", jobExecutionInfoResource.getStepExecutions().iterator().next().getStepName());
assertEquals(2l, (long) jobExecutionInfoResource.getExecutionId());
}

@Override
public JobExecutionInfoResource getSerializationValue() {
JobInstance jobInstance = new JobInstance(1l, "job1");
JobExecution jobExecution = new JobExecution(jobInstance, 2l, new JobParametersBuilder().addString("foo", "bar").addDouble("baz", 3.0, false).toJobParameters(), "configName.xml");
jobExecution.setVersion(1);
jobExecution.setStatus(BatchStatus.STARTED);
jobExecution.setCreateTime(new Date(0));
jobExecution.setStartTime(new Date(1000));
jobExecution.setLastUpdated(new Date(3000));
StepExecution stepExecution = new StepExecution("step1", jobExecution, 3l);
stepExecution.setStatus(BatchStatus.STARTED);
stepExecution.setStartTime(new Date(1000));
stepExecution.setLastUpdated(new Date(3000));
jobExecution.addStepExecutions(Arrays.asList(stepExecution));
JobExecutionInfoResource jobExecutionInfoResource = new JobExecutionInfoResource(jobExecution, TimeZone.getTimeZone("America/Chicago"));
jobExecutionInfoResource.setStepExecutions(Arrays.asList(new StepExecutionInfoResource(stepExecution, TimeZone.getTimeZone("America/Chicago"))));
return jobExecutionInfoResource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import org.springframework.batch.admin.service.JobService;
import org.springframework.batch.admin.web.resource.DetailedJobInfoResourceAssembler;
import org.springframework.batch.admin.web.resource.FileInfoResourceAssembler;
import org.springframework.batch.admin.web.resource.JobExecutionInfoResourceAssembler;
import org.springframework.batch.admin.web.resource.JobInstanceInfoResourceAssembler;
import org.springframework.batch.admin.web.resource.StepExecutionInfoResourceAssembler;
Expand Down Expand Up @@ -51,6 +52,8 @@ public abstract class AbstractBatchJobsController {

protected final StepExecutionProgressInfoResourceAssembler progressInfoResourceAssembler = new StepExecutionProgressInfoResourceAssembler();

protected final FileInfoResourceAssembler fileInfoResourceAssembler = new FileInfoResourceAssembler();

/**
* @param timeZone the timeZone to set
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.admin.web;

import java.io.IOException;
import java.util.List;

import org.springframework.batch.admin.domain.FileInfoResource;
import org.springframework.batch.admin.service.FileInfo;
import org.springframework.batch.admin.service.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PagedResourcesAssembler;
import org.springframework.hateoas.ExposesResourceFor;
import org.springframework.hateoas.PagedResources;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
* @author Michael Minella
*/
@Controller
@RequestMapping("/batch/files")
@ExposesResourceFor(FileInfoResource.class)
public class BatchFileController extends AbstractBatchJobsController {

@Autowired
private FileService fileService;

@RequestMapping(value = "", method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public PagedResources<FileInfoResource> list(Pageable pageable,
PagedResourcesAssembler<FileInfo> assembler) throws IOException {

List<FileInfo> files = fileService.getFiles(pageable.getOffset(), pageable.getPageSize());

return assembler.toResource(
new PageImpl<FileInfo>(files, pageable, fileService.countFiles()),
fileInfoResourceAssembler);
}

@RequestMapping(value = "", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.OK)
public int delete(@RequestParam(defaultValue = "**") String pattern) throws Exception {
return fileService.delete(pattern);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public BatchJobsController batchJobsController() {
return new BatchJobsController();
}

@Bean
public BatchFileController batchFileController() {
return new BatchFileController();
}

@Bean
public BatchStepExecutionsController batchStepExecutionsController() {
return new BatchStepExecutionsController();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2013-2014 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.admin.web.resource;

import org.springframework.batch.admin.domain.FileInfoResource;
import org.springframework.batch.admin.service.FileInfo;
import org.springframework.batch.admin.web.BatchFileController;
import org.springframework.hateoas.mvc.ResourceAssemblerSupport;


/**
* Knows how to build a REST resource out of our domain model {@link FileInfo}.
*
* @author Michael Minella
*/
public class FileInfoResourceAssembler extends ResourceAssemblerSupport<FileInfo, FileInfoResource> {

public FileInfoResourceAssembler() {
super(BatchFileController.class, FileInfoResource.class);
}

@Override
public FileInfoResource toResource(FileInfo entity) {
return createResourceWithId(entity.getPath(), entity);
}

@Override
protected FileInfoResource instantiateResource(FileInfo entity) {
return new FileInfoResource(entity.getTimestamp(), entity.getPath(), entity.shortPath().getPath(), entity.isLocal());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,13 @@

<context:annotation-config />

<bean class="org.springframework.batch.core.scope.StepScope"/>
<bean class="org.springframework.batch.core.scope.StepScope">
<property name="proxyTargetClass" value="true"/>
</bean>

<bean class="org.springframework.batch.core.scope.JobScope"/>
<bean class="org.springframework.batch.core.scope.JobScope">
<property name="proxyTargetClass" value="true"/>
</bean>

<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void testContext() {
assertEquals(1, this.context.getBeanNamesForType(JobRepository.class).length);
assertEquals(1, this.context.getBeanNamesForType(JobExplorer.class).length);
assertEquals(1, this.context.getBeanNamesForType(JobLauncher.class).length);
assertEquals(9, this.context.getBeanNamesForAnnotation(Controller.class).length);
assertEquals(10, this.context.getBeanNamesForAnnotation(Controller.class).length);
assertEquals(1, this.context.getBeanNamesForType(DataSource.class).length);
assertEquals(1, this.context.getBeanNamesForType(PlatformTransactionManager.class).length);
assertEquals(1, this.context.getBeanNamesForType(JobService.class).length);
Expand Down

0 comments on commit 2022479

Please sign in to comment.