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

Commit

Permalink
Added tests for serialization of FileInfoResource
Browse files Browse the repository at this point in the history
  • Loading branch information
mminella committed Jul 2, 2015
1 parent 2022479 commit 7313b5d
Show file tree
Hide file tree
Showing 8 changed files with 260 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,25 @@
@XmlRootElement
public class FileInfoResource extends ResourceSupport {

private final String timestamp;
private String timestamp;

private final String path;
private String path;

private final String shortPath;
private String shortPath;

private final boolean local;
private boolean local;

public FileInfoResource(String timestamp, String path, String shortPath, boolean local) {
private int deleteCount = 0;

public FileInfoResource() {
}

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

public String getTimestamp() {
Expand All @@ -55,4 +61,8 @@ public String getShortPath() {
public boolean isLocal() {
return local;
}

public int getDeleteCount() {
return deleteCount;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright 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.domain;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.springframework.test.util.JsonPathExpectationsHelper;

/**
* @author Michael Minella
*/
public class FileInfoResourceSerializationTests extends AbstractSerializationTests<FileInfoResource> {

private String timestamp = formatter.format(new Date());

private static DateFormat formatter = new SimpleDateFormat("");

@Override
public void assertJson(String json) throws Exception {
new JsonPathExpectationsHelper("$.timestamp").assertValue(json, timestamp);
new JsonPathExpectationsHelper("$.path").assertValue(json, "file://foo/bar/baz.txt");
new JsonPathExpectationsHelper("$.shortPath").assertValue(json, "foo/bar/baz.txt");
new JsonPathExpectationsHelper("$.local").assertValue(json, true);
}

@Override
public void assertObject(FileInfoResource fileInfoResource) throws Exception {
assertEquals(timestamp, fileInfoResource.getTimestamp());
assertEquals("file://foo/bar/baz.txt", fileInfoResource.getPath());
assertEquals("foo/bar/baz.txt", fileInfoResource.getShortPath());
assertTrue(fileInfoResource.isLocal());
}

@Override
public FileInfoResource getSerializationValue() {
FileInfoResource resource =
new FileInfoResource(timestamp,
"file://foo/bar/baz.txt",
"foo/bar/baz.txt",
true,
0);
return resource;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,21 +38,23 @@ public class FileInfo implements Comparable<FileInfo>, Serializable {

private final boolean local;

private final int deleteCount;

public FileInfo(String path) {
this(path, null, true);
this(path, null, true, 0);
}

public FileInfo(String path, String timestamp, boolean local) {
public FileInfo(String path, String timestamp, boolean local, int deleteCount) {
super();
this.path = path.replace("\\", "/");
this.shortPath = extractPath(path, timestamp);
this.timestamp = extractTimestamp(path, timestamp);
this.local = local;
this.deleteCount = deleteCount;
}

public FileInfo shortPath() {
FileInfo info = new FileInfo(shortPath, timestamp, local);
return info;
return new FileInfo(shortPath, timestamp, local, deleteCount);
}

public String getPattern() {
Expand Down Expand Up @@ -112,6 +114,10 @@ public String getPath() {
return path;
}

public int getDeleteCount() {
return deleteCount;
}

public String getFileName() {
if (path.matches(TIMESTAMP_PATTERN)) {
return path;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@
package org.springframework.batch.admin.web;

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

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.batch.admin.domain.FileInfoResource;
import org.springframework.batch.admin.service.FileInfo;
import org.springframework.batch.admin.service.FileService;
Expand All @@ -29,10 +33,16 @@
import org.springframework.hateoas.PagedResources;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
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;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.util.HtmlUtils;

/**
* @author Michael Minella
Expand All @@ -42,6 +52,8 @@
@ExposesResourceFor(FileInfoResource.class)
public class BatchFileController extends AbstractBatchJobsController {

private static Log logger = LogFactory.getLog(BatchFileController.class);

@Autowired
private FileService fileService;

Expand All @@ -59,7 +71,52 @@ public PagedResources<FileInfoResource> list(Pageable pageable,

@RequestMapping(value = "", method = RequestMethod.DELETE)
@ResponseStatus(HttpStatus.OK)
public int delete(@RequestParam(defaultValue = "**") String pattern) throws Exception {
return fileService.delete(pattern);
public FileInfoResource delete(@RequestParam(defaultValue = "**") String pattern) throws Exception {
FileInfo fileInfo = new FileInfo(pattern, "", true, fileService.delete(pattern));

return fileInfoResourceAssembler.toResource(fileInfo);
}

@RequestMapping(value = "", method = RequestMethod.POST)
public String uploadRequest(@RequestParam String path, @RequestParam MultipartFile file, ModelMap model,
@RequestParam(defaultValue = "0") int startFile, @RequestParam(defaultValue = "20") int pageSize,
@ModelAttribute("date") Date date, Errors errors) throws Exception {
return upload(path, file, model, startFile, pageSize, date, errors);
}

@RequestMapping(value = "/{path}", method = RequestMethod.POST)
public String upload(@PathVariable String path, @RequestParam MultipartFile file, ModelMap model,
@RequestParam(defaultValue = "0") int startFile, @RequestParam(defaultValue = "20") int pageSize,
@ModelAttribute("date") Date date, Errors errors) throws Exception {

String originalFilename = file.getOriginalFilename();
if (file.isEmpty()) {
errors.reject("file.upload.empty", new Object[] { originalFilename },
"File upload was empty for filename=[" + HtmlUtils.htmlEscape(originalFilename) + "]");
return null;
}

try {
FileInfo dest = fileService.createFile(path + "/" + originalFilename);
file.transferTo(fileService.getResource(dest.getPath()).getFile());
fileService.publish(dest);
model.put("uploaded", dest.getPath());
}
catch (IOException e) {
errors.reject("file.upload.failed", new Object[] { originalFilename }, "File upload failed for "
+ HtmlUtils.htmlEscape(originalFilename));
}
catch (Exception e) {
String message = "File upload failed downstream processing for "
+ HtmlUtils.htmlEscape(originalFilename);
if (logger.isDebugEnabled()) {
logger.debug(message, e);
} else {
logger.info(message);
}
errors.reject("file.upload.failed.downstream", new Object[] { originalFilename }, message);
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.web.accept.ContentNegotiationManager;
import org.springframework.web.filter.HttpPutFormContentFilter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;

Expand All @@ -38,6 +39,11 @@
@Import(RestControllerAdvice.class)
public class RestConfiguration {

@Bean
public HttpPutFormContentFilter putFilter() {
return new HttpPutFormContentFilter();
}

@Bean
public BatchJobExecutionsController batchJobExecutionsController() {
return new BatchJobExecutionsController();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@ public FileInfoResource toResource(FileInfo entity) {

@Override
protected FileInfoResource instantiateResource(FileInfo entity) {
return new FileInfoResource(entity.getTimestamp(), entity.getPath(), entity.shortPath().getPath(), entity.isLocal());
return new FileInfoResource(entity.getTimestamp(), entity.getPath(), entity.shortPath().getPath(), entity.isLocal(), entity.getDeleteCount());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ public void testCompareTo() {

@Test
public void testCompareToWithTimestamp() throws Exception {
FileInfo info1 = new FileInfo("foo", "19990101.124500", false);
FileInfo info2 = new FileInfo("foo", "19990101.124400", false);
FileInfo info1 = new FileInfo("foo", "19990101.124500", false, 0);
FileInfo info2 = new FileInfo("foo", "19990101.124400", false, 0);
assertEquals(-1, info1.compareTo(info2));

ArrayList<FileInfo> list = new ArrayList<FileInfo>(Arrays.asList(info1, info2));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright 2013-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 static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.equalTo;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.batch.admin.service.FileInfo;
import org.springframework.batch.admin.service.FileService;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.StepExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;

/**
* Tests REST compliance of {@link BatchJobInstancesController} endpoints.
*
* @author Ilayaperumal Gopinathan
* @author Michael Minella
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestDependencies.class, RestConfiguration.class})
@WebAppConfiguration
public class BatchFilesControllerIntegrationTests extends AbstractControllerIntegrationTest {

@Autowired
private FileService fileService;

@Before
public void before() throws Exception {
Date startTime = new Date();
Date endTime = new Date();
JobExecution execution = new JobExecution(3L,
new JobParametersBuilder().addString("foo", "bar").addLong("foo2", 0L).toJobParameters());
execution.setExitStatus(ExitStatus.COMPLETED);
execution.setStartTime(startTime);
execution.setEndTime(endTime);
execution.setLastUpdated(new Date());

StepExecution stepExecution = new StepExecution("s1", execution);
stepExecution.setLastUpdated(new Date());
stepExecution.setId(1l);
execution.addStepExecutions(Collections.singletonList(stepExecution));
}

@Test
public void testList() throws Exception {
List<FileInfo> files = new ArrayList<FileInfo>();
files.add(new FileInfo("foo.txt", "sometimestamp", true, 0));
files.add(new FileInfo("bar/foo.txt", "anothertimestamp", false, 0));
files.add(new FileInfo("bar/baz.txt", "lasttimestamp", true, 0));

when(fileService.getFiles(0, 10)).thenReturn(files);

mockMvc.perform(
get("/batch/files").param("page", "0").param("size", "10").accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.pagedResources.content.[*].timestamp", contains("sometimestamp", "anothertimestamp", "lasttimestamp")))
.andExpect(jsonPath("$.pagedResources.content.[*].path", contains("foo.txt", "bar/foo.txt", "bar/baz.txt")))
.andExpect(jsonPath("$.pagedResources.content.[*].shortPath", contains("foo.txt", "bar/foo.txt", "bar/baz.txt")))
.andExpect(jsonPath("$.pagedResources.content.[*].local", contains(true, false, true)));
}

@Test
public void testDelete() throws Exception {
when(fileService.delete("pattern")).thenReturn(3);

mockMvc.perform(
delete("/batch/files").param("pattern", "pattern").accept(MediaType.APPLICATION_JSON)).andDo(print()).andExpect(status().isOk())
.andExpect(jsonPath("$.fileInfoResource.deleteCount", equalTo(3)));
}
}

0 comments on commit 7313b5d

Please sign in to comment.