Skip to content

Commit 1cbe0bb

Browse files
Tobianasihrasko
authored andcommitted
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 248bee4 commit 1cbe0bb

File tree

6 files changed

+66
-54
lines changed

6 files changed

+66
-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: 52 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,77 @@ public class OpenApiLighty extends AbstractLightyModule {
4044
private final RestConfConfiguration restConfConfiguration;
4145
private final LightyJettyServerProvider jettyServerBuilder;
4246
private final LightyServices lightyServices;
47+
private final WebContextSecurer webContextSecurer;
48+
private Registration registration;
49+
private OpenApiService openApiService;
4350

44-
private JaxRsOpenApi jaxRsOpenApi;
45-
46-
public OpenApiLighty(RestConfConfiguration restConfConfiguration,
47-
LightyJettyServerProvider jettyServerBuilder, LightyServices lightyServices) {
51+
public OpenApiLighty(final RestConfConfiguration restConfConfiguration,
52+
final LightyJettyServerProvider jettyServerBuilder,
53+
final LightyServices lightyServices, final @Nullable WebContextSecurer webContextSecurer) {
4854
this.restConfConfiguration = restConfConfiguration;
4955
this.jettyServerBuilder = jettyServerBuilder;
5056
this.lightyServices = lightyServices;
57+
this.registration = null;
58+
this.webContextSecurer = (webContextSecurer == null)
59+
? new CommunityRestConf.LightyWebContextSecurer() : webContextSecurer;
5160
}
5261

5362
@Override
5463
protected boolean initProcedure() {
5564
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(),
65+
this.openApiService = new OpenApiServiceImpl(lightyServices.getDOMSchemaService(),
6266
lightyServices.getDOMMountPointService(), lightyServices.getJaxRsEndpoint());
6367

64-
this.jaxRsOpenApi = new JaxRsOpenApi(openApiService);
65-
66-
final ServletContainer restServletContainer = new ServletContainer(ResourceConfig
67-
.forApplication((new Application() {
68+
final var webContextBuilder = WebContext.builder()
69+
.name("OpenAPI")
70+
.contextPath(OPENAPI_PATH)
71+
.supportsSessions(true)
72+
.addServlet(ServletDetails.builder()
73+
.servlet(new JerseyServletSupport().createHttpServletBuilder(new Application() {
6874
@Override
6975
public Set<Object> getSingletons() {
7076
return Set.of(new JaxRsOpenApi(openApiService),
7177
new OpenApiBodyWriter(new JsonFactoryBuilder().build()));
7278
}
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);
79+
}).build())
80+
.addUrlPattern("/api/v3/*")
81+
.build())
82+
.addServlet(addStaticResources("/explorer", "OpenApiStaticServlet"));
83+
84+
webContextSecurer.requireAuthentication(webContextBuilder, "/*");
85+
86+
try {
87+
registration = jettyServerBuilder.getServer().registerWebContext(webContextBuilder.build());
88+
} catch (ServletException e) {
89+
LOG.error("Failed to register OpenApi web context: {}!", jettyServerBuilder.getClass(), e);
90+
return false;
91+
}
8592
return true;
8693
}
8794

8895
@Override
8996
protected boolean stopProcedure() {
9097
LOG.info("shutting down openapi ...");
98+
this.registration.close();
9199
return true;
92100
}
93101

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();
102+
private ServletDetails addStaticResources(String path, String servletName) {
103+
final String externalResource = OpenApiLighty.class.getResource("/explorer").toExternalForm();
97104
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 + "/*");
105+
106+
return ServletDetails.builder()
107+
.servlet(new DefaultServlet())
108+
.name(servletName)
109+
.addUrlPattern(path + "/*")
110+
.putInitParam("resourceBase", externalResource)
111+
.putInitParam("dirAllowed", TRUE)
112+
.putInitParam("pathInfoOnly", TRUE)
113+
.build();
104114
}
105115

106116
@VisibleForTesting
107-
JaxRsOpenApi getJaxRsOpenApi() {
108-
return jaxRsOpenApi;
117+
OpenApiService getjaxRsOpenApi() {
118+
return this.openApiService;
109119
}
110120
}

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)