Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in / Register
Toggle navigation
S
spring-boot
Project
Project
Details
Activity
Releases
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
DEMO
spring-boot
Commits
3ea7c2e0
Commit
3ea7c2e0
authored
Jun 20, 2018
by
Andy Wilkinson
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch '2.0.x'
parents
c90f5899
4fc0a330
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
151 additions
and
24 deletions
+151
-24
UndertowReactiveWebServerFactory.java
...b/embedded/undertow/UndertowReactiveWebServerFactory.java
+27
-14
UndertowServletWebServerFactory.java
...eb/embedded/undertow/UndertowServletWebServerFactory.java
+51
-10
UndertowWebServer.java
...amework/boot/web/embedded/undertow/UndertowWebServer.java
+20
-0
UndertowReactiveWebServerFactoryTests.java
...edded/undertow/UndertowReactiveWebServerFactoryTests.java
+53
-0
No files found.
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactory.java
View file @
3ea7c2e0
...
...
@@ -16,6 +16,7 @@
package
org
.
springframework
.
boot
.
web
.
embedded
.
undertow
;
import
java.io.Closeable
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
...
...
@@ -28,7 +29,6 @@ import io.undertow.Undertow;
import
io.undertow.UndertowOptions
;
import
io.undertow.server.HttpHandler
;
import
io.undertow.server.handlers.accesslog.AccessLogHandler
;
import
io.undertow.server.handlers.accesslog.AccessLogReceiver
;
import
io.undertow.server.handlers.accesslog.DefaultAccessLogReceiver
;
import
io.undertow.servlet.api.DeploymentInfo
;
import
org.xnio.OptionMap
;
...
...
@@ -96,9 +96,8 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF
public
WebServer
getWebServer
(
org
.
springframework
.
http
.
server
.
reactive
.
HttpHandler
httpHandler
)
{
Undertow
.
Builder
builder
=
createBuilder
(
getPort
());
HttpHandler
handler
=
createUndertowHandler
(
httpHandler
);
builder
.
setHandler
(
handler
);
return
new
UndertowWebServer
(
builder
,
getPort
()
>=
0
);
Closeable
closeable
=
configureHandler
(
builder
,
httpHandler
);
return
new
UndertowWebServer
(
builder
,
getPort
()
>=
0
,
closeable
);
}
private
Undertow
.
Builder
createBuilder
(
int
port
)
{
...
...
@@ -127,7 +126,7 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF
return
builder
;
}
private
HttpHandler
createUndertowHandler
(
private
Closeable
configureHandler
(
Undertow
.
Builder
builder
,
org
.
springframework
.
http
.
server
.
reactive
.
HttpHandler
httpHandler
)
{
HttpHandler
handler
=
new
UndertowHttpHandlerAdapter
(
httpHandler
);
if
(
this
.
useForwardHeaders
)
{
...
...
@@ -135,25 +134,39 @@ public class UndertowReactiveWebServerFactory extends AbstractReactiveWebServerF
}
handler
=
UndertowCompressionConfigurer
.
configureCompression
(
getCompression
(),
handler
);
Closeable
closeable
=
null
;
if
(
isAccessLogEnabled
())
{
handler
=
createAccessLogHandler
(
handler
);
closeable
=
configureAccessLogHandler
(
builder
,
handler
);
}
return
handler
;
else
{
builder
.
setHandler
(
handler
);
}
return
closeable
;
}
private
AccessLogHandler
createAccessLogHandler
(
io
.
undertow
.
server
.
HttpHandler
handler
)
{
private
Closeable
configureAccessLogHandler
(
Undertow
.
Builder
builder
,
HttpHandler
handler
)
{
try
{
createAccessLogDirectoryIfNecessary
();
XnioWorker
worker
=
createWorker
();
String
prefix
=
(
this
.
accessLogPrefix
!=
null
?
this
.
accessLogPrefix
:
"access_log."
);
AccessLogReceiver
accessLogReceiver
=
new
DefaultAccessLogReceiver
(
createWorker
()
,
this
.
accessLogDirectory
,
prefix
,
this
.
accessLogSuffix
,
Default
AccessLogReceiver
accessLogReceiver
=
new
DefaultAccessLogReceiver
(
worker
,
this
.
accessLogDirectory
,
prefix
,
this
.
accessLogSuffix
,
this
.
accessLogRotate
);
String
formatString
=
(
this
.
accessLogPattern
!=
null
?
this
.
accessLogPattern
String
formatString
=
(
(
this
.
accessLogPattern
!=
null
)
?
this
.
accessLogPattern
:
"common"
);
return
new
AccessLogHandler
(
handler
,
accessLogReceiver
,
formatString
,
Undertow
.
class
.
getClassLoader
());
builder
.
setHandler
(
new
AccessLogHandler
(
handler
,
accessLogReceiver
,
formatString
,
Undertow
.
class
.
getClassLoader
()));
return
()
->
{
try
{
accessLogReceiver
.
close
();
worker
.
shutdown
();
}
catch
(
IOException
ex
)
{
throw
new
IllegalStateException
(
ex
);
}
};
}
catch
(
IOException
ex
)
{
throw
new
IllegalStateException
(
"Failed to create AccessLogHandler"
,
ex
);
...
...
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowServletWebServerFactory.java
View file @
3ea7c2e0
...
...
@@ -25,11 +25,14 @@ import java.util.ArrayList;
import
java.util.Arrays
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.EventListener
;
import
java.util.List
;
import
java.util.Set
;
import
javax.servlet.ServletContainerInitializer
;
import
javax.servlet.ServletContext
;
import
javax.servlet.ServletContextEvent
;
import
javax.servlet.ServletContextListener
;
import
javax.servlet.ServletException
;
import
io.undertow.Undertow
;
...
...
@@ -48,6 +51,7 @@ import io.undertow.server.session.SessionManager;
import
io.undertow.servlet.Servlets
;
import
io.undertow.servlet.api.DeploymentInfo
;
import
io.undertow.servlet.api.DeploymentManager
;
import
io.undertow.servlet.api.ListenerInfo
;
import
io.undertow.servlet.api.MimeMapping
;
import
io.undertow.servlet.api.ServletContainerInitializerInfo
;
import
io.undertow.servlet.api.ServletStackTraces
;
...
...
@@ -292,27 +296,35 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
}
private
void
configureAccessLog
(
DeploymentInfo
deploymentInfo
)
{
deploymentInfo
.
addInitialHandlerChainWrapper
(
this
::
createAccessLogHandler
);
}
private
AccessLogHandler
createAccessLogHandler
(
HttpHandler
handler
)
{
try
{
createAccessLogDirectoryIfNecessary
();
XnioWorker
worker
=
createWorker
();
String
prefix
=
(
this
.
accessLogPrefix
!=
null
?
this
.
accessLogPrefix
:
"access_log."
);
AccessLogReceiver
accessLogReceiver
=
new
DefaultAccessLogReceiver
(
createWorker
()
,
this
.
accessLogDirectory
,
prefix
,
this
.
accessLogSuffix
,
Default
AccessLogReceiver
accessLogReceiver
=
new
DefaultAccessLogReceiver
(
worker
,
this
.
accessLogDirectory
,
prefix
,
this
.
accessLogSuffix
,
this
.
accessLogRotate
);
String
formatString
=
(
this
.
accessLogPattern
!=
null
?
this
.
accessLogPattern
:
"common"
);
return
new
AccessLogHandler
(
handler
,
accessLogReceiver
,
formatString
,
Undertow
.
class
.
getClassLoader
());
EventListener
listener
=
new
AccessLogShutdownListener
(
worker
,
accessLogReceiver
);
deploymentInfo
.
addListener
(
new
ListenerInfo
(
AccessLogShutdownListener
.
class
,
new
ImmediateInstanceFactory
<
EventListener
>(
listener
)));
deploymentInfo
.
addInitialHandlerChainWrapper
(
(
handler
)
->
createAccessLogHandler
(
handler
,
accessLogReceiver
));
}
catch
(
IOException
ex
)
{
throw
new
IllegalStateException
(
"Failed to create AccessLogHandler"
,
ex
);
}
}
private
AccessLogHandler
createAccessLogHandler
(
HttpHandler
handler
,
AccessLogReceiver
accessLogReceiver
)
{
createAccessLogDirectoryIfNecessary
();
String
formatString
=
((
this
.
accessLogPattern
!=
null
)
?
this
.
accessLogPattern
:
"common"
);
return
new
AccessLogHandler
(
handler
,
accessLogReceiver
,
formatString
,
Undertow
.
class
.
getClassLoader
());
}
private
void
createAccessLogDirectoryIfNecessary
()
{
Assert
.
state
(
this
.
accessLogDirectory
!=
null
,
"Access log directory is not set"
);
if
(!
this
.
accessLogDirectory
.
isDirectory
()
&&
!
this
.
accessLogDirectory
.
mkdirs
())
{
...
...
@@ -645,4 +657,33 @@ public class UndertowServletWebServerFactory extends AbstractServletWebServerFac
}
private
static
class
AccessLogShutdownListener
implements
ServletContextListener
{
private
final
XnioWorker
worker
;
private
final
DefaultAccessLogReceiver
accessLogReceiver
;
AccessLogShutdownListener
(
XnioWorker
worker
,
DefaultAccessLogReceiver
accessLogReceiver
)
{
this
.
worker
=
worker
;
this
.
accessLogReceiver
=
accessLogReceiver
;
}
@Override
public
void
contextInitialized
(
ServletContextEvent
sce
)
{
}
@Override
public
void
contextDestroyed
(
ServletContextEvent
sce
)
{
try
{
this
.
accessLogReceiver
.
close
();
this
.
worker
.
shutdown
();
}
catch
(
IOException
ex
)
{
throw
new
IllegalStateException
(
ex
);
}
}
}
}
spring-boot-project/spring-boot/src/main/java/org/springframework/boot/web/embedded/undertow/UndertowWebServer.java
View file @
3ea7c2e0
...
...
@@ -16,6 +16,7 @@
package
org
.
springframework
.
boot
.
web
.
embedded
.
undertow
;
import
java.io.Closeable
;
import
java.lang.reflect.Field
;
import
java.net.BindException
;
import
java.net.InetSocketAddress
;
...
...
@@ -56,6 +57,8 @@ public class UndertowWebServer implements WebServer {
private
final
boolean
autoStart
;
private
final
Closeable
closeable
;
private
Undertow
undertow
;
private
volatile
boolean
started
=
false
;
...
...
@@ -66,8 +69,21 @@ public class UndertowWebServer implements WebServer {
* @param autoStart if the server should be started
*/
public
UndertowWebServer
(
Undertow
.
Builder
builder
,
boolean
autoStart
)
{
this
(
builder
,
autoStart
,
null
);
}
/**
* Create a new {@link UndertowWebServer} instance.
* @param builder the builder
* @param autoStart if the server should be started
* @param closeable called when the server is stopped
* @since 2.0.4
*/
public
UndertowWebServer
(
Undertow
.
Builder
builder
,
boolean
autoStart
,
Closeable
closeable
)
{
this
.
builder
=
builder
;
this
.
autoStart
=
autoStart
;
this
.
closeable
=
closeable
;
}
@Override
...
...
@@ -112,6 +128,7 @@ public class UndertowWebServer implements WebServer {
try
{
if
(
this
.
undertow
!=
null
)
{
this
.
undertow
.
stop
();
this
.
closeable
.
close
();
}
}
catch
(
Exception
ex
)
{
...
...
@@ -214,6 +231,9 @@ public class UndertowWebServer implements WebServer {
this
.
started
=
false
;
try
{
this
.
undertow
.
stop
();
if
(
this
.
closeable
!=
null
)
{
this
.
closeable
.
close
();
}
}
catch
(
Exception
ex
)
{
throw
new
WebServerException
(
"Unable to stop undertow"
,
ex
);
...
...
spring-boot-project/spring-boot/src/test/java/org/springframework/boot/web/embedded/undertow/UndertowReactiveWebServerFactoryTests.java
View file @
3ea7c2e0
...
...
@@ -16,15 +16,25 @@
package
org
.
springframework
.
boot
.
web
.
embedded
.
undertow
;
import
java.io.File
;
import
java.io.IOException
;
import
java.net.URISyntaxException
;
import
java.util.Arrays
;
import
io.undertow.Undertow
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.junit.rules.TemporaryFolder
;
import
org.mockito.InOrder
;
import
reactor.core.publisher.Mono
;
import
org.springframework.boot.web.reactive.server.AbstractReactiveWebServerFactoryTests
;
import
org.springframework.http.MediaType
;
import
org.springframework.http.server.reactive.HttpHandler
;
import
org.springframework.web.reactive.function.BodyInserters
;
import
org.springframework.web.reactive.function.client.WebClient
;
import
static
org
.
assertj
.
core
.
api
.
Assertions
.
assertThat
;
import
static
org
.
mockito
.
ArgumentMatchers
.
any
;
import
static
org
.
mockito
.
Mockito
.
inOrder
;
import
static
org
.
mockito
.
Mockito
.
mock
;
...
...
@@ -38,6 +48,9 @@ import static org.mockito.Mockito.mock;
public
class
UndertowReactiveWebServerFactoryTests
extends
AbstractReactiveWebServerFactoryTests
{
@Rule
public
TemporaryFolder
temporaryFolder
=
new
TemporaryFolder
();
@Override
protected
UndertowReactiveWebServerFactory
getFactory
()
{
return
new
UndertowReactiveWebServerFactory
(
0
);
...
...
@@ -83,4 +96,44 @@ public class UndertowReactiveWebServerFactoryTests
assertForwardHeaderIsUsed
(
factory
);
}
@Test
public
void
accessLogCanBeEnabled
()
throws
IOException
,
URISyntaxException
,
InterruptedException
{
testAccessLog
(
null
,
null
,
"access_log.log"
);
}
@Test
public
void
accessLogCanBeCustomized
()
throws
IOException
,
URISyntaxException
,
InterruptedException
{
testAccessLog
(
"my_access."
,
"logz"
,
"my_access.logz"
);
}
private
void
testAccessLog
(
String
prefix
,
String
suffix
,
String
expectedFile
)
throws
IOException
,
URISyntaxException
,
InterruptedException
{
UndertowReactiveWebServerFactory
factory
=
getFactory
();
factory
.
setAccessLogEnabled
(
true
);
factory
.
setAccessLogPrefix
(
prefix
);
factory
.
setAccessLogSuffix
(
suffix
);
File
accessLogDirectory
=
this
.
temporaryFolder
.
getRoot
();
factory
.
setAccessLogDirectory
(
accessLogDirectory
);
assertThat
(
accessLogDirectory
.
listFiles
()).
isEmpty
();
this
.
webServer
=
factory
.
getWebServer
(
new
EchoHandler
());
this
.
webServer
.
start
();
WebClient
client
=
getWebClient
().
build
();
Mono
<
String
>
result
=
client
.
post
().
uri
(
"/test"
).
contentType
(
MediaType
.
TEXT_PLAIN
)
.
body
(
BodyInserters
.
fromObject
(
"Hello World"
)).
exchange
()
.
flatMap
((
response
)
->
response
.
bodyToMono
(
String
.
class
));
assertThat
(
result
.
block
()).
isEqualTo
(
"Hello World"
);
File
accessLog
=
new
File
(
accessLogDirectory
,
expectedFile
);
awaitFile
(
accessLog
);
assertThat
(
accessLogDirectory
.
listFiles
()).
contains
(
accessLog
);
}
private
void
awaitFile
(
File
file
)
throws
InterruptedException
{
long
end
=
System
.
currentTimeMillis
()
+
10000
;
while
(!
file
.
exists
()
&&
System
.
currentTimeMillis
()
<
end
)
{
Thread
.
sleep
(
100
);
}
}
}
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