Skip to content

Commit bf618d5

Browse files
committed
Merge branch '1.3.x
2 parents b8ad953 + b1dd928 commit bf618d5

File tree

2 files changed

+71
-21
lines changed

2 files changed

+71
-21
lines changed

spring-boot-devtools/src/main/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploader.java

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2015 the original author or authors.
2+
* Copyright 2012-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
1919
import java.io.ByteArrayOutputStream;
2020
import java.io.IOException;
2121
import java.io.ObjectOutputStream;
22+
import java.net.ConnectException;
2223
import java.net.MalformedURLException;
2324
import java.net.URI;
2425
import java.net.URISyntaxException;
@@ -51,6 +52,7 @@
5152
* Listens and pushes any classpath updates to a remote endpoint.
5253
*
5354
* @author Phillip Webb
55+
* @author Andy Wilkinson
5456
* @since 1.3.0
5557
*/
5658
public class ClassPathChangeUploader
@@ -91,23 +93,45 @@ public ClassPathChangeUploader(String url, ClientHttpRequestFactory requestFacto
9193
public void onApplicationEvent(ClassPathChangedEvent event) {
9294
try {
9395
ClassLoaderFiles classLoaderFiles = getClassLoaderFiles(event);
94-
ClientHttpRequest request = this.requestFactory.createRequest(this.uri,
95-
HttpMethod.POST);
9696
byte[] bytes = serialize(classLoaderFiles);
97-
HttpHeaders headers = request.getHeaders();
98-
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
99-
headers.setContentLength(bytes.length);
100-
FileCopyUtils.copy(bytes, request.getBody());
101-
logUpload(classLoaderFiles);
102-
ClientHttpResponse response = request.execute();
103-
Assert.state(response.getStatusCode() == HttpStatus.OK, "Unexpected "
104-
+ response.getStatusCode() + " response uploading class files");
97+
performUpload(classLoaderFiles, bytes);
10598
}
10699
catch (IOException ex) {
107100
throw new IllegalStateException(ex);
108101
}
109102
}
110103

104+
private void performUpload(ClassLoaderFiles classLoaderFiles, byte[] bytes)
105+
throws IOException {
106+
try {
107+
while (true) {
108+
try {
109+
ClientHttpRequest request = this.requestFactory
110+
.createRequest(this.uri, HttpMethod.POST);
111+
HttpHeaders headers = request.getHeaders();
112+
headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
113+
headers.setContentLength(bytes.length);
114+
FileCopyUtils.copy(bytes, request.getBody());
115+
ClientHttpResponse response = request.execute();
116+
Assert.state(response.getStatusCode() == HttpStatus.OK,
117+
"Unexpected " + response.getStatusCode()
118+
+ " response uploading class files");
119+
logUpload(classLoaderFiles);
120+
return;
121+
}
122+
catch (ConnectException ex) {
123+
logger.warn("Failed to connect when uploading to " + this.uri
124+
+ ". Upload will be retried in 2 seconds");
125+
Thread.sleep(2000);
126+
}
127+
}
128+
}
129+
catch (InterruptedException ex) {
130+
Thread.currentThread().interrupt();
131+
throw new IllegalStateException(ex);
132+
}
133+
}
134+
111135
private void logUpload(ClassLoaderFiles classLoaderFiles) {
112136
int size = classLoaderFiles.size();
113137
logger.info(

spring-boot-devtools/src/test/java/org/springframework/boot/devtools/remote/client/ClassPathChangeUploaderTests.java

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.io.File;
2121
import java.io.IOException;
2222
import java.io.ObjectInputStream;
23+
import java.net.ConnectException;
2324
import java.util.Collection;
2425
import java.util.Iterator;
2526
import java.util.LinkedHashSet;
@@ -50,6 +51,7 @@
5051
* Tests for {@link ClassPathChangeUploader}.
5152
*
5253
* @author Phillip Webb
54+
* @author Andy Wilkinson
5355
*/
5456
public class ClassPathChangeUploaderTests {
5557

@@ -101,19 +103,28 @@ public void urlMustNotBeMalformed() throws Exception {
101103
@Test
102104
public void sendsClassLoaderFiles() throws Exception {
103105
File sourceFolder = this.temp.newFolder();
104-
Set<ChangedFile> files = new LinkedHashSet<ChangedFile>();
105-
File file1 = createFile(sourceFolder, "File1");
106-
File file2 = createFile(sourceFolder, "File2");
107-
File file3 = createFile(sourceFolder, "File3");
108-
files.add(new ChangedFile(sourceFolder, file1, Type.ADD));
109-
files.add(new ChangedFile(sourceFolder, file2, Type.MODIFY));
110-
files.add(new ChangedFile(sourceFolder, file3, Type.DELETE));
111-
Set<ChangedFiles> changeSet = new LinkedHashSet<ChangedFiles>();
112-
changeSet.add(new ChangedFiles(sourceFolder, files));
113-
ClassPathChangedEvent event = new ClassPathChangedEvent(this, changeSet, false);
106+
ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder);
114107
this.requestFactory.willRespond(HttpStatus.OK);
115108
this.uploader.onApplicationEvent(event);
109+
assertThat(this.requestFactory.getExecutedRequests()).hasSize(1);
116110
MockClientHttpRequest request = this.requestFactory.getExecutedRequests().get(0);
111+
verifyUploadRequest(sourceFolder, request);
112+
}
113+
114+
@Test
115+
public void retriesOnConnectException() throws Exception {
116+
File sourceFolder = this.temp.newFolder();
117+
ClassPathChangedEvent event = createClassPathChangedEvent(sourceFolder);
118+
this.requestFactory.willRespond(new ConnectException());
119+
this.requestFactory.willRespond(HttpStatus.OK);
120+
this.uploader.onApplicationEvent(event);
121+
assertThat(this.requestFactory.getExecutedRequests()).hasSize(2);
122+
verifyUploadRequest(sourceFolder,
123+
this.requestFactory.getExecutedRequests().get(1));
124+
}
125+
126+
private void verifyUploadRequest(File sourceFolder, MockClientHttpRequest request)
127+
throws IOException, ClassNotFoundException {
117128
ClassLoaderFiles classLoaderFiles = deserialize(request.getBodyAsBytes());
118129
Collection<SourceFolder> sourceFolders = classLoaderFiles.getSourceFolders();
119130
assertThat(sourceFolders.size()).isEqualTo(1);
@@ -132,6 +143,21 @@ private void assertClassFile(ClassLoaderFile file, String content, Kind kind) {
132143
assertThat(file.getKind()).isEqualTo(kind);
133144
}
134145

146+
private ClassPathChangedEvent createClassPathChangedEvent(File sourceFolder)
147+
throws IOException {
148+
Set<ChangedFile> files = new LinkedHashSet<ChangedFile>();
149+
File file1 = createFile(sourceFolder, "File1");
150+
File file2 = createFile(sourceFolder, "File2");
151+
File file3 = createFile(sourceFolder, "File3");
152+
files.add(new ChangedFile(sourceFolder, file1, Type.ADD));
153+
files.add(new ChangedFile(sourceFolder, file2, Type.MODIFY));
154+
files.add(new ChangedFile(sourceFolder, file3, Type.DELETE));
155+
Set<ChangedFiles> changeSet = new LinkedHashSet<ChangedFiles>();
156+
changeSet.add(new ChangedFiles(sourceFolder, files));
157+
ClassPathChangedEvent event = new ClassPathChangedEvent(this, changeSet, false);
158+
return event;
159+
}
160+
135161
private File createFile(File sourceFolder, String name) throws IOException {
136162
File file = new File(sourceFolder, name);
137163
FileCopyUtils.copy(name.getBytes(), file);

0 commit comments

Comments
 (0)