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
8e2ce75d
Commit
8e2ce75d
authored
Mar 04, 2015
by
Johannes Stelzer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #51 from joshiste/api-gateway
Zuul-Reverse-Proxy for registered applications and removal of CORS-stuff
parents
4302e92d
e52f6c75
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
423 additions
and
370 deletions
+423
-370
pom.xml
pom.xml
+27
-0
application.js
spring-boot-admin-server-ui/app/js/service/application.js
+7
-7
applicationJmx.js
spring-boot-admin-server-ui/app/js/service/applicationJmx.js
+4
-4
applicationLogging.js
...boot-admin-server-ui/app/js/service/applicationLogging.js
+3
-3
package.json
spring-boot-admin-server-ui/package.json
+1
-1
pom.xml
spring-boot-admin-server/pom.xml
+36
-0
WebappConfig.java
...n/java/de/codecentric/boot/admin/config/WebappConfig.java
+185
-0
RegistryController.java
...codecentric/boot/admin/controller/RegistryController.java
+2
-1
ClientApplicationEvent.java
.../codecentric/boot/admin/event/ClientApplicationEvent.java
+24
-0
ClientApplicationRegisteredEvent.java
...ic/boot/admin/event/ClientApplicationRegisteredEvent.java
+12
-0
ClientApplicationUnregisteredEvent.java
.../boot/admin/event/ClientApplicationUnregisteredEvent.java
+12
-0
ApplicationRegistry.java
.../codecentric/boot/admin/registry/ApplicationRegistry.java
+15
-1
ApplicationRouteLocator.java
.../codecentric/boot/admin/zuul/ApplicationRouteLocator.java
+38
-0
ApplicationRouteRefreshListener.java
...tric/boot/admin/zuul/ApplicationRouteRefreshListener.java
+24
-0
AdminApplicationHazelcastTest.java
...codecentric/boot/admin/AdminApplicationHazelcastTest.java
+2
-2
AdminApplicationTest.java
.../java/de/codecentric/boot/admin/AdminApplicationTest.java
+18
-7
RegistryControllerTest.java
...centric/boot/admin/controller/RegistryControllerTest.java
+7
-2
ApplicationRegistryTest.java
...ecentric/boot/admin/registry/ApplicationRegistryTest.java
+6
-0
SpringBootAdminClientAutoConfiguration.java
.../admin/config/SpringBootAdminClientAutoConfiguration.java
+0
-65
EndpointCorsInterceptor.java
...e/codecentric/boot/admin/web/EndpointCorsInterceptor.java
+0
-56
CorsFilterOnDifferentPortsTest.java
...entric/boot/admin/web/CorsFilterOnDifferentPortsTest.java
+0
-112
CorsFilterOnSamePortsTest.java
...codecentric/boot/admin/web/CorsFilterOnSamePortsTest.java
+0
-109
No files found.
pom.xml
View file @
8e2ce75d
...
@@ -26,6 +26,7 @@
...
@@ -26,6 +26,7 @@
<spring-boot.version>
1.2.2.RELEASE
</spring-boot.version>
<spring-boot.version>
1.2.2.RELEASE
</spring-boot.version>
<hazelcast.version>
3.3.3
</hazelcast.version>
<hazelcast.version>
3.3.3
</hazelcast.version>
<commons-lang3.version>
3.3.2
</commons-lang3.version>
<commons-lang3.version>
3.3.2
</commons-lang3.version>
<spring-cloud.version>
1.0.0.RELEASE
</spring-cloud.version>
<build-plugin.jacoco.version>
0.7.3.201502191951
</build-plugin.jacoco.version>
<build-plugin.jacoco.version>
0.7.3.201502191951
</build-plugin.jacoco.version>
<build-plugin.coveralls.version>
3.0.1
</build-plugin.coveralls.version>
<build-plugin.coveralls.version>
3.0.1
</build-plugin.coveralls.version>
...
@@ -220,6 +221,23 @@
...
@@ -220,6 +221,23 @@
<artifactId>
spring-boot-starter-web
</artifactId>
<artifactId>
spring-boot-starter-web
</artifactId>
<version>
${spring-boot.version}
</version>
<version>
${spring-boot.version}
</version>
</dependency>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-zuul
</artifactId>
<version>
${spring-cloud.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-netflix-core
</artifactId>
<version>
${spring-cloud.version}
</version>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-commons
</artifactId>
<version>
${spring-cloud.version}
</version>
</dependency>
<dependency>
<dependency>
<groupId>
org.apache.commons
</groupId>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<artifactId>
commons-lang3
</artifactId>
...
@@ -244,4 +262,13 @@
...
@@ -244,4 +262,13 @@
</dependency>
</dependency>
</dependencies>
</dependencies>
</dependencyManagement>
</dependencyManagement>
<repositories>
<repository>
<id>
spring-release
</id>
<snapshots>
<enabled>
false
</enabled>
</snapshots>
<url>
http://repo.spring.io/release
</url>
</repository>
</repositories>
</project>
</project>
spring-boot-admin-server-ui/app/js/service/application.js
View file @
8e2ce75d
...
@@ -32,31 +32,31 @@ module.exports = function ($resource, $http, $rootScope) {
...
@@ -32,31 +32,31 @@ module.exports = function ($resource, $http, $rootScope) {
};
};
Application
.
prototype
.
getHealth
=
function
()
{
Application
.
prototype
.
getHealth
=
function
()
{
return
$http
.
get
(
this
.
url
+
'/health'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
get
(
'api/applications/'
+
this
.
id
+
'/health'
).
error
(
new
AuthInterceptor
(
this
));
};
};
Application
.
prototype
.
getInfo
=
function
()
{
Application
.
prototype
.
getInfo
=
function
()
{
return
$http
.
get
(
this
.
url
+
'/info'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
get
(
'api/applications/'
+
this
.
id
+
'/info'
).
error
(
new
AuthInterceptor
(
this
));
};
};
Application
.
prototype
.
getMetrics
=
function
()
{
Application
.
prototype
.
getMetrics
=
function
()
{
return
$http
.
get
(
this
.
url
+
'/metrics'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
get
(
'api/applications/'
+
this
.
id
+
'/metrics'
).
error
(
new
AuthInterceptor
(
this
));
};
};
Application
.
prototype
.
getEnv
=
function
()
{
Application
.
prototype
.
getEnv
=
function
()
{
return
$http
.
get
(
this
.
url
+
'/env'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
get
(
'api/applications/'
+
this
.
id
+
'/env'
).
error
(
new
AuthInterceptor
(
this
));
};
};
Application
.
prototype
.
getThreadDump
=
function
()
{
Application
.
prototype
.
getThreadDump
=
function
()
{
return
$http
.
get
(
this
.
url
+
'/dump'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
get
(
'api/applications/'
+
this
.
id
+
'/dump'
).
error
(
new
AuthInterceptor
(
this
));
};
};
Application
.
prototype
.
getTraces
=
function
()
{
Application
.
prototype
.
getTraces
=
function
()
{
return
$http
.
get
(
this
.
url
+
'/trace'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
get
(
'api/applications/'
+
this
.
id
+
'/trace'
).
error
(
new
AuthInterceptor
(
this
));
};
};
Application
.
prototype
.
hasLogfile
=
function
()
{
Application
.
prototype
.
hasLogfile
=
function
()
{
return
$http
.
head
(
this
.
url
+
'/logfile'
).
error
(
new
AuthInterceptor
(
this
));
return
$http
.
head
(
'api/applications/'
+
this
.
id
+
'/logfile'
).
error
(
new
AuthInterceptor
(
this
));
};
};
return
Application
;
return
Application
;
...
...
spring-boot-admin-server-ui/app/js/service/applicationJmx.js
View file @
8e2ce75d
...
@@ -17,7 +17,7 @@
...
@@ -17,7 +17,7 @@
module
.
exports
=
function
(
$rootScope
,
Abbreviator
,
jolokia
)
{
module
.
exports
=
function
(
$rootScope
,
Abbreviator
,
jolokia
)
{
this
.
list
=
function
(
app
)
{
this
.
list
=
function
(
app
)
{
return
jolokia
.
list
(
app
.
url
+
'/jolokia/'
)
return
jolokia
.
list
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
)
.
then
(
function
(
response
)
{
.
then
(
function
(
response
)
{
var
domains
=
[];
var
domains
=
[];
for
(
var
rDomainName
in
response
.
value
)
{
for
(
var
rDomainName
in
response
.
value
)
{
...
@@ -81,14 +81,14 @@ module.exports = function ($rootScope, Abbreviator, jolokia) {
...
@@ -81,14 +81,14 @@ module.exports = function ($rootScope, Abbreviator, jolokia) {
};
};
this
.
readAllAttr
=
function
(
app
,
bean
)
{
this
.
readAllAttr
=
function
(
app
,
bean
)
{
return
jolokia
.
read
(
app
.
url
+
'/jolokia/'
,
bean
.
id
);
return
jolokia
.
read
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
,
bean
.
id
);
};
};
this
.
writeAttr
=
function
(
app
,
bean
,
attr
,
val
)
{
this
.
writeAttr
=
function
(
app
,
bean
,
attr
,
val
)
{
return
jolokia
.
writeAttr
(
app
.
url
+
'/jolokia/'
,
bean
.
id
,
attr
,
val
);
return
jolokia
.
writeAttr
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
,
bean
.
id
,
attr
,
val
);
};
};
this
.
invoke
=
function
(
app
,
bean
,
opname
,
args
)
{
this
.
invoke
=
function
(
app
,
bean
,
opname
,
args
)
{
return
jolokia
.
exec
(
app
.
url
+
'/jolokia/'
,
bean
.
id
,
opname
,
args
);
return
jolokia
.
exec
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
,
bean
.
id
,
opname
,
args
);
};
};
};
};
spring-boot-admin-server-ui/app/js/service/applicationLogging.js
View file @
8e2ce75d
...
@@ -29,16 +29,16 @@ module.exports = function ($http, jolokia) {
...
@@ -29,16 +29,16 @@ module.exports = function ($http, jolokia) {
arguments
:
[
loggers
[
j
].
name
]
arguments
:
[
loggers
[
j
].
name
]
});
});
}
}
return
jolokia
.
bulkRequest
(
app
.
url
+
'/jolokia/'
,
requests
);
return
jolokia
.
bulkRequest
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
,
requests
);
};
};
this
.
setLoglevel
=
function
(
app
,
logger
,
level
)
{
this
.
setLoglevel
=
function
(
app
,
logger
,
level
)
{
return
jolokia
.
exec
(
app
.
url
+
'/jolokia/'
,
LOGBACK_MBEAN
,
'setLoggerLevel'
,
[
logger
,
return
jolokia
.
exec
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
,
LOGBACK_MBEAN
,
'setLoggerLevel'
,
[
logger
,
level
level
]);
]);
};
};
this
.
getAllLoggers
=
function
(
app
)
{
this
.
getAllLoggers
=
function
(
app
)
{
return
jolokia
.
readAttr
(
app
.
url
+
'/jolokia/'
,
LOGBACK_MBEAN
,
'LoggerList'
);
return
jolokia
.
readAttr
(
'/api/applications/'
+
app
.
id
+
'/jolokia/'
,
LOGBACK_MBEAN
,
'LoggerList'
);
};
};
};
};
spring-boot-admin-server-ui/package.json
View file @
8e2ce75d
{
{
"name"
:
"spring-boot-admin-server-ui"
,
"name"
:
"spring-boot-admin-server-ui"
,
"version"
:
"1.1.
1
"
,
"version"
:
"1.1.
3
"
,
"scripts"
:
{
"scripts"
:
{
"postinstall"
:
"./node_modules/protractor/bin/webdriver-manager update"
,
"postinstall"
:
"./node_modules/protractor/bin/webdriver-manager update"
,
"pretest"
:
"./node_modules/protractor/bin/webdriver-manager start &"
,
"pretest"
:
"./node_modules/protractor/bin/webdriver-manager start &"
,
...
...
spring-boot-admin-server/pom.xml
View file @
8e2ce75d
...
@@ -25,6 +25,42 @@
...
@@ -25,6 +25,42 @@
<groupId>
org.apache.commons
</groupId>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<artifactId>
commons-lang3
</artifactId>
</dependency>
</dependency>
<!-- Use Zuul WITHOUT Hystrix/Ribbon/Config Client -->
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-zuul
</artifactId>
<exclusions>
<exclusion>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter
</artifactId>
</exclusion>
<exclusion>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-hystrix
</artifactId>
</exclusion>
<exclusion>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-starter-ribbon
</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-netflix-core
</artifactId>
</dependency>
<dependency>
<groupId>
org.springframework.cloud
</groupId>
<artifactId>
spring-cloud-commons
</artifactId>
</dependency>
<dependency>
<groupId>
org.apache.httpcomponents
</groupId>
<artifactId>
httpclient
</artifactId>
<version>
4.3.6
</version>
</dependency>
<!-- Hazelcast-Support -->
<dependency>
<dependency>
<groupId>
com.hazelcast
</groupId>
<groupId>
com.hazelcast
</groupId>
<artifactId>
hazelcast
</artifactId>
<artifactId>
hazelcast
</artifactId>
...
...
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/config/WebappConfig.java
View file @
8e2ce75d
...
@@ -16,12 +16,33 @@
...
@@ -16,12 +16,33 @@
package
de
.
codecentric
.
boot
.
admin
.
config
;
package
de
.
codecentric
.
boot
.
admin
.
config
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.actuate.endpoint.Endpoint
;
import
org.springframework.boot.actuate.trace.TraceRepository
;
import
org.springframework.boot.autoconfigure.AutoConfigureBefore
;
import
org.springframework.boot.autoconfigure.AutoConfigureBefore
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnClass
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnExpression
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnExpression
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.web.ServerProperties
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.cloud.netflix.zuul.RoutesEndpoint
;
import
org.springframework.cloud.netflix.zuul.ZuulFilterInitializer
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator
;
import
org.springframework.cloud.netflix.zuul.filters.RouteLocator
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties
;
import
org.springframework.cloud.netflix.zuul.filters.post.SendErrorFilter
;
import
org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter
;
import
org.springframework.cloud.netflix.zuul.filters.pre.DebugFilter
;
import
org.springframework.cloud.netflix.zuul.filters.pre.FormBodyWrapperFilter
;
import
org.springframework.cloud.netflix.zuul.filters.pre.PreDecorationFilter
;
import
org.springframework.cloud.netflix.zuul.filters.pre.Servlet30WrapperFilter
;
import
org.springframework.cloud.netflix.zuul.filters.route.SimpleHostRoutingFilter
;
import
org.springframework.cloud.netflix.zuul.web.ZuulController
;
import
org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.converter.HttpMessageConverter
;
import
org.springframework.http.converter.HttpMessageConverter
;
...
@@ -29,9 +50,13 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
...
@@ -29,9 +50,13 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConvert
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
;
import
org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter
;
import
com.hazelcast.config.Config
;
import
com.hazelcast.config.Config
;
import
com.hazelcast.core.EntryEvent
;
import
com.hazelcast.core.EntryListener
;
import
com.hazelcast.core.Hazelcast
;
import
com.hazelcast.core.Hazelcast
;
import
com.hazelcast.core.HazelcastInstance
;
import
com.hazelcast.core.HazelcastInstance
;
import
com.hazelcast.core.IMap
;
import
com.hazelcast.core.IMap
;
import
com.hazelcast.core.MapEvent
;
import
com.netflix.zuul.ZuulFilter
;
import
de.codecentric.boot.admin.controller.RegistryController
;
import
de.codecentric.boot.admin.controller.RegistryController
;
import
de.codecentric.boot.admin.model.Application
;
import
de.codecentric.boot.admin.model.Application
;
...
@@ -41,6 +66,8 @@ import de.codecentric.boot.admin.registry.HashingApplicationUrlIdGenerator;
...
@@ -41,6 +66,8 @@ import de.codecentric.boot.admin.registry.HashingApplicationUrlIdGenerator;
import
de.codecentric.boot.admin.registry.store.ApplicationStore
;
import
de.codecentric.boot.admin.registry.store.ApplicationStore
;
import
de.codecentric.boot.admin.registry.store.HazelcastApplicationStore
;
import
de.codecentric.boot.admin.registry.store.HazelcastApplicationStore
;
import
de.codecentric.boot.admin.registry.store.SimpleApplicationStore
;
import
de.codecentric.boot.admin.registry.store.SimpleApplicationStore
;
import
de.codecentric.boot.admin.zuul.ApplicationRouteLocator
;
import
de.codecentric.boot.admin.zuul.ApplicationRouteRefreshListener
;
@Configuration
@Configuration
public
class
WebappConfig
extends
WebMvcConfigurerAdapter
{
public
class
WebappConfig
extends
WebMvcConfigurerAdapter
{
...
@@ -89,6 +116,115 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
...
@@ -89,6 +116,115 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
}
}
@Configuration
@Configuration
@EnableConfigurationProperties
(
ZuulProperties
.
class
)
public
static
class
RevereseZuulProxyConfiguration
{
@Autowired
(
required
=
false
)
private
TraceRepository
traces
;
@Autowired
private
ZuulProperties
zuulProperties
;
@Autowired
private
ServerProperties
server
;
@Autowired
private
ApplicationRegistry
registry
;
@Bean
public
ApplicationRouteLocator
routeLocator
()
{
return
new
ApplicationRouteLocator
(
this
.
server
.
getServletPrefix
(),
registry
,
this
.
zuulProperties
,
RegistryController
.
PATH
);
}
@Bean
public
PreDecorationFilter
preDecorationFilter
()
{
return
new
PreDecorationFilter
(
routeLocator
(),
this
.
zuulProperties
.
isAddProxyHeaders
());
}
@Bean
public
SimpleHostRoutingFilter
simpleHostRoutingFilter
()
{
ProxyRequestHelper
helper
=
new
ProxyRequestHelper
();
if
(
this
.
traces
!=
null
)
{
helper
.
setTraces
(
this
.
traces
);
}
return
new
SimpleHostRoutingFilter
(
helper
);
}
@Bean
public
ZuulController
zuulController
()
{
return
new
ZuulController
();
}
@Bean
public
ZuulHandlerMapping
zuulHandlerMapping
(
RouteLocator
routes
)
{
return
new
ZuulHandlerMapping
(
routes
,
zuulController
());
}
// pre filters
@Bean
public
FormBodyWrapperFilter
formBodyWrapperFilter
()
{
return
new
FormBodyWrapperFilter
();
}
@Bean
public
DebugFilter
debugFilter
()
{
return
new
DebugFilter
();
}
@Bean
public
Servlet30WrapperFilter
servlet30WrapperFilter
()
{
return
new
Servlet30WrapperFilter
();
}
// post filters
@Bean
public
SendResponseFilter
sendResponseFilter
()
{
return
new
SendResponseFilter
();
}
@Bean
public
SendErrorFilter
sendErrorFilter
()
{
return
new
SendErrorFilter
();
}
@Configuration
protected
static
class
ZuulFilterConfiguration
{
@Autowired
private
Map
<
String
,
ZuulFilter
>
filters
;
@Bean
public
ZuulFilterInitializer
zuulFilterInitializer
()
{
return
new
ZuulFilterInitializer
(
this
.
filters
);
}
}
@Bean
ApplicationRouteRefreshListener
applicationRouteRefreshListener
()
{
return
new
ApplicationRouteRefreshListener
(
routeLocator
(),
zuulHandlerMapping
(
routeLocator
()));
}
@Configuration
@ConditionalOnClass
(
Endpoint
.
class
)
protected
static
class
RoutesEndpointConfiguration
{
@Autowired
private
ProxyRouteLocator
routeLocator
;
@Bean
public
RoutesEndpoint
zuulEndpoint
()
{
return
new
RoutesEndpoint
(
this
.
routeLocator
);
}
}
}
@Configuration
@ConditionalOnClass
({
Hazelcast
.
class
})
@ConditionalOnClass
({
Hazelcast
.
class
})
@ConditionalOnExpression
(
"${spring.boot.admin.hazelcast.enable:true}"
)
@ConditionalOnExpression
(
"${spring.boot.admin.hazelcast.enable:true}"
)
@AutoConfigureBefore
(
SimpleConfig
.
class
)
@AutoConfigureBefore
(
SimpleConfig
.
class
)
...
@@ -114,8 +250,57 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
...
@@ -114,8 +250,57 @@ public class WebappConfig extends WebMvcConfigurerAdapter {
public
ApplicationStore
applicationStore
(
HazelcastInstance
hazelcast
)
{
public
ApplicationStore
applicationStore
(
HazelcastInstance
hazelcast
)
{
IMap
<
String
,
Application
>
map
=
hazelcast
.<
String
,
Application
>
getMap
(
hazelcastMapName
);
IMap
<
String
,
Application
>
map
=
hazelcast
.<
String
,
Application
>
getMap
(
hazelcastMapName
);
map
.
addIndex
(
"name"
,
false
);
map
.
addIndex
(
"name"
,
false
);
map
.
addEntryListener
(
entryListener
(),
false
);
return
new
HazelcastApplicationStore
(
map
);
return
new
HazelcastApplicationStore
(
map
);
}
}
@Bean
public
EntryListener
<
String
,
Application
>
entryListener
()
{
return
new
ApplicationEntryListener
();
}
private
static
class
ApplicationEntryListener
implements
EntryListener
<
String
,
Application
>
{
@Autowired
private
ZuulHandlerMapping
zuulHandlerMapping
;
@Autowired
private
ApplicationRouteLocator
routeLocator
;
private
void
reset
()
{
routeLocator
.
resetRoutes
();
zuulHandlerMapping
.
registerHandlers
();
}
@Override
public
void
entryAdded
(
EntryEvent
<
String
,
Application
>
event
)
{
reset
();
}
@Override
public
void
entryRemoved
(
EntryEvent
<
String
,
Application
>
event
)
{
reset
();
}
@Override
public
void
entryUpdated
(
EntryEvent
<
String
,
Application
>
event
)
{
reset
();
}
@Override
public
void
entryEvicted
(
EntryEvent
<
String
,
Application
>
event
)
{
reset
();
}
@Override
public
void
mapEvicted
(
MapEvent
event
)
{
reset
();
}
@Override
public
void
mapCleared
(
MapEvent
event
)
{
reset
();
}
}
}
}
}
}
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/controller/RegistryController.java
View file @
8e2ce75d
...
@@ -36,8 +36,9 @@ import de.codecentric.boot.admin.registry.ApplicationRegistryConflictException;
...
@@ -36,8 +36,9 @@ import de.codecentric.boot.admin.registry.ApplicationRegistryConflictException;
* REST controller for controlling registration of managed applications.
* REST controller for controlling registration of managed applications.
*/
*/
@RestController
@RestController
@RequestMapping
(
value
=
"/api/applications"
)
@RequestMapping
(
value
=
RegistryController
.
PATH
)
public
class
RegistryController
{
public
class
RegistryController
{
public
static
final
String
PATH
=
"/api/applications"
;
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
RegistryController
.
class
);
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
RegistryController
.
class
);
...
...
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/event/ClientApplicationEvent.java
0 → 100644
View file @
8e2ce75d
package
de
.
codecentric
.
boot
.
admin
.
event
;
import
org.springframework.context.ApplicationEvent
;
import
de.codecentric.boot.admin.model.Application
;
/**
* Abstract Event regearding spring boot admin clients
* @author Johannes Stelzer
*/
public
abstract
class
ClientApplicationEvent
extends
ApplicationEvent
{
private
static
final
long
serialVersionUID
=
1L
;
private
final
Application
application
;
public
ClientApplicationEvent
(
Object
source
,
Application
application
)
{
super
(
source
);
this
.
application
=
application
;
}
public
Application
getApplication
()
{
return
application
;
}
}
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/event/ClientApplicationRegisteredEvent.java
0 → 100644
View file @
8e2ce75d
package
de
.
codecentric
.
boot
.
admin
.
event
;
import
de.codecentric.boot.admin.model.Application
;
public
class
ClientApplicationRegisteredEvent
extends
ClientApplicationEvent
{
public
ClientApplicationRegisteredEvent
(
Object
source
,
Application
application
)
{
super
(
source
,
application
);
}
private
static
final
long
serialVersionUID
=
1L
;
}
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/event/ClientApplicationUnregisteredEvent.java
0 → 100644
View file @
8e2ce75d
package
de
.
codecentric
.
boot
.
admin
.
event
;
import
de.codecentric.boot.admin.model.Application
;
public
class
ClientApplicationUnregisteredEvent
extends
ClientApplicationEvent
{
public
ClientApplicationUnregisteredEvent
(
Object
source
,
Application
application
)
{
super
(
source
,
application
);
}
private
static
final
long
serialVersionUID
=
1L
;
}
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/registry/ApplicationRegistry.java
View file @
8e2ce75d
...
@@ -22,7 +22,11 @@ import java.util.Collection;
...
@@ -22,7 +22,11 @@ import java.util.Collection;
import
org.apache.commons.lang3.Validate
;
import
org.apache.commons.lang3.Validate
;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationContextAware
;
import
de.codecentric.boot.admin.event.ClientApplicationRegisteredEvent
;
import
de.codecentric.boot.admin.event.ClientApplicationUnregisteredEvent
;
import
de.codecentric.boot.admin.model.Application
;
import
de.codecentric.boot.admin.model.Application
;
import
de.codecentric.boot.admin.registry.store.ApplicationStore
;
import
de.codecentric.boot.admin.registry.store.ApplicationStore
;
...
@@ -30,11 +34,12 @@ import de.codecentric.boot.admin.registry.store.ApplicationStore;
...
@@ -30,11 +34,12 @@ import de.codecentric.boot.admin.registry.store.ApplicationStore;
* Registry for all applications that should be managed/administrated by the Spring Boot Admin application.
* Registry for all applications that should be managed/administrated by the Spring Boot Admin application.
* Backed by an ApplicationStore for persistence and an ApplicationIdGenerator for id generation.
* Backed by an ApplicationStore for persistence and an ApplicationIdGenerator for id generation.
*/
*/
public
class
ApplicationRegistry
{
public
class
ApplicationRegistry
implements
ApplicationContextAware
{
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
ApplicationRegistry
.
class
);
private
static
final
Logger
LOGGER
=
LoggerFactory
.
getLogger
(
ApplicationRegistry
.
class
);
private
final
ApplicationStore
store
;
private
final
ApplicationStore
store
;
private
final
ApplicationIdGenerator
generator
;
private
final
ApplicationIdGenerator
generator
;
private
ApplicationContext
context
;
public
ApplicationRegistry
(
ApplicationStore
store
,
ApplicationIdGenerator
generator
)
{
public
ApplicationRegistry
(
ApplicationStore
store
,
ApplicationIdGenerator
generator
)
{
this
.
store
=
store
;
this
.
store
=
store
;
...
@@ -59,6 +64,7 @@ public class ApplicationRegistry {
...
@@ -59,6 +64,7 @@ public class ApplicationRegistry {
if
(
oldApp
==
null
)
{
if
(
oldApp
==
null
)
{
LOGGER
.
info
(
"New Application {} registered "
,
newApp
);
LOGGER
.
info
(
"New Application {} registered "
,
newApp
);
context
.
publishEvent
(
new
ClientApplicationRegisteredEvent
(
this
,
newApp
));
}
else
{
}
else
{
if
((
app
.
getUrl
().
equals
(
oldApp
.
getUrl
())
&&
app
.
getName
().
equals
(
oldApp
.
getName
())))
{
if
((
app
.
getUrl
().
equals
(
oldApp
.
getUrl
())
&&
app
.
getName
().
equals
(
oldApp
.
getName
())))
{
LOGGER
.
debug
(
"Application {} refreshed"
,
newApp
);
LOGGER
.
debug
(
"Application {} refreshed"
,
newApp
);
...
@@ -121,7 +127,15 @@ public class ApplicationRegistry {
...
@@ -121,7 +127,15 @@ public class ApplicationRegistry {
*/
*/
public
Application
unregister
(
String
id
)
{
public
Application
unregister
(
String
id
)
{
Application
app
=
store
.
delete
(
id
);
Application
app
=
store
.
delete
(
id
);
if
(
app
!=
null
)
{
LOGGER
.
info
(
"Application {} unregistered "
,
app
);
LOGGER
.
info
(
"Application {} unregistered "
,
app
);
context
.
publishEvent
(
new
ClientApplicationUnregisteredEvent
(
this
,
app
));
}
return
app
;
return
app
;
}
}
@Override
public
void
setApplicationContext
(
ApplicationContext
applicationContext
)
{
this
.
context
=
applicationContext
;
}
}
}
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/zuul/ApplicationRouteLocator.java
0 → 100644
View file @
8e2ce75d
package
de
.
codecentric
.
boot
.
admin
.
zuul
;
import
java.util.LinkedHashMap
;
import
org.springframework.cloud.netflix.zuul.filters.ProxyRouteLocator
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties
;
import
org.springframework.cloud.netflix.zuul.filters.ZuulProperties.ZuulRoute
;
import
de.codecentric.boot.admin.model.Application
;
import
de.codecentric.boot.admin.registry.ApplicationRegistry
;
public
class
ApplicationRouteLocator
extends
ProxyRouteLocator
{
private
ApplicationRegistry
registry
;
private
String
prefix
;
public
ApplicationRouteLocator
(
String
servletPath
,
ApplicationRegistry
registry
,
ZuulProperties
properties
,
String
prefix
)
{
super
(
servletPath
,
null
,
properties
);
this
.
registry
=
registry
;
this
.
prefix
=
prefix
;
}
@Override
protected
LinkedHashMap
<
String
,
ZuulRoute
>
locateRoutes
()
{
LinkedHashMap
<
String
,
ZuulRoute
>
locateRoutes
=
super
.
locateRoutes
();
if
(
registry
!=
null
)
{
for
(
Application
application
:
registry
.
getApplications
())
{
String
key
=
prefix
+
"/"
+
application
.
getId
()
+
"/*/**"
;
locateRoutes
.
put
(
key
,
new
ZuulRoute
(
key
,
application
.
getUrl
()));
}
}
return
locateRoutes
;
}
}
spring-boot-admin-server/src/main/java/de/codecentric/boot/admin/zuul/ApplicationRouteRefreshListener.java
0 → 100644
View file @
8e2ce75d
package
de
.
codecentric
.
boot
.
admin
.
zuul
;
import
org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping
;
import
org.springframework.context.ApplicationListener
;
import
de.codecentric.boot.admin.event.ClientApplicationEvent
;
public
class
ApplicationRouteRefreshListener
implements
ApplicationListener
<
ClientApplicationEvent
>
{
private
final
ApplicationRouteLocator
routeLocator
;
private
final
ZuulHandlerMapping
zuulHandlerMapping
;
public
ApplicationRouteRefreshListener
(
ApplicationRouteLocator
routeLocator
,
ZuulHandlerMapping
zuulHandlerMapping
)
{
this
.
routeLocator
=
routeLocator
;
this
.
zuulHandlerMapping
=
zuulHandlerMapping
;
}
@Override
public
void
onApplicationEvent
(
ClientApplicationEvent
event
)
{
this
.
routeLocator
.
resetRoutes
();
this
.
zuulHandlerMapping
.
registerHandlers
();
}
}
spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/AdminApplicationHazelcastTest.java
View file @
8e2ce75d
...
@@ -70,8 +70,8 @@ public class AdminApplicationHazelcastTest {
...
@@ -70,8 +70,8 @@ public class AdminApplicationHazelcastTest {
@After
@After
public
void
shutdown
()
{
public
void
shutdown
()
{
instance1
.
stop
();
instance1
.
close
();
instance2
.
stop
();
instance2
.
close
();
}
}
@Test
@Test
...
...
spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/AdminApplicationTest.java
View file @
8e2ce75d
...
@@ -18,23 +18,23 @@ package de.codecentric.boot.admin;
...
@@ -18,23 +18,23 @@ package de.codecentric.boot.admin;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.test.IntegrationTest
;
import
org.springframework.boot.test.SpringApplicationConfiguration
;
import
org.springframework.boot.test.SpringApplicationConfiguration
;
import
org.springframework.boot.test.TestRestTemplate
;
import
org.springframework.boot.test.TestRestTemplate
;
import
org.springframework.boot.test.WebIntegrationTest
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.context.web.WebAppConfiguration
;
import
org.springframework.web.client.RestTemplate
;
import
de.codecentric.boot.admin.AdminApplicationTest.TestAdminApplication
;
import
de.codecentric.boot.admin.AdminApplicationTest.TestAdminApplication
;
import
de.codecentric.boot.admin.config.EnableAdminServer
;
import
de.codecentric.boot.admin.config.EnableAdminServer
;
import
de.codecentric.boot.admin.model.Application
;
/**
/**
*
*
...
@@ -44,12 +44,9 @@ import de.codecentric.boot.admin.config.EnableAdminServer;
...
@@ -44,12 +44,9 @@ import de.codecentric.boot.admin.config.EnableAdminServer;
*/
*/
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringApplicationConfiguration
(
classes
=
TestAdminApplication
.
class
)
@SpringApplicationConfiguration
(
classes
=
TestAdminApplication
.
class
)
@WebAppConfiguration
@WebIntegrationTest
({
"server.port=0"
})
@IntegrationTest
({
"server.port=0"
})
public
class
AdminApplicationTest
{
public
class
AdminApplicationTest
{
RestTemplate
restTemplate
=
new
TestRestTemplate
();
@Value
(
"${local.server.port}"
)
@Value
(
"${local.server.port}"
)
private
int
port
=
0
;
private
int
port
=
0
;
...
@@ -61,6 +58,20 @@ public class AdminApplicationTest {
...
@@ -61,6 +58,20 @@ public class AdminApplicationTest {
assertEquals
(
HttpStatus
.
OK
,
entity
.
getStatusCode
());
assertEquals
(
HttpStatus
.
OK
,
entity
.
getStatusCode
());
}
}
@Test
public
void
testReverseProxy
()
{
String
apiBaseUrl
=
"http://localhost:"
+
port
+
"/api/applications"
;
ResponseEntity
<
Application
>
entity
=
new
TestRestTemplate
().
postForEntity
(
apiBaseUrl
,
new
Application
(
"http://localhost:"
+
port
,
"TestApp"
),
Application
.
class
);
@SuppressWarnings
(
"rawtypes"
)
ResponseEntity
<
Map
>
health
=
new
TestRestTemplate
().
getForEntity
(
apiBaseUrl
+
"/"
+
entity
.
getBody
().
getId
()
+
"/info"
,
Map
.
class
);
assertEquals
(
HttpStatus
.
OK
,
health
.
getStatusCode
());
}
@Configuration
@Configuration
@EnableAutoConfiguration
@EnableAutoConfiguration
@EnableAdminServer
@EnableAdminServer
...
...
spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/controller/RegistryControllerTest.java
View file @
8e2ce75d
...
@@ -23,6 +23,8 @@ import java.util.Collection;
...
@@ -23,6 +23,8 @@ import java.util.Collection;
import
org.junit.Before
;
import
org.junit.Before
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.mockito.Mockito
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.http.ResponseEntity
;
...
@@ -34,11 +36,14 @@ import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
...
@@ -34,11 +36,14 @@ import de.codecentric.boot.admin.registry.store.SimpleApplicationStore;
public
class
RegistryControllerTest
{
public
class
RegistryControllerTest
{
private
RegistryController
controller
;
private
RegistryController
controller
;
private
ApplicationRegistry
registry
;
@Before
@Before
public
void
setup
()
{
public
void
setup
()
{
controller
=
new
RegistryController
(
new
ApplicationRegistry
(
new
SimpleApplicationStore
(),
registry
=
new
ApplicationRegistry
(
new
SimpleApplicationStore
(),
new
HashingApplicationUrlIdGenerator
()));
new
HashingApplicationUrlIdGenerator
());
registry
.
setApplicationContext
(
Mockito
.
mock
(
ApplicationContext
.
class
));
controller
=
new
RegistryController
(
registry
);
}
}
@Test
@Test
...
...
spring-boot-admin-server/src/test/java/de/codecentric/boot/admin/registry/ApplicationRegistryTest.java
View file @
8e2ce75d
...
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertTrue;
...
@@ -23,6 +23,8 @@ import static org.junit.Assert.assertTrue;
import
java.util.Collection
;
import
java.util.Collection
;
import
org.junit.Test
;
import
org.junit.Test
;
import
org.mockito.Mockito
;
import
org.springframework.context.ApplicationContext
;
import
de.codecentric.boot.admin.model.Application
;
import
de.codecentric.boot.admin.model.Application
;
import
de.codecentric.boot.admin.registry.store.SimpleApplicationStore
;
import
de.codecentric.boot.admin.registry.store.SimpleApplicationStore
;
...
@@ -32,6 +34,10 @@ public class ApplicationRegistryTest {
...
@@ -32,6 +34,10 @@ public class ApplicationRegistryTest {
private
ApplicationRegistry
registry
=
new
ApplicationRegistry
(
new
SimpleApplicationStore
(),
private
ApplicationRegistry
registry
=
new
ApplicationRegistry
(
new
SimpleApplicationStore
(),
new
HashingApplicationUrlIdGenerator
());
new
HashingApplicationUrlIdGenerator
());
public
ApplicationRegistryTest
()
{
registry
.
setApplicationContext
(
Mockito
.
mock
(
ApplicationContext
.
class
));
}
@Test
(
expected
=
NullPointerException
.
class
)
@Test
(
expected
=
NullPointerException
.
class
)
public
void
registerFailed1
()
throws
Exception
{
public
void
registerFailed1
()
throws
Exception
{
registry
.
register
(
new
Application
(
null
,
null
));
registry
.
register
(
new
Application
(
null
,
null
));
...
...
spring-boot-starter-admin-client/src/main/java/de/codecentric/boot/admin/config/SpringBootAdminClientAutoConfiguration.java
View file @
8e2ce75d
...
@@ -15,34 +15,22 @@
...
@@ -15,34 +15,22 @@
*/
*/
package
de
.
codecentric
.
boot
.
admin
.
config
;
package
de
.
codecentric
.
boot
.
admin
.
config
;
import
java.lang.reflect.Field
;
import
java.util.Arrays
;
import
java.util.Arrays
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMapping
;
import
org.springframework.boot.actuate.endpoint.mvc.EndpointHandlerMappingCustomizer
;
import
org.springframework.boot.actuate.endpoint.mvc.JolokiaMvcEndpoint
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnExpression
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnExpression
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
;
import
org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.boot.context.properties.EnableConfigurationProperties
;
import
org.springframework.context.ApplicationContext
;
import
org.springframework.context.ApplicationListener
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Bean
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.client.ClientHttpRequestInterceptor
;
import
org.springframework.http.client.ClientHttpRequestInterceptor
;
import
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
;
import
org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
;
import
org.springframework.scheduling.config.ScheduledTaskRegistrar
;
import
org.springframework.scheduling.config.ScheduledTaskRegistrar
;
import
org.springframework.util.ReflectionUtils
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.client.RestTemplate
;
import
org.springframework.web.servlet.DispatcherServlet
;
import
org.springframework.web.servlet.mvc.ServletWrappingController
;
import
de.codecentric.boot.admin.actuate.LogfileMvcEndpoint
;
import
de.codecentric.boot.admin.actuate.LogfileMvcEndpoint
;
import
de.codecentric.boot.admin.services.SpringBootAdminRegistrator
;
import
de.codecentric.boot.admin.services.SpringBootAdminRegistrator
;
import
de.codecentric.boot.admin.web.BasicAuthHttpRequestInterceptor
;
import
de.codecentric.boot.admin.web.BasicAuthHttpRequestInterceptor
;
import
de.codecentric.boot.admin.web.EndpointCorsInterceptor
;
/**
/**
* This configuration adds a registrator bean to the spring context. This bean checks periodicaly, if the using
* This configuration adds a registrator bean to the spring context. This bean checks periodicaly, if the using
...
@@ -105,57 +93,4 @@ public class SpringBootAdminClientAutoConfiguration {
...
@@ -105,57 +93,4 @@ public class SpringBootAdminClientAutoConfiguration {
}
}
}
}
@Bean
protected
EndpointCorsInterceptor
endpointCorsInterceptor
()
{
return
new
EndpointCorsInterceptor
();
}
@Bean
protected
EndpointHandlerMappingCustomizer
endpointHandlerMappingCustomizer
()
{
return
new
EndpointHandlerMappingCustomizer
()
{
@Override
public
void
customize
(
EndpointHandlerMapping
mapping
)
{
mapping
.
setInterceptors
(
new
Object
[]
{
endpointCorsInterceptor
()
});
}
};
}
@Autowired
private
ApplicationContext
applicationContext
;
@Bean
public
ApplicationListener
<
EmbeddedServletContainerInitializedEvent
>
appListener
()
{
/*
* Set jolokias AgentServlet to support Options request and the Dispatcher servlet
* to forward such. Done in this nasty way in case a second servlet-container is
* spun up, when management.port != server.port Also @see
* https://github.com/spring-projects/spring-boot/issues/1987
*/
return
new
ApplicationListener
<
EmbeddedServletContainerInitializedEvent
>()
{
@Override
public
void
onApplicationEvent
(
EmbeddedServletContainerInitializedEvent
event
)
{
// set DispatcherServlet to forward OptionsRequest
for
(
DispatcherServlet
servlet
:
event
.
getApplicationContext
()
.
getBeansOfType
(
DispatcherServlet
.
class
).
values
())
{
servlet
.
setDispatchOptionsRequest
(
true
);
}
// set Jolokias ServletWrappingController to support OPTIONS
for
(
JolokiaMvcEndpoint
jolokiaMvcEndpoint
:
SpringBootAdminClientAutoConfiguration
.
this
.
applicationContext
.
getBeansOfType
(
JolokiaMvcEndpoint
.
class
).
values
())
{
try
{
Field
controllerField
=
JolokiaMvcEndpoint
.
class
.
getDeclaredField
(
"controller"
);
ReflectionUtils
.
makeAccessible
(
controllerField
);
ServletWrappingController
controller
=
(
ServletWrappingController
)
controllerField
.
get
(
jolokiaMvcEndpoint
);
controller
.
setSupportedMethods
(
"GET"
,
"HEAD"
,
"POST"
,
"OPTIONS"
);
}
catch
(
Exception
ex
)
{
throw
new
RuntimeException
(
"Couldn't reconfigure servletWrappingController for Jolokia"
,
ex
);
}
}
}
};
}
}
}
spring-boot-starter-admin-client/src/main/java/de/codecentric/boot/admin/web/EndpointCorsInterceptor.java
deleted
100644 → 0
View file @
4302e92d
/*
* 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
de
.
codecentric
.
boot
.
admin
.
web
;
import
javax.servlet.http.HttpServletRequest
;
import
javax.servlet.http.HttpServletResponse
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.web.servlet.handler.HandlerInterceptorAdapter
;
public
class
EndpointCorsInterceptor
extends
HandlerInterceptorAdapter
{
// Configurable origin for CORS - default: * (all)
@Value
(
"${http.filter.cors.origin:*}"
)
private
String
origin
;
@Value
(
"${http.filter.cors.headers:Origin, X-Requested-With, Content-Type, Accept}"
)
private
String
headers
;
@Override
public
boolean
preHandle
(
HttpServletRequest
request
,
HttpServletResponse
response
,
Object
handler
)
throws
Exception
{
response
.
setHeader
(
"Access-Control-Allow-Origin"
,
origin
);
response
.
setHeader
(
"Access-Control-Allow-Headers"
,
headers
);
return
super
.
preHandle
(
request
,
response
,
handler
);
}
public
void
setOrigin
(
String
origin
)
{
this
.
origin
=
origin
;
}
public
String
getOrigin
()
{
return
origin
;
}
public
String
getHeaders
()
{
return
headers
;
}
public
void
setHeaders
(
String
headers
)
{
this
.
headers
=
headers
;
}
}
spring-boot-starter-admin-client/src/test/java/de/codecentric/boot/admin/web/CorsFilterOnDifferentPortsTest.java
deleted
100644 → 0
View file @
4302e92d
/*
* 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
de
.
codecentric
.
boot
.
admin
.
web
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
java.util.Arrays
;
import
java.util.Map
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.test.IntegrationTest
;
import
org.springframework.boot.test.SpringApplicationConfiguration
;
import
org.springframework.boot.test.TestRestTemplate
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpEntity
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.context.web.WebAppConfiguration
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.client.RestTemplate
;
import
de.codecentric.boot.admin.web.CorsFilterOnDifferentPortsTest.TestAdminApplication
;
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringApplicationConfiguration
(
classes
=
TestAdminApplication
.
class
)
@WebAppConfiguration
@IntegrationTest
({
"server.port=0"
,
"management.port=0"
,
"spring.boot.admin.url=http://localhost:65000"
})
public
class
CorsFilterOnDifferentPortsTest
{
RestTemplate
restTemplate
=
new
TestRestTemplate
();
@Value
(
"${local.server.port}"
)
private
int
serverPort
=
0
;
@Value
(
"${local.management.port}"
)
private
int
managementPort
=
0
;
@Test
@SuppressWarnings
(
"rawtypes"
)
public
void
testCORS_GET_info_endpoint
()
{
// DO serve CORS-Headers on management-endpoints
ResponseEntity
<
Map
>
info
=
new
TestRestTemplate
().
getForEntity
(
"http://localhost:"
+
managementPort
+
"/info"
,
Map
.
class
);
assertEquals
(
HttpStatus
.
OK
,
info
.
getStatusCode
());
assertEquals
(
Arrays
.
asList
(
"*"
),
info
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
Arrays
.
asList
(
"Origin, X-Requested-With, Content-Type, Accept"
),
info
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Test
public
void
testCORS_OPTIONS_jolokia_endpoint
()
{
// DO serve CORS-Headers on management-endpoints
ResponseEntity
<
Void
>
options
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
managementPort
+
"/jolokia"
,
HttpMethod
.
OPTIONS
,
HttpEntity
.
EMPTY
,
Void
.
class
);
assertEquals
(
HttpStatus
.
OK
,
options
.
getStatusCode
());
assertEquals
(
Arrays
.
asList
(
"*"
),
options
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
Arrays
.
asList
(
"Origin, X-Requested-With, Content-Type, Accept"
),
options
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Test
public
void
testCORS_GET_application
()
{
// DO NOT serve CORS-Headers on application-endpoints
ResponseEntity
<
String
>
hello
=
new
TestRestTemplate
().
getForEntity
(
"http://localhost:"
+
serverPort
+
"/hello"
,
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
hello
.
getStatusCode
());
assertEquals
(
null
,
hello
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
null
,
hello
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Test
public
void
testCORS_OPTIONS_application
()
{
// DO NOT serve CORS-Headers on application-endpoints
ResponseEntity
<
Void
>
options
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
serverPort
+
"/hello"
,
HttpMethod
.
OPTIONS
,
HttpEntity
.
EMPTY
,
Void
.
class
);
assertEquals
(
HttpStatus
.
OK
,
options
.
getStatusCode
());
assertEquals
(
null
,
options
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
null
,
options
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Configuration
@EnableAutoConfiguration
@RestController
public
static
class
TestAdminApplication
{
@RequestMapping
(
"/hello"
)
public
String
hello
()
{
return
"hello world!"
;
}
}
}
\ No newline at end of file
spring-boot-starter-admin-client/src/test/java/de/codecentric/boot/admin/web/CorsFilterOnSamePortsTest.java
deleted
100644 → 0
View file @
4302e92d
/*
* 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
de
.
codecentric
.
boot
.
admin
.
web
;
import
static
org
.
junit
.
Assert
.
assertEquals
;
import
java.util.Arrays
;
import
java.util.Map
;
import
org.junit.Test
;
import
org.junit.runner.RunWith
;
import
org.springframework.beans.factory.annotation.Value
;
import
org.springframework.boot.autoconfigure.EnableAutoConfiguration
;
import
org.springframework.boot.test.IntegrationTest
;
import
org.springframework.boot.test.SpringApplicationConfiguration
;
import
org.springframework.boot.test.TestRestTemplate
;
import
org.springframework.context.annotation.Configuration
;
import
org.springframework.http.HttpEntity
;
import
org.springframework.http.HttpMethod
;
import
org.springframework.http.HttpStatus
;
import
org.springframework.http.ResponseEntity
;
import
org.springframework.test.context.junit4.SpringJUnit4ClassRunner
;
import
org.springframework.test.context.web.WebAppConfiguration
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
org.springframework.web.client.RestTemplate
;
import
de.codecentric.boot.admin.web.CorsFilterOnSamePortsTest.TestAdminApplication
;
@RunWith
(
SpringJUnit4ClassRunner
.
class
)
@SpringApplicationConfiguration
(
classes
=
TestAdminApplication
.
class
)
@WebAppConfiguration
@IntegrationTest
({
"server.port=0"
,
"spring.boot.admin.url=http://localhost:65000"
})
public
class
CorsFilterOnSamePortsTest
{
RestTemplate
restTemplate
=
new
TestRestTemplate
();
@Value
(
"${local.server.port}"
)
private
int
serverPort
=
0
;
@Test
@SuppressWarnings
(
"rawtypes"
)
public
void
testCORS_GET_info_endpoint
()
{
// DO serve CORS-Headers on management-endpoints
ResponseEntity
<
Map
>
info
=
new
TestRestTemplate
().
getForEntity
(
"http://localhost:"
+
serverPort
+
"/info"
,
Map
.
class
);
assertEquals
(
HttpStatus
.
OK
,
info
.
getStatusCode
());
assertEquals
(
Arrays
.
asList
(
"*"
),
info
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
Arrays
.
asList
(
"Origin, X-Requested-With, Content-Type, Accept"
),
info
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Test
public
void
testCORS_OPTIONS_jolokia_endpoint
()
{
// DO serve CORS-Headers on management-endpoints
ResponseEntity
<
Void
>
options
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
serverPort
+
"/jolokia"
,
HttpMethod
.
OPTIONS
,
HttpEntity
.
EMPTY
,
Void
.
class
);
assertEquals
(
HttpStatus
.
OK
,
options
.
getStatusCode
());
assertEquals
(
Arrays
.
asList
(
"*"
),
options
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
Arrays
.
asList
(
"Origin, X-Requested-With, Content-Type, Accept"
),
options
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Test
public
void
testCORS_GET_application
()
{
// DO NOT serve CORS-Headers on application-endpoints
ResponseEntity
<
String
>
hello
=
new
TestRestTemplate
().
getForEntity
(
"http://localhost:"
+
serverPort
+
"/hello"
,
String
.
class
);
assertEquals
(
HttpStatus
.
OK
,
hello
.
getStatusCode
());
assertEquals
(
null
,
hello
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
null
,
hello
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Test
public
void
testCORS_OPTIONS_application
()
{
// DO NOT serve CORS-Headers on application-endpoints
ResponseEntity
<
Void
>
options
=
new
TestRestTemplate
().
exchange
(
"http://localhost:"
+
serverPort
+
"/hello"
,
HttpMethod
.
OPTIONS
,
HttpEntity
.
EMPTY
,
Void
.
class
);
assertEquals
(
HttpStatus
.
OK
,
options
.
getStatusCode
());
assertEquals
(
null
,
options
.
getHeaders
().
get
(
"Access-Control-Allow-Origin"
));
assertEquals
(
null
,
options
.
getHeaders
().
get
(
"Access-Control-Allow-Headers"
));
}
@Configuration
@EnableAutoConfiguration
@RestController
public
static
class
TestAdminApplication
{
@RequestMapping
(
"/hello"
)
public
String
hello
()
{
return
"hello world!"
;
}
}
}
\ No newline at end of file
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