Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
spring-boot-admin
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
openSource
spring-boot-admin
Commits
86e21786
Commit
86e21786
authored
Jun 10, 2018
by
Johannes Edmeier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix flaky tests
Force the connections in wiremock tests to be closed. See
https://github.com/tomakehurst/wiremock/issues/485
parent
3eae8ab1
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
54 additions
and
43 deletions
+54
-43
AdminServerWebConfiguration.java
...boot/admin/server/config/AdminServerWebConfiguration.java
+4
-5
AbstractInstancesProxyController.java
...ot/admin/server/web/AbstractInstancesProxyController.java
+5
-9
InstanceWebClient.java
...ntric/boot/admin/server/web/client/InstanceWebClient.java
+6
-6
InstancesProxyController.java
...t/admin/server/web/reactive/InstancesProxyController.java
+2
-5
InstancesProxyController.java
...ot/admin/server/web/servlet/InstancesProxyController.java
+2
-5
AbstractInstancesProxyControllerIntegrationTest.java
.../web/AbstractInstancesProxyControllerIntegrationTest.java
+32
-8
InstanceExchangeFilterFunctionsTest.java
...erver/web/client/InstanceExchangeFilterFunctionsTest.java
+2
-3
application.yml
spring-boot-admin-server/src/test/resources/application.yml
+1
-2
No files found.
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/config/AdminServerWebConfiguration.java
View file @
86e21786
...
...
@@ -78,11 +78,11 @@ public class AdminServerWebConfiguration {
@Bean
@ConditionalOnMissingBean
public
de
.
codecentric
.
boot
.
admin
.
server
.
web
.
reactive
.
InstancesProxyController
instancesProxyController
(
Instance
Registry
instanceRegistry
,
Instance
WebClient
instanceWebClient
)
{
InstanceRegistry
instanceRegistry
,
InstanceWebClient
instanceWebClient
)
{
return
new
de
.
codecentric
.
boot
.
admin
.
server
.
web
.
reactive
.
InstancesProxyController
(
adminServerProperties
.
getContextPath
(),
adminServerProperties
.
getInstanceProxy
().
getIgnoredHeaders
(),
instanceRegistry
,
instanceWebClient
,
adminServerProperties
.
getMonitor
().
getReadTimeout
()
);
instanceRegistry
,
instanceWebClient
);
}
@Bean
...
...
@@ -110,8 +110,7 @@ public class AdminServerWebConfiguration {
public
InstancesProxyController
instancesProxyController
(
InstanceRegistry
instanceRegistry
,
InstanceWebClient
instanceWebClient
)
{
return
new
InstancesProxyController
(
adminServerProperties
.
getContextPath
(),
adminServerProperties
.
getInstanceProxy
().
getIgnoredHeaders
(),
instanceRegistry
,
instanceWebClient
,
adminServerProperties
.
getMonitor
().
getReadTimeout
());
adminServerProperties
.
getInstanceProxy
().
getIgnoredHeaders
(),
instanceRegistry
,
instanceWebClient
);
}
@Bean
...
...
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/web/AbstractInstancesProxyController.java
View file @
86e21786
...
...
@@ -21,12 +21,12 @@ import de.codecentric.boot.admin.server.domain.values.InstanceId;
import
de.codecentric.boot.admin.server.services.InstanceRegistry
;
import
de.codecentric.boot.admin.server.web.client.InstanceWebClient
;
import
de.codecentric.boot.admin.server.web.client.exception.ResolveEndpointException
;
import
io.netty.handler.timeout.ReadTimeoutException
;
import
reactor.core.publisher.Mono
;
import
java.io.IOException
;
import
java.net.ConnectException
;
import
java.net.URI
;
import
java.time.Duration
;
import
java.util.Arrays
;
import
java.util.Map
;
import
java.util.Set
;
...
...
@@ -55,21 +55,17 @@ public class AbstractInstancesProxyController {
private
final
InstanceRegistry
registry
;
private
final
InstanceWebClient
instanceWebClient
;
private
final
Set
<
String
>
ignoredHeaders
;
private
final
Duration
readTimeout
;
private
final
ExchangeStrategies
strategies
=
ExchangeStrategies
.
withDefaults
();
public
AbstractInstancesProxyController
(
String
adminContextPath
,
Set
<
String
>
ignoredHeaders
,
InstanceRegistry
registry
,
InstanceWebClient
instanceWebClient
,
Duration
readTimeout
)
{
InstanceRegistry
registry
,
InstanceWebClient
instanceWebClient
)
{
this
.
ignoredHeaders
=
Stream
.
concat
(
ignoredHeaders
.
stream
(),
Arrays
.
stream
(
HOP_BY_HOP_HEADERS
))
.
map
(
String:
:
toLowerCase
)
.
collect
(
Collectors
.
toSet
());
this
.
registry
=
registry
;
this
.
instanceWebClient
=
instanceWebClient
;
this
.
realRequestMappingPath
=
adminContextPath
+
REQUEST_MAPPING_PATH
;
this
.
readTimeout
=
readTimeout
;
}
protected
Mono
<
ClientResponse
>
forward
(
String
instanceId
,
...
...
@@ -104,17 +100,17 @@ public class AbstractInstancesProxyController {
}
}
return
headersSpec
.
exchange
().
timeout
(
this
.
readTimeout
,
Mono
.
fromSupplier
(()
->
{
return
headersSpec
.
exchange
().
onErrorResume
(
ReadTimeoutException
.
class
,
ex
->
Mono
.
fromSupplier
(()
->
{
log
.
trace
(
"Timeout for Proxy-Request for instance {} with URL '{}'"
,
instance
.
getId
(),
uri
);
return
ClientResponse
.
create
(
HttpStatus
.
GATEWAY_TIMEOUT
,
strategies
).
build
();
})).
onErrorResume
(
ResolveEndpointException
.
class
,
ex
->
Mono
.
fromSupplier
(()
->
{
log
.
trace
(
"No Endpoint found for Proxy-Request for instance {} with URL '{}'"
,
instance
.
getId
(),
uri
);
return
ClientResponse
.
create
(
HttpStatus
.
NOT_FOUND
,
strategies
).
build
();
})).
onErrorResume
(
IOException
.
class
,
ex
->
Mono
.
fromSupplier
(()
->
{
log
.
trace
(
"
Error for
Proxy-Request for instance {} with URL '{}' errored"
,
instance
.
getId
(),
uri
,
ex
);
log
.
trace
(
"Proxy-Request for instance {} with URL '{}' errored"
,
instance
.
getId
(),
uri
,
ex
);
return
ClientResponse
.
create
(
HttpStatus
.
BAD_GATEWAY
,
strategies
).
build
();
})).
onErrorResume
(
ConnectException
.
class
,
ex
->
Mono
.
fromSupplier
(()
->
{
log
.
trace
(
"
Error for Proxy-Request for instance {} with URL '{}' timed out
"
,
instance
.
getId
(),
uri
,
ex
);
log
.
trace
(
"
Connect for Proxy-Request for instance {} with URL '{}' failed
"
,
instance
.
getId
(),
uri
,
ex
);
return
ClientResponse
.
create
(
HttpStatus
.
BAD_GATEWAY
,
strategies
).
build
();
}));
}
...
...
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/web/client/InstanceWebClient.java
View file @
86e21786
...
...
@@ -63,14 +63,14 @@ public class InstanceWebClient {
}
public
WebClient
instance
(
Mono
<
Instance
>
instance
)
{
return
webClient
.
mutate
()
//
.
filters
(
filters
->
filters
.
add
(
0
,
InstanceExchangeFilterFunctions
.
setInstance
(
instance
)))
//
return
webClient
.
mutate
()
.
filters
(
filters
->
filters
.
add
(
0
,
InstanceExchangeFilterFunctions
.
setInstance
(
instance
)))
.
build
();
}
public
WebClient
instance
(
Instance
instance
)
{
return
webClient
.
mutate
()
//
.
filters
(
filters
->
filters
.
add
(
0
,
InstanceExchangeFilterFunctions
.
setInstance
(
instance
)))
//
return
webClient
.
mutate
()
.
filters
(
filters
->
filters
.
add
(
0
,
InstanceExchangeFilterFunctions
.
setInstance
(
instance
)))
.
build
();
}
...
...
@@ -78,8 +78,8 @@ public class InstanceWebClient {
Duration
readTimeout
,
WebClientCustomizer
customizer
)
{
ReactorClientHttpConnector
connector
=
new
ReactorClientHttpConnector
(
options
->
options
.
option
(
ChannelOption
.
CONNECT_TIMEOUT_MILLIS
,
(
int
)
connectTimeout
.
toMillis
())
//
.
compression
(
true
)
//
options
->
options
.
option
(
ChannelOption
.
CONNECT_TIMEOUT_MILLIS
,
(
int
)
connectTimeout
.
toMillis
())
.
compression
(
true
)
.
afterNettyContextInit
(
ctx
->
{
ctx
.
addHandlerLast
(
new
ReadTimeoutHandler
(
readTimeout
.
toMillis
(),
TimeUnit
.
MILLISECONDS
));
...
...
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/web/reactive/InstancesProxyController.java
View file @
86e21786
...
...
@@ -23,7 +23,6 @@ import de.codecentric.boot.admin.server.web.client.InstanceWebClient;
import
reactor.core.publisher.Mono
;
import
java.net.URI
;
import
java.time.Duration
;
import
java.util.Set
;
import
org.springframework.http.server.reactive.ServerHttpRequest
;
import
org.springframework.http.server.reactive.ServerHttpResponse
;
...
...
@@ -41,10 +40,8 @@ import org.springframework.web.util.UriComponentsBuilder;
public
class
InstancesProxyController
extends
AbstractInstancesProxyController
{
public
InstancesProxyController
(
String
adminContextPath
,
Set
<
String
>
ignoredHeaders
,
InstanceRegistry
registry
,
InstanceWebClient
instanceWebClient
,
Duration
readTimeout
)
{
super
(
adminContextPath
,
ignoredHeaders
,
registry
,
instanceWebClient
,
readTimeout
);
InstanceRegistry
registry
,
InstanceWebClient
instanceWebClient
)
{
super
(
adminContextPath
,
ignoredHeaders
,
registry
,
instanceWebClient
);
}
@RequestMapping
(
path
=
REQUEST_MAPPING_PATH
,
method
=
{
RequestMethod
.
GET
,
RequestMethod
.
HEAD
,
RequestMethod
.
POST
,
RequestMethod
.
PUT
,
RequestMethod
.
PATCH
,
RequestMethod
.
DELETE
,
RequestMethod
.
OPTIONS
})
...
...
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/server/web/servlet/InstancesProxyController.java
View file @
86e21786
...
...
@@ -26,7 +26,6 @@ import reactor.core.publisher.Mono;
import
java.io.IOException
;
import
java.io.OutputStream
;
import
java.net.URI
;
import
java.time.Duration
;
import
java.util.Set
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
...
...
@@ -57,10 +56,8 @@ public class InstancesProxyController extends AbstractInstancesProxyController {
public
InstancesProxyController
(
String
adminContextPath
,
Set
<
String
>
ignoredHeaders
,
InstanceRegistry
registry
,
InstanceWebClient
instanceWebClient
,
Duration
readTimeout
)
{
super
(
adminContextPath
,
ignoredHeaders
,
registry
,
instanceWebClient
,
readTimeout
);
InstanceRegistry
registry
,
InstanceWebClient
instanceWebClient
)
{
super
(
adminContextPath
,
ignoredHeaders
,
registry
,
instanceWebClient
);
}
@ResponseBody
...
...
spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/web/AbstractInstancesProxyControllerIntegrationTest.java
View file @
86e21786
...
...
@@ -31,7 +31,14 @@ import org.springframework.http.HttpStatus;
import
org.springframework.http.MediaType
;
import
org.springframework.test.web.reactive.server.EntityExchangeResult
;
import
org.springframework.test.web.reactive.server.WebTestClient
;
import
com.github.tomakehurst.wiremock.common.FileSource
;
import
com.github.tomakehurst.wiremock.extension.Parameters
;
import
com.github.tomakehurst.wiremock.extension.ResponseTransformer
;
import
com.github.tomakehurst.wiremock.http.Fault
;
import
com.github.tomakehurst.wiremock.http.HttpHeader
;
import
com.github.tomakehurst.wiremock.http.HttpHeaders
;
import
com.github.tomakehurst.wiremock.http.Request
;
import
com.github.tomakehurst.wiremock.http.Response
;
import
com.github.tomakehurst.wiremock.junit.WireMockClassRule
;
import
static
com
.
github
.
tomakehurst
.
wiremock
.
client
.
WireMock
.
aResponse
;
...
...
@@ -54,11 +61,8 @@ public abstract class AbstractInstancesProxyControllerIntegrationTest {
private
static
ParameterizedTypeReference
<
Map
<
String
,
Object
>>
RESPONSE_TYPE
=
new
ParameterizedTypeReference
<
Map
<
String
,
Object
>>()
{
};
@ClassRule
public
static
WireMockClassRule
wireMock
=
new
WireMockClassRule
(
options
().
dynamicPort
()
.
asynchronousResponseEnabled
(
true
)
.
asynchronousResponseThreads
(
10
)
.
jettyAcceptors
(
10
)
.
containerThreads
(
20
));
public
static
WireMockClassRule
wireMock
=
new
WireMockClassRule
(
options
().
dynamicPort
().
extensions
(
new
ConnectionCloseExtension
()));
private
static
WebTestClient
client
;
private
static
String
instanceId
;
...
...
@@ -87,12 +91,12 @@ public abstract class AbstractInstancesProxyControllerIntegrationTest {
wireMock
.
stubFor
(
get
(
urlEqualTo
(
"/mgmt/timeout"
)).
willReturn
(
ok
().
withFixedDelay
(
10000
)));
wireMock
.
stubFor
(
get
(
urlEqualTo
(
"/mgmt/test"
)).
willReturn
(
ok
(
"{ \"foo\" : \"bar\" }"
).
withHeader
(
CONTENT_TYPE
,
ACTUATOR_CONTENT_TYPE
)));
wireMock
.
stubFor
(
get
(
urlEqualTo
(
"/mgmt/test/has%20spaces"
)).
willReturn
(
ok
(
"{ \"foo\" : \"bar-with-spaces\" }"
).
withHeader
(
CONTENT_TYPE
,
ACTUATOR_CONTENT_TYPE
)));
wireMock
.
stubFor
(
post
(
urlEqualTo
(
"/mgmt/test"
)).
willReturn
(
ok
()));
wireMock
.
stubFor
(
delete
(
urlEqualTo
(
"/mgmt/test"
)).
willReturn
(
serverError
().
withBody
(
"{\"error\": \"You're doing it wrong!\"}"
)
.
withHeader
(
CONTENT_TYPE
,
ACTUATOR_CONTENT_TYPE
)));
wireMock
.
stubFor
(
get
(
urlEqualTo
(
"/mgmt/test/has%20spaces"
)).
willReturn
(
ok
(
"{ \"foo\" : \"bar-with-spaces\" }"
).
withHeader
(
CONTENT_TYPE
,
ACTUATOR_CONTENT_TYPE
)));
instanceId
=
registerInstance
(
managementUrl
);
}
...
...
@@ -139,7 +143,10 @@ public abstract class AbstractInstancesProxyControllerIntegrationTest {
.
uri
(
"/instances/{instanceId}/actuator/test"
,
instanceId
)
.
accept
(
ACTUATOR_V2_MEDIATYPE
)
.
exchange
()
.
expectStatus
().
isEqualTo
(
HttpStatus
.
OK
).
expectBody
(
String
.
class
).
isEqualTo
(
"{ \"foo\" : \"bar\" }"
);
.
expectStatus
()
.
isEqualTo
(
HttpStatus
.
OK
)
.
expectBody
(
String
.
class
)
.
isEqualTo
(
"{ \"foo\" : \"bar\" }"
);
client
.
post
()
.
uri
(
"/instances/{instanceId}/actuator/test"
,
instanceId
)
...
...
@@ -216,3 +223,20 @@ public abstract class AbstractInstancesProxyControllerIntegrationTest {
//@formatter:on
}
}
//Force the connections to be closed...
//see https://github.com/tomakehurst/wiremock/issues/485
class
ConnectionCloseExtension
extends
ResponseTransformer
{
@Override
public
Response
transform
(
Request
request
,
Response
response
,
FileSource
files
,
Parameters
parameters
)
{
return
Response
.
Builder
.
like
(
response
)
.
headers
(
HttpHeaders
.
copyOf
(
response
.
getHeaders
())
.
plus
(
new
HttpHeader
(
"Connection"
,
"Close"
)))
.
build
();
}
@Override
public
String
getName
()
{
return
"ConnectionCloseExtension"
;
}
}
spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/server/web/client/InstanceExchangeFilterFunctionsTest.java
View file @
86e21786
...
...
@@ -34,8 +34,8 @@ import org.springframework.web.reactive.function.client.ClientResponse;
import
org.springframework.web.reactive.function.client.ExchangeFilterFunction
;
import
static
de
.
codecentric
.
boot
.
admin
.
server
.
web
.
client
.
InstanceExchangeFilterFunctions
.
ATTRIBUTE_ENDPOINT
;
import
static
io
.
netty
.
handler
.
codec
.
http
.
HttpHeaders
.
Values
.
APPLICATION_JSON
;
import
static
org
.
springframework
.
http
.
HttpHeaders
.
CONTENT_TYPE
;
import
static
org
.
springframework
.
http
.
MediaType
.
APPLICATION_JSON_VALUE
;
public
class
InstanceExchangeFilterFunctionsTest
{
private
static
final
DefaultDataBufferFactory
BUFFER_FACTORY
=
new
DefaultDataBufferFactory
();
...
...
@@ -72,8 +72,7 @@ public class InstanceExchangeFilterFunctionsTest {
ClientRequest
request
=
ClientRequest
.
create
(
HttpMethod
.
GET
,
URI
.
create
(
"/test"
))
.
attribute
(
ATTRIBUTE_ENDPOINT
,
"test"
)
.
build
();
ClientResponse
response
=
ClientResponse
.
create
(
HttpStatus
.
OK
)
.
header
(
CONTENT_TYPE
,
APPLICATION_JSON
)
ClientResponse
response
=
ClientResponse
.
create
(
HttpStatus
.
OK
).
header
(
CONTENT_TYPE
,
APPLICATION_JSON_VALUE
)
.
body
(
Flux
.
just
(
ORIGINAL
))
.
build
();
...
...
spring-boot-admin-server/src/test/resources/application.yml
View file @
86e21786
...
...
@@ -7,4 +7,4 @@ spring:
enabled
:
false
logging
:
level
:
de.codecentric
:
DEBUG
\ No newline at end of file
de.codecentric
:
DEBUG
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment