Merge branch '1.3.x

This commit is contained in:
Andy Wilkinson 2016-07-13 10:38:03 +01:00
commit bf618d505c
2 changed files with 71 additions and 21 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2015 the original author or authors.
* Copyright 2012-2016 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.
@ -19,6 +19,7 @@ package org.springframework.boot.devtools.remote.client;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
@ -51,6 +52,7 @@ import org.springframework.util.FileCopyUtils;
* Listens and pushes any classpath updates to a remote endpoint.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.3.0
*/
public class ClassPathChangeUploader
@ -91,23 +93,45 @@ public class ClassPathChangeUploader
public void onApplicationEvent(ClassPathChangedEvent event) {
try {
ClassLoaderFiles classLoaderFiles = getClassLoaderFiles(event);
ClientHttpRequest request = this.requestFactory.createRequest(this.uri,
HttpMethod.POST);
byte[] bytes = serialize(classLoaderFiles);
HttpHeaders headers = request.getHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(bytes.length);
FileCopyUtils.copy(bytes, request.getBody());
logUpload(classLoaderFiles);
ClientHttpResponse response = request.execute();
Assert.state(response.getStatusCode() == HttpStatus.OK, "Unexpected "
+ response.getStatusCode() + " response uploading class files");
performUpload(classLoaderFiles, bytes);
}
catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes)
throws IOException {
try {
while (true) {
try {
ClientHttpRequest request = this.requestFactory
.createRequest(this.uri, HttpMethod.POST);
HttpHeaders headers = request.getHeaders();
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
headers.setContentLength(bytes.length);
FileCopyUtils.copy(bytes, request.getBody());
ClientHttpResponse response = request.execute();
Assert.state(response.getStatusCode() == HttpStatus.OK,
"Unexpected " + response.getStatusCode()
+ " response uploading class files");
logUpload(classLoaderFiles);
return;
}
catch (ConnectException ex) {
logger.warn("Failed to connect when uploading to " + this.uri
+ ". Upload will be retried in 2 seconds");
Thread.sleep(2000);
}
}
}
catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new IllegalStateException(ex);
}
}
private void logUpload(ClassLoaderFiles classLoaderFiles) {
int size = classLoaderFiles.size();
logger.info(

View File

@ -20,6 +20,7 @@ import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ConnectException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
@ -50,6 +51,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link ClassPathChangeUploader}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class ClassPathChangeUploaderTests {
@ -101,19 +103,28 @@ public class ClassPathChangeUploaderTests {
@Test
public void sendsClassLoaderFiles() throws Exception {
File sourceFolder = this.temp.newFolder();
Set<ChangedFile> files = new LinkedHashSet<ChangedFile>();
File file1 = createFile(sourceFolder, "File1");
File file2 = createFile(sourceFolder, "File2");
File file3 = createFile(sourceFolder, "File3");
files.add(new ChangedFile(sourceFolder, file1, Type.ADD));
files.add(new ChangedFile(sourceFolder, file2, Type.MODIFY));
files.add(new ChangedFile(sourceFolder, file3, Type.DELETE));
Set<ChangedFiles> changeSet = new LinkedHashSet<ChangedFiles>();
changeSet.add(new ChangedFiles(sourceFolder, files));
ClassPathChangedEvent event = new ClassPathChangedEvent(this, changeSet, false);
ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder);
this.requestFactory.willRespond(HttpStatus.OK);
this.uploader.onApplicationEvent(event);
assertThat(this.requestFactory.getExecutedRequests()).hasSize(1);
MockClientHttpRequest request = this.requestFactory.getExecutedRequests().get(0);
verifyUploadRequest(sourceFolder, request);
}
@Test
public void retriesOnConnectException() throws Exception {
File sourceFolder = this.temp.newFolder();
ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder);
this.requestFactory.willRespond(new ConnectException());
this.requestFactory.willRespond(HttpStatus.OK);
this.uploader.onApplicationEvent(event);
assertThat(this.requestFactory.getExecutedRequests()).hasSize(2);
verifyUploadRequest(sourceFolder,
this.requestFactory.getExecutedRequests().get(1));
}
private void verifyUploadRequest(File sourceFolder, MockClientHttpRequest request)
throws IOException, ClassNotFoundException {
ClassLoaderFiles classLoaderFiles = deserialize(request.getBodyAsBytes());
Collection<SourceFolder> sourceFolders = classLoaderFiles.getSourceFolders();
assertThat(sourceFolders.size()).isEqualTo(1);
@ -132,6 +143,21 @@ public class ClassPathChangeUploaderTests {
assertThat(file.getKind()).isEqualTo(kind);
}
private ClassPathChangedEvent createClassPathChangedEvent(File sourceFolder)
throws IOException {
Set<ChangedFile> files = new LinkedHashSet<ChangedFile>();
File file1 = createFile(sourceFolder, "File1");
File file2 = createFile(sourceFolder, "File2");
File file3 = createFile(sourceFolder, "File3");
files.add(new ChangedFile(sourceFolder, file1, Type.ADD));
files.add(new ChangedFile(sourceFolder, file2, Type.MODIFY));
files.add(new ChangedFile(sourceFolder, file3, Type.DELETE));
Set<ChangedFiles> changeSet = new LinkedHashSet<ChangedFiles>();
changeSet.add(new ChangedFiles(sourceFolder, files));
ClassPathChangedEvent event = new ClassPathChangedEvent(this, changeSet, false);
return event;
}
private File createFile(File sourceFolder, String name) throws IOException {
File file = new File(sourceFolder, name);
FileCopyUtils.copy(name.getBytes(), file);