1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.rest.tools;
35
36 import info.magnolia.cms.beans.config.ServerConfiguration;
37 import info.magnolia.cms.util.CustomServletConfig;
38 import info.magnolia.context.MgnlContext;
39 import info.magnolia.event.EventBus;
40 import info.magnolia.event.SystemEventBus;
41 import info.magnolia.objectfactory.ComponentProvider;
42 import info.magnolia.rest.EndpointDefinition;
43 import info.magnolia.rest.RestDispatcherServlet;
44 import info.magnolia.rest.RestIntegrationModule;
45 import info.magnolia.rest.registry.ConfiguredEndpointDefinition;
46 import info.magnolia.rest.registry.EndpointDefinitionRegistry;
47 import info.magnolia.rest.registry.EndpointDefinitionRegistryEvent;
48
49 import java.io.IOException;
50 import java.util.ArrayList;
51 import java.util.HashMap;
52 import java.util.List;
53
54 import javax.inject.Inject;
55 import javax.inject.Named;
56 import javax.servlet.ServletConfig;
57 import javax.servlet.ServletException;
58 import javax.servlet.http.HttpServletRequest;
59 import javax.servlet.http.HttpServletResponse;
60
61 import io.swagger.v3.jaxrs2.integration.OpenApiServlet;
62 import io.swagger.v3.jaxrs2.integration.resources.OpenApiResource;
63 import io.swagger.v3.oas.integration.SwaggerConfiguration;
64 import io.swagger.v3.oas.models.OpenAPI;
65 import io.swagger.v3.oas.models.servers.Server;
66
67
68
69
70
71
72
73 public class SwaggerRestDispatcherServlet extends RestDispatcherServlet {
74
75 private static final String ENDPOINT_NAME = "openapi";
76
77
78
79 static final String SWAGGER = "swagger";
80
81 private final RestToolsModule restToolsModule;
82 private OpenApiServlet swaggerServlet;
83
84
85
86
87
88
89 private boolean swaggerCacheIsStale = false;
90
91 @Inject
92 public SwaggerRestDispatcherServlet(final RestIntegrationModule restIntegrationModule, final EndpointDefinitionRegistry endpointDefinitionRegistry, @Named(SystemEventBus.NAME) EventBus systemEventBus, final RestToolsModule restToolsModule, ComponentProvider componentProvider, ServerConfiguration serverConfiguration) {
93 super(restIntegrationModule, endpointDefinitionRegistry, systemEventBus, componentProvider, serverConfiguration);
94 this.restToolsModule = restToolsModule;
95 }
96
97 @Override
98 public void init(ServletConfig servletConfig) throws ServletException {
99 super.init(servletConfig);
100
101 initApiListing();
102
103 swaggerServlet = new OpenApiServlet();
104 swaggerServlet.init(new CustomServletConfig("DefaultJaxrsConfig", super.getServletContext(), new HashMap<>()));
105 }
106
107 private void initApiListing() {
108
109 ConfiguredEndpointDefinition endpointDefinition = new ConfiguredEndpointDefinition();
110 endpointDefinition.setImplementationClass(OpenApiResource.class);
111 endpointDefinition.setName(ENDPOINT_NAME);
112 super.registerEndpoint(endpointDefinition);
113 }
114
115 @Override
116 protected Object instantiateEndpoint(EndpointDefinition endpointDefinition) {
117 Object endpoint = super.instantiateEndpoint(endpointDefinition);
118 if (ENDPOINT_NAME.equalsIgnoreCase(endpointDefinition.getName()) && endpoint instanceof OpenApiResource) {
119 OpenAPI oas = new OpenAPI();
120 List<Server> servers = new ArrayList<>();
121
122 servers.add(new Server().url(restToolsModule.getApiBasepath()));
123 oas.servers(servers);
124 SwaggerConfiguration oasConfig = new SwaggerConfiguration()
125 .openAPI(oas)
126 .prettyPrint(false);
127 ((OpenApiResource) endpoint).setOpenApiConfiguration(oasConfig);
128 }
129
130 return endpoint;
131 }
132
133
134
135
136
137
138 private void refreshApiListing() {
139 unregisterEndpoint(ENDPOINT_NAME);
140 initApiListing();
141 swaggerCacheIsStale = true;
142 }
143
144 @Override
145 protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
146
147 if (swaggerCacheIsStale) {
148 MgnlContext.getWebContext().getServletContext().removeAttribute(SWAGGER);
149 swaggerCacheIsStale = false;
150 }
151
152 super.service(httpServletRequest, httpServletResponse);
153 }
154
155 @Override
156 public void destroy() {
157 unregisterEndpoint(ENDPOINT_NAME);
158 super.destroy();
159 if (swaggerServlet != null) {
160 swaggerServlet.destroy();
161 }
162 }
163
164 @Override
165 public void onEndpointRegistered(EndpointDefinitionRegistryEvent event) {
166 super.onEndpointRegistered(event);
167 refreshApiListing();
168 }
169
170 @Override
171 public void onEndpointReregistered(EndpointDefinitionRegistryEvent event) {
172 super.onEndpointReregistered(event);
173 refreshApiListing();
174 }
175
176 @Override
177 public void onEndpointUnregistered(EndpointDefinitionRegistryEvent event) {
178 super.onEndpointUnregistered(event);
179 refreshApiListing();
180 }
181 }