Skip to content

Commit d803f56

Browse files
committed
Modernize OpenApi
Use the JettyWebServer to initialize OpenApi the same way as its done in ODL. Also add possibility to add WebContextSecurer to secure the /openapi endpoint. JIRA: LIGHTY-329 Signed-off-by: tobias.pobocik <[email protected]>
1 parent cec0ee9 commit d803f56

File tree

6 files changed

+64
-54
lines changed

6 files changed

+64
-54
lines changed

lighty-applications/lighty-rnc-app-aggregator/lighty-rnc-module/src/main/java/io/lighty/applications/rnc/module/RncLightyModule.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ private AAALighty initAAA(final AAAConfiguration config, final LightyServices se
144144

145145
private OpenApiLighty initOpenApiLighty(final RestConfConfiguration config,
146146
final LightyJettyServerProvider serverBuilder, final LightyServices services) {
147-
return new OpenApiLighty(config, serverBuilder, services);
147+
return new OpenApiLighty(config, serverBuilder, services, null);
148148
}
149149

150150
private void startAndWaitLightyModule(final LightyModule lightyModule) throws RncLightyAppStartException {

lighty-examples/lighty-community-restconf-actions-app/src/main/java/io/lighty/examples/controllers/actions/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ private void startLighty(final ControllerConfiguration controllerConfiguration,
167167

168168
//3. start openApi and RestConf server
169169
this.openApi =
170-
new OpenApiLighty(restconfConfiguration, jettyServerBuilder, this.lightyController.getServices());
170+
new OpenApiLighty(restconfConfiguration, jettyServerBuilder, this.lightyController.getServices(), null);
171171
final boolean openApiStartOk = this.openApi.start()
172172
.get(modulesConfig.getModuleTimeoutSeconds(), TimeUnit.SECONDS);
173173
if (!openApiStartOk) {

lighty-examples/lighty-community-restconf-netconf-app/src/main/java/io/lighty/examples/controllers/restconfapp/Main.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ private void startLighty(final ControllerConfiguration controllerConfiguration,
160160
lightyController.getServices().withJaxRsEndpoint(restconf.getJaxRsEndpoint());
161161

162162
this.openApi =
163-
new OpenApiLighty(restconfConfiguration, jettyServerBuilder, this.lightyController.getServices());
163+
new OpenApiLighty(restconfConfiguration, jettyServerBuilder, this.lightyController.getServices(), null);
164164
final boolean openApiStartOk = this.openApi.start()
165165
.get(modulesConfig.getModuleTimeoutSeconds(), TimeUnit.SECONDS);
166166
if (!openApiStartOk) {

lighty-modules/lighty-openapi/src/main/java/io/lighty/openapi/OpenApiLighty.java

Lines changed: 50 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,23 @@
1111
import com.google.common.annotations.VisibleForTesting;
1212
import io.lighty.core.controller.api.AbstractLightyModule;
1313
import io.lighty.core.controller.api.LightyServices;
14+
import io.lighty.modules.northbound.restconf.community.impl.CommunityRestConf;
1415
import io.lighty.modules.northbound.restconf.community.impl.config.RestConfConfiguration;
1516
import io.lighty.server.LightyJettyServerProvider;
1617
import java.util.Set;
18+
import javax.servlet.ServletException;
1719
import javax.ws.rs.core.Application;
18-
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
20+
import org.eclipse.jdt.annotation.Nullable;
1921
import org.eclipse.jetty.servlet.DefaultServlet;
20-
import org.eclipse.jetty.servlet.ServletContextHandler;
21-
import org.eclipse.jetty.servlet.ServletHolder;
22-
import org.glassfish.jersey.server.ResourceConfig;
23-
import org.glassfish.jersey.servlet.ServletContainer;
22+
import org.opendaylight.aaa.web.ServletDetails;
23+
import org.opendaylight.aaa.web.WebContext;
24+
import org.opendaylight.aaa.web.WebContextSecurer;
25+
import org.opendaylight.aaa.web.servlet.jersey2.JerseyServletSupport;
26+
import org.opendaylight.restconf.openapi.api.OpenApiService;
2427
import org.opendaylight.restconf.openapi.impl.OpenApiServiceImpl;
2528
import org.opendaylight.restconf.openapi.jaxrs.JaxRsOpenApi;
2629
import org.opendaylight.restconf.openapi.jaxrs.OpenApiBodyWriter;
30+
import org.opendaylight.yangtools.concepts.Registration;
2731
import org.slf4j.Logger;
2832
import org.slf4j.LoggerFactory;
2933

@@ -40,71 +44,75 @@ public class OpenApiLighty extends AbstractLightyModule {
4044
private final RestConfConfiguration restConfConfiguration;
4145
private final LightyJettyServerProvider jettyServerBuilder;
4246
private final LightyServices lightyServices;
47+
private Registration registration;
48+
private OpenApiService openApiService;
49+
private WebContextSecurer webContextSecurer;
4350

44-
private JaxRsOpenApi jaxRsOpenApi;
45-
46-
public OpenApiLighty(RestConfConfiguration restConfConfiguration,
47-
LightyJettyServerProvider jettyServerBuilder, LightyServices lightyServices) {
51+
public OpenApiLighty(RestConfConfiguration restConfConfiguration, LightyJettyServerProvider jettyServerBuilder,
52+
LightyServices lightyServices, @Nullable WebContextSecurer webContextSecurer) {
4853
this.restConfConfiguration = restConfConfiguration;
4954
this.jettyServerBuilder = jettyServerBuilder;
5055
this.lightyServices = lightyServices;
56+
this.registration = null;
57+
this.webContextSecurer = (webContextSecurer == null)
58+
? new CommunityRestConf.LightyWebContextSecurer() : webContextSecurer;
5159
}
5260

5361
@Override
5462
protected boolean initProcedure() {
5563
LOG.info("initializing openapi");
56-
57-
//replace all slash characters from the beginning of the string
58-
String basePathString = restConfConfiguration.getRestconfServletContextPath().replaceAll("^/+", "");
59-
LOG.info("basePath: {}", basePathString);
60-
61-
final var openApiService = new OpenApiServiceImpl(lightyServices.getDOMSchemaService(),
64+
this.openApiService = new OpenApiServiceImpl(lightyServices.getDOMSchemaService(),
6265
lightyServices.getDOMMountPointService(), lightyServices.getJaxRsEndpoint());
6366

64-
this.jaxRsOpenApi = new JaxRsOpenApi(openApiService);
65-
66-
final ServletContainer restServletContainer = new ServletContainer(ResourceConfig
67-
.forApplication((new Application() {
67+
final var webContextBuilder = WebContext.builder()
68+
.name("OpenAPI")
69+
.contextPath(OPENAPI_PATH)
70+
.supportsSessions(true)
71+
.addServlet(ServletDetails.builder()
72+
.servlet(new JerseyServletSupport().createHttpServletBuilder(new Application() {
6873
@Override
6974
public Set<Object> getSingletons() {
7075
return Set.of(new JaxRsOpenApi(openApiService),
7176
new OpenApiBodyWriter(new JsonFactoryBuilder().build()));
7277
}
73-
})));
74-
75-
ServletHolder restServletHolder = new ServletHolder(restServletContainer);
76-
77-
ContextHandlerCollection contexts = new ContextHandlerCollection();
78-
ServletContextHandler mainHandler = new ServletContextHandler(contexts, OPENAPI_PATH, true, false);
79-
mainHandler.addServlet(restServletHolder, "/api/v3/*");
80-
81-
addStaticResources(mainHandler, "/explorer", "static-content");
82-
83-
LOG.info("adding context handler ...");
84-
jettyServerBuilder.addContextHandler(contexts);
78+
}).build())
79+
.addUrlPattern("/api/v3/*")
80+
.build())
81+
.addServlet(addStaticResources("/explorer", "OpenApiStaticServlet"));
82+
83+
webContextSecurer.requireAuthentication(webContextBuilder, "/*");
84+
85+
try {
86+
registration = jettyServerBuilder.build().registerWebContext(webContextBuilder.build());
87+
} catch (ServletException e) {
88+
LOG.error("Failed to register OpenApi web context: {}!", jettyServerBuilder.getClass(), e);
89+
}
8590
return true;
8691
}
8792

8893
@Override
8994
protected boolean stopProcedure() {
9095
LOG.info("shutting down openapi ...");
96+
this.registration.close();
9197
return true;
9298
}
9399

94-
private void addStaticResources(ServletContextHandler mainHandler, String path, String servletName) {
95-
LOG.info("initializing openapi UI at: http(s)://{hostname:port}{}{}/index.html", OPENAPI_PATH, path);
96-
String externalResource = OpenApiLighty.class.getResource(path).toExternalForm();
100+
private ServletDetails addStaticResources(String path, String servletName) {
101+
final String externalResource = OpenApiLighty.class.getResource("/explorer").toExternalForm();
97102
LOG.info("externalResource: {}", externalResource);
98-
DefaultServlet defaultServlet = new DefaultServlet();
99-
ServletHolder holderPwd = new ServletHolder(servletName, defaultServlet);
100-
holderPwd.setInitParameter("resourceBase", externalResource);
101-
holderPwd.setInitParameter("dirAllowed", TRUE);
102-
holderPwd.setInitParameter("pathInfoOnly", TRUE);
103-
mainHandler.addServlet(holderPwd, path + "/*");
103+
104+
return ServletDetails.builder()
105+
.servlet(new DefaultServlet())
106+
.name(servletName)
107+
.addUrlPattern(path + "/*")
108+
.putInitParam("resourceBase", externalResource)
109+
.putInitParam("dirAllowed", TRUE)
110+
.putInitParam("pathInfoOnly", TRUE)
111+
.build();
104112
}
105113

106114
@VisibleForTesting
107-
JaxRsOpenApi getJaxRsOpenApi() {
108-
return jaxRsOpenApi;
115+
OpenApiService getjaxRsOpenApi() {
116+
return this.openApiService;
109117
}
110118
}

lighty-modules/lighty-openapi/src/test/java/io/lighty/openapi/OpenApiLightyTest.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,23 @@ public abstract class OpenApiLightyTest extends OpenApiLightyTestBase {
2424

2525
public void simpleOpenApiModuleTest() {
2626
Assert.assertNotNull(getLightyController());
27-
Assert.assertNotNull(getOpenApiModule());
27+
Assert.assertNotNull(getJaxRsOpenapi());
2828
}
2929

3030
public void testGetListOfMounts(UriInfo uriInfo) {
31-
assertSuccessResponse(getOpenApiModule().getJaxRsOpenApi().getListOfMounts(uriInfo));
31+
assertSuccessResponse(getJaxRsOpenapi().getListOfMounts(uriInfo));
3232
}
3333

3434
public void testGetAllModulesDoc(UriInfo uriInfo) throws IOException {
35-
assertSuccessResponse(getOpenApiModule().getJaxRsOpenApi().getAllModulesDoc(uriInfo, 0, 0, 0, 0));
35+
assertSuccessResponse(getJaxRsOpenapi().getAllModulesDoc(uriInfo, 0, 0, 0, 0));
3636
}
3737

3838
public void testGetDocByModule(UriInfo uriInfo, String modelName, String revisionDate) throws IOException {
39-
assertSuccessResponse(
40-
getOpenApiModule().getJaxRsOpenApi().getDocByModule(modelName, revisionDate, uriInfo, 0, 0));
39+
assertSuccessResponse(getJaxRsOpenapi().getDocByModule(modelName, revisionDate, uriInfo, 0, 0));
4140
}
4241

4342
public void testGetApiExplorer(UriInfo uriInfo) {
44-
final Response response = getOpenApiModule().getJaxRsOpenApi().getApiExplorer(uriInfo);
43+
final Response response = getJaxRsOpenapi().getApiExplorer(uriInfo);
4544

4645
final int redirectCode = 303;
4746
Assert.assertEquals(response.getStatus(), redirectCode);

lighty-modules/lighty-openapi/src/test/java/io/lighty/openapi/OpenApiLightyTestBase.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.lang.reflect.Method;
2121
import java.net.InetSocketAddress;
2222
import java.util.concurrent.TimeUnit;
23+
import org.opendaylight.restconf.openapi.jaxrs.JaxRsOpenApi;
2324
import org.slf4j.Logger;
2425
import org.slf4j.LoggerFactory;
2526
import org.testng.ITestResult;
@@ -39,6 +40,7 @@ public abstract class OpenApiLightyTestBase {
3940
private LightyController lightyController;
4041
private OpenApiLighty openApiModule;
4142
private CommunityRestConf communityRestConf;
43+
private JaxRsOpenApi jaxRsOpenApi;
4244

4345
@BeforeClass(timeOut = 60_000)
4446
public void startControllerAndRestConf() throws Exception {
@@ -63,11 +65,12 @@ public void startControllerAndRestConf() throws Exception {
6365
restConfConfiguration.getInetAddress(), restConfConfiguration.getHttpPort()));
6466

6567
openApiModule = new OpenApiLighty(restConfConfiguration, jettyServerBuilder,
66-
lightyController.getServices());
68+
lightyController.getServices(), null);
6769
LOG.info("Starting Lighty OpenApi");
6870
openApiModule.start().get();
6971
communityRestConf.startServer();
7072
LOG.info("Lighty OpenApi started");
73+
jaxRsOpenApi = new JaxRsOpenApi(openApiModule.getjaxRsOpenApi());
7174
}
7275

7376
@BeforeMethod
@@ -115,7 +118,7 @@ LightyController getLightyController() {
115118
return lightyController;
116119
}
117120

118-
OpenApiLighty getOpenApiModule() {
119-
return openApiModule;
121+
JaxRsOpenApi getJaxRsOpenapi() {
122+
return jaxRsOpenApi;
120123
}
121124
}

0 commit comments

Comments
 (0)