Skip to content

Commit

Permalink
WIP convert CommunityRestConf to JaxRsEndpoint
Browse files Browse the repository at this point in the history
This change also required us to convert LightyServerBuilder to use JettyWebServer since it
is used in CommunityRestConf to initialize JaxRsEndpoint.

Signed-off-by: tobias.pobocik <[email protected]>
  • Loading branch information
Tobianas committed Oct 22, 2024
1 parent ede85bc commit aa22659
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@
package io.lighty.aaa;

import io.lighty.server.LightyServerBuilder;
import java.lang.reflect.Field;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.security.AccessController;
import java.security.PrivilegedAction;
import javax.servlet.Servlet;
import org.eclipse.jetty.server.Server;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.opendaylight.aaa.web.jetty.JettyWebServer;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
Expand All @@ -34,16 +38,36 @@ public void init() {
public void initLocalHttpServerTest() throws Exception {
InetSocketAddress socketAddress = new InetSocketAddress(InetAddress.getLocalHost(), 8888);
LightyServerBuilder serverBuilder = new LightyServerBuilder(socketAddress);
Server server = serverBuilder.build();
JettyWebServer server = serverBuilder.build();
Server jettyServer = null;
try {
// Use AccessController.doPrivileged to allow access to the private field
Field serverField = AccessController.doPrivileged((PrivilegedAction<Field>) () -> {
try {
Field field = JettyWebServer.class.getDeclaredField("server");
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("Field not found", e);
}
});

jettyServer = (Server) serverField.get(server);

// Only set the handler if no handler is already set by JaxRsEndpoint

} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set handler on JettyWebServer", e);
}
LocalHttpServer localHttpServer = new LocalHttpServer(serverBuilder);
localHttpServer.registerServlet(TEST_SERVLET, servlet, null);
localHttpServer.unregister(TEST_SERVLET);

server.start();
Assert.assertTrue(server.isStarted());
Assert.assertTrue(server.isRunning());
Assert.assertTrue(jettyServer.isStarted());
Assert.assertTrue(jettyServer.isRunning());
server.stop();
Assert.assertFalse(server.isStarted());
Assert.assertFalse(server.isRunning());
Assert.assertFalse(jettyServer.isStarted());
Assert.assertFalse(jettyServer.isRunning());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@
package io.lighty.server;

import io.lighty.server.config.SecurityConfig;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.jetty.alpn.server.ALPNServerConnectionFactory;
import org.eclipse.jetty.http.HttpScheme;
import org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory;
Expand All @@ -17,6 +20,7 @@
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.opendaylight.aaa.web.jetty.JettyWebServer;

public class Http2LightyServerBuilder extends LightyServerBuilder {

Expand All @@ -28,9 +32,10 @@ public Http2LightyServerBuilder(final InetSocketAddress inetSocketAddress, final
}

@Override
public Server build() {
super.server = new Server();
public JettyWebServer build() {
super.server = new JettyWebServer(this.inetSocketAddress.getPort());
final var server = super.build();

// HTTPS Configuration
final var httpsConfig = new HttpConfiguration();
httpsConfig.setSecureScheme(HttpScheme.HTTPS.asString());
Expand All @@ -48,9 +53,27 @@ public Server build() {
final var ssl = securityConfig.getSslConnectionFactory(alpn.getProtocol());

// HTTP/2 Connector
final var sslConnector = new ServerConnector(server, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig));
sslConnector.setPort(this.inetSocketAddress.getPort());
server.addConnector(sslConnector);
try {
// Use AccessController.doPrivileged to allow access to the private field
Field serverField = AccessController.doPrivileged((PrivilegedAction<Field>) () -> {
try {
Field field = JettyWebServer.class.getDeclaredField("server");
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("Field not found", e);
}
});

Server jettyServer = (Server) serverField.get(server);
final var sslConnector = new ServerConnector(
jettyServer, ssl, alpn, h2, new HttpConnectionFactory(httpsConfig));
sslConnector.setPort(this.inetSocketAddress.getPort());
jettyServer.addConnector(sslConnector);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set handler on JettyWebServer", e);
}

return server;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,56 @@
package io.lighty.server;

import io.lighty.server.config.SecurityConfig;
import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.security.AccessController;
import java.security.PrivilegedAction;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.opendaylight.aaa.web.jetty.JettyWebServer;

public class HttpsLightyServerBuilder extends LightyServerBuilder {
private final SecurityConfig securityConfig;

public HttpsLightyServerBuilder(final InetSocketAddress inetSocketAddress, final SecurityConfig securityConfig) {
super(inetSocketAddress);
this.server = new Server();
this.securityConfig = securityConfig;
}

@Override
public Server build() {
final Server server = super.build();
public JettyWebServer build() {
super.server = new JettyWebServer(this.inetSocketAddress.getPort());
final JettyWebServer server = super.build();

// HTTPS Configuration
final SslConnectionFactory ssl = securityConfig.getSslConnectionFactory(HttpVersion.HTTP_1_1.asString());
final ServerConnector sslConnector = new ServerConnector(server,
ssl, httpConfiguration(this.inetSocketAddress));
sslConnector.setPort(this.inetSocketAddress.getPort());
final ServerConnector sslConnector;

try {
// Use AccessController.doPrivileged to allow access to the private field
Field serverField = AccessController.doPrivileged((PrivilegedAction<Field>) () -> {
try {
Field field = JettyWebServer.class.getDeclaredField("server");
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("Field not found", e);
}
});

Server jettyServer = (Server) serverField.get(server);
sslConnector = new ServerConnector(jettyServer, ssl, httpConfiguration(this.inetSocketAddress));
sslConnector.setPort(this.inetSocketAddress.getPort());
jettyServer.addConnector(sslConnector);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set handler on JettyWebServer", e);
}

server.addConnector(sslConnector);
return server;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
*/
package io.lighty.server;

import java.lang.reflect.Field;
import java.net.InetSocketAddress;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.EventListener;
Expand All @@ -18,8 +21,10 @@
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.FilterHolder;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.opendaylight.aaa.web.jetty.JettyWebServer;

/**
* Allows user to build jetty server.
Expand All @@ -31,13 +36,8 @@ public class LightyServerBuilder {

protected final InetSocketAddress inetSocketAddress;
protected final List<Handler> contexts;
protected Server server;
protected JettyWebServer server;

/**
* Init new jetty server on specific port and address wrapped into {@link InetSocketAddress}.
*
* @param inetSocketAddress - port and address of server
*/
public LightyServerBuilder(final InetSocketAddress inetSocketAddress) {
this.inetSocketAddress = inetSocketAddress;
this.filters = new HashMap<>();
Expand All @@ -46,80 +46,106 @@ public LightyServerBuilder(final InetSocketAddress inetSocketAddress) {
this.contexts = new ArrayList<>();
}

/**
* Init jetty server with existing ones.
*
* @param server - jetty server
*/
public LightyServerBuilder(final Server server) {
public LightyServerBuilder(final JettyWebServer server) {
this(new InetSocketAddress(0));
this.server = server;
}

/**
* Add filter for handlers.
*
* @param filterHolder - filter holder
* @param path - path
* @return instance of {@link LightyServerBuilder}
*/
public LightyServerBuilder addCommonFilter(final FilterHolder filterHolder, final String path) {
this.filters.put(filterHolder, path);
return this;
}

/**
* Add listener for handlers.
*
* @param eventListener - event listener
* @return instance of {@link LightyServerBuilder}
*/
public LightyServerBuilder addCommonEventListener(final EventListener eventListener) {
this.listeners.add(eventListener);
return this;
}

/**
* Add init parameters for handlers.
*
* @param key - key of init parameters
* @param value - value of init parameters
* @return instance of {@link LightyServerBuilder}
*/
public LightyServerBuilder addCommonInitParameter(final String key, final String value) {
this.parameters.put(key, value);
return this;
}

/**
* Add specific handler for server to handle incoming HTTP requests.
*
* @param handler - specific handler
* @return instance of {@link LightyServerBuilder}
*/
public LightyServerBuilder addContextHandler(final Handler handler) {
this.contexts.add(handler);
return this;
}

/**
* Build jetty server with specific settings (filters, init params, event listeners, handlers).
*
* @return instance of jetty server
*/
public Server build() {
public JettyWebServer build() {
if (this.server == null) {
this.server = new Server(this.inetSocketAddress);
this.server = new JettyWebServer(this.inetSocketAddress.getPort());
}

final ContextHandlerCollection contextHandlerCollection = new ContextHandlerCollection();
this.contexts.forEach((contextHandler) -> {
this.contexts.forEach(contextHandler -> {
addFilters(contextHandler);
contextHandlerCollection.addHandler(contextHandler);
});
this.server.setHandler(contextHandlerCollection);

try {
Field serverField = AccessController.doPrivileged((PrivilegedAction<Field>) () -> {
try {
Field field = JettyWebServer.class.getDeclaredField("server");
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("Field not found", e);
}
});

Server jettyServer = (Server) serverField.get(this.server);
Handler currentHandler = jettyServer.getHandler();

if (currentHandler == null) {
jettyServer.setHandler(contextHandlerCollection);
} else if (currentHandler instanceof HandlerCollection) {
HandlerCollection handlerCollection = (HandlerCollection) currentHandler;
handlerCollection.addHandler(contextHandlerCollection);
} else {
HandlerCollection handlerCollection = new HandlerCollection();
handlerCollection.addHandler(currentHandler);
handlerCollection.addHandler(contextHandlerCollection);
jettyServer.setHandler(handlerCollection);
}

} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to set handler on JettyWebServer", e);
}

return this.server;
}

@SuppressWarnings("IllegalCatch")
public void addHandlerAtRuntime(ContextHandlerCollection newHandler) {
try {
Field serverField = AccessController.doPrivileged((PrivilegedAction<Field>) () -> {
try {
Field field = JettyWebServer.class.getDeclaredField("server");
field.setAccessible(true);
return field;
} catch (NoSuchFieldException e) {
throw new RuntimeException("Field not found", e);
}
});

Server jettyServer = (Server) serverField.get(this.server);
Handler currentHandler = jettyServer.getHandler();

if (currentHandler instanceof HandlerCollection) {
HandlerCollection handlerCollection = (HandlerCollection) currentHandler;
handlerCollection.addHandler(newHandler);
newHandler.start();
} else {
throw new IllegalStateException("Current handler is not a HandlerCollection");
}

} catch (RuntimeException e) {
throw new RuntimeException("Failed to add handler at runtime", e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

void addFilters(final Handler contextHandler) {
if (contextHandler instanceof ContextHandlerCollection) {
final ContextHandlerCollection sch = (ContextHandlerCollection) contextHandler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
import io.lighty.server.util.LightyServerConfigUtils;
import java.net.InetSocketAddress;
import java.util.EventListener;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.servlet.FilterHolder;
import org.opendaylight.aaa.web.jetty.JettyWebServer;
import org.testng.annotations.Test;

public class LightyServerBuilderTest {
Expand Down Expand Up @@ -68,7 +68,7 @@ public void testHttpsCustomServerBuilder() throws Exception {
assertNotNull(server);
}

private static Server initLightyServer(final LightyServerBuilder serverBuilder) {
private static JettyWebServer initLightyServer(final LightyServerBuilder serverBuilder) {
final var filterHolder = new FilterHolder();
final var contexts = new ContextHandlerCollection();
serverBuilder.addCommonEventListener(new EventListener(){});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public Set<Object> getSingletons() {
addStaticResources(mainHandler, "/explorer", "static-content");

LOG.info("adding context handler ...");
jettyServerBuilder.addContextHandler(contexts);
jettyServerBuilder.addHandlerAtRuntime(contexts);
return true;
}

Expand Down
Loading

0 comments on commit aa22659

Please sign in to comment.