diff --git a/README.md b/README.md index c2ac6f32..23f42fd7 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ dropwizard-swagger ================== -a Dropwizard bundle that serves Swagger UI static content and loads Swagger endpoints. Swagger UI static content is taken from https://github.com/wordnik/swagger-ui +a Dropwizard bundle that serves Swagger UI static content and loads Swagger endpoints. Swagger UI static content is taken from https://github.com/swagger-api/swagger-ui -Current version has been tested with Dropwizard 0.8.0 and Swagger 1.5.1-M2 which supports Swagger 2 spec! +Current version has been tested with Dropwizard 0.8.0 and Swagger 1.5.4 which supports Swagger 2 spec! Note: if you come from previous versions there have been some changes in the way the bundle is configured, see details below. @@ -21,6 +21,7 @@ dropwizard-swagger|Dropwizard|Swagger API|Swagger UI 0.5.x | 0.7.x | 1.3.12 | v2.1.4-M1 0.6.x | 0.8.0 | 1.3.12 | v2.1.4-M1 0.7.x | 0.8.0 | 1.5.1-M2| v2.1.4-M1 + 0.8.x | 0.8.4 | 1.5.4 | v2.1.4-M1 How to use it ------------- diff --git a/pom.xml b/pom.xml index a56a7bcd..59d0af09 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ io.federecio dropwizard-swagger - 0.7.1-SNAPSHOT + 0.8.2-wikia Dropwizard Swagger support A simple way to document your REST APIs in DropWizard using Swagger @@ -47,12 +47,12 @@ - 0.8.0 + 0.8.1 UTF-8 UTF-8 UTF-8 1.7 - 1.5.1-M2 + 1.5.3 @@ -77,7 +77,7 @@ ${dropwizard.version} - com.wordnik + io.swagger swagger-jersey2-jaxrs ${swagger.version} @@ -127,13 +127,17 @@ - org.glassfish.jersey.media - jersey-media-multipart + org.glassfish.jersey.core + jersey-server org.glassfish.jersey.containers jersey-container-servlet-core + + org.glassfish.hk2.external + javax.inject + @@ -178,6 +182,12 @@ dropwizard-junit 0.6 test + + + io.dropwizard + dropwizard-core + + org.seleniumhq.selenium.client-drivers diff --git a/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java b/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java index 80e32dc2..76cad0a5 100644 --- a/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java +++ b/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundle.java @@ -16,15 +16,21 @@ package io.federecio.dropwizard.swagger; import com.fasterxml.jackson.annotation.JsonInclude; -import com.google.common.collect.ImmutableMap; -import com.wordnik.swagger.jaxrs.config.BeanConfig; -import com.wordnik.swagger.jaxrs.listing.ApiListingResource; import io.dropwizard.Configuration; import io.dropwizard.ConfiguredBundle; import io.dropwizard.assets.AssetsBundle; import io.dropwizard.setup.Bootstrap; import io.dropwizard.setup.Environment; import io.dropwizard.views.ViewBundle; +import io.swagger.jaxrs.config.BeanConfig; +import io.swagger.jaxrs.listing.ApiListingResource; +import io.swagger.models.Swagger; +import org.eclipse.jetty.servlets.CrossOriginFilter; + +import java.util.EnumSet; + +import javax.servlet.DispatcherType; +import javax.servlet.FilterRegistration; /** * A {@link io.dropwizard.ConfiguredBundle} that provides hassle-free configuration of Swagger and Swagger UI @@ -38,12 +44,7 @@ public abstract class SwaggerBundle implements Configur @Override public void initialize(Bootstrap bootstrap) { - bootstrap.addBundle(new ViewBundle() { - @Override - public ImmutableMap> getViewConfiguration(final Configuration configuration) { - return ImmutableMap.of(); - } - }); + bootstrap.addBundle(new ViewBundle<>()); } @Override @@ -56,17 +57,40 @@ public void run(T configuration, Environment environment) throws Exception { ConfigurationHelper configurationHelper = new ConfigurationHelper(configuration, swaggerBundleConfiguration); new AssetsBundle(Constants.SWAGGER_RESOURCES_PATH, configurationHelper.getSwaggerUriPath(), null, Constants.SWAGGER_ASSETS_NAME).run(environment); - environment.jersey().register(new SwaggerResource(configurationHelper.getUrlPattern())); + environment.jersey().register( + new SwaggerResource( + configurationHelper.getUrlPattern(), + swaggerBundleConfiguration.getUiConfiguration())); environment.getObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); - setUpSwagger(swaggerBundleConfiguration, configurationHelper.getUrlPattern()); + BeanConfig beanConfig = setUpSwagger(swaggerBundleConfiguration, + configurationHelper.getUrlPattern()); + + configureCors(environment, "/swagger.json", "/swagger.yaml"); + + environment.getApplicationContext().setAttribute("swagger", beanConfig.getSwagger()); environment.jersey().register(new ApiListingResource()); } @SuppressWarnings("unused") protected abstract SwaggerBundleConfiguration getSwaggerBundleConfiguration(T configuration); - private void setUpSwagger(SwaggerBundleConfiguration swaggerBundleConfiguration, String urlPattern) { + @SuppressWarnings("unused") + protected void setUpSwagger(Swagger swagger) {} + + protected void configureCors(Environment environment, String... urlPatterns) { + FilterRegistration.Dynamic + filter = environment.servlets().addFilter("CORS", CrossOriginFilter.class); + filter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, urlPatterns); + filter.setInitParameter(CrossOriginFilter.ALLOWED_METHODS_PARAM, "GET,PUT,POST,DELETE,OPTIONS"); + filter.setInitParameter(CrossOriginFilter.ALLOWED_ORIGINS_PARAM, "*"); + filter.setInitParameter(CrossOriginFilter.ACCESS_CONTROL_ALLOW_ORIGIN_HEADER, "*"); + filter.setInitParameter("allowedHeaders", "Content-Type,Authorization,X-Requested-With,Content-Length,Accept,Origin"); + filter.setInitParameter("allowCredentials", "true"); + } + + private BeanConfig setUpSwagger(SwaggerBundleConfiguration swaggerBundleConfiguration, + String urlPattern) { BeanConfig config = new BeanConfig(); if (swaggerBundleConfiguration.getTitle() != null) { @@ -107,5 +131,8 @@ private void setUpSwagger(SwaggerBundleConfiguration swaggerBundleConfiguration, config.setScan(true); + setUpSwagger(config.getSwagger()); + + return config; } } diff --git a/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundleConfiguration.java b/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundleConfiguration.java index 5e92585c..aff05934 100644 --- a/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundleConfiguration.java +++ b/src/main/java/io/federecio/dropwizard/swagger/SwaggerBundleConfiguration.java @@ -19,7 +19,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; /** - * For the meaning of all these properties please refer to Swagger documentation or {@link com.wordnik.swagger.jaxrs.config.BeanConfig} + * For the meaning of all these properties please refer to Swagger documentation or {@link io.swagger.jaxrs.config.BeanConfig} * * @author Tristan Burch * @author Federico Recio @@ -30,7 +30,7 @@ public class SwaggerBundleConfiguration { /** * This is the only property that is required for Swagger to work correctly. *

- * It is a comma separated list of the all the packages that contain the {@link com.wordnik.swagger.annotations.Api} + * It is a comma separated list of the all the packages that contain the {@link io.swagger.annotations.Api} * annoted resources */ @JsonProperty @@ -69,6 +69,9 @@ public class SwaggerBundleConfiguration { @JsonProperty private String uriPrefix; + @JsonProperty("ui") + private SwaggerUIConfiguration uiConfiguration = new SwaggerUIConfiguration(); + public String getResourcePackage() { return resourcePackage; } @@ -141,6 +144,16 @@ public void setUriPrefix(String uriPrefix) { this.uriPrefix = uriPrefix; } + @JsonProperty("ui") + public SwaggerUIConfiguration getUiConfiguration() { + return uiConfiguration; + } + + @JsonProperty("ui") + public void setUiConfiguration(SwaggerUIConfiguration ui) { + this.uiConfiguration = ui; + } + @Override public String toString() { return "SwaggerBundleConfiguration{" + diff --git a/src/main/java/io/federecio/dropwizard/swagger/SwaggerResource.java b/src/main/java/io/federecio/dropwizard/swagger/SwaggerResource.java index 56f0016f..d9b16fe2 100644 --- a/src/main/java/io/federecio/dropwizard/swagger/SwaggerResource.java +++ b/src/main/java/io/federecio/dropwizard/swagger/SwaggerResource.java @@ -27,13 +27,15 @@ @Produces(MediaType.TEXT_HTML) public class SwaggerResource { private final String urlPattern; + private final SwaggerUIConfiguration config; - public SwaggerResource(String urlPattern) { + public SwaggerResource(String urlPattern, SwaggerUIConfiguration config) { this.urlPattern = urlPattern; + this.config = config; } @GET public SwaggerView get() { - return new SwaggerView(urlPattern); + return new SwaggerView(urlPattern, config); } } diff --git a/src/main/java/io/federecio/dropwizard/swagger/SwaggerUIConfiguration.java b/src/main/java/io/federecio/dropwizard/swagger/SwaggerUIConfiguration.java new file mode 100644 index 00000000..d257aef3 --- /dev/null +++ b/src/main/java/io/federecio/dropwizard/swagger/SwaggerUIConfiguration.java @@ -0,0 +1,38 @@ +package io.federecio.dropwizard.swagger; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class SwaggerUIConfiguration { + @JsonProperty + String authName = "api_key"; + + @JsonProperty + String authKey = "api_key"; + + @JsonProperty + String authKeyLocation = "query"; + + public String getAuthName() { + return authName; + } + + public void setAuthName(String authName) { + this.authName = authName; + } + + public String getAuthKey() { + return authKey; + } + + public void setAuthKey(String authKey) { + this.authKey = authKey; + } + + public String getAuthKeyLocation() { + return authKeyLocation; + } + + public void setAuthKeyLocation(String authKeyLocation) { + this.authKeyLocation = authKeyLocation; + } +} diff --git a/src/main/java/io/federecio/dropwizard/swagger/SwaggerView.java b/src/main/java/io/federecio/dropwizard/swagger/SwaggerView.java index e096fdb7..dca229c5 100644 --- a/src/main/java/io/federecio/dropwizard/swagger/SwaggerView.java +++ b/src/main/java/io/federecio/dropwizard/swagger/SwaggerView.java @@ -29,9 +29,11 @@ public class SwaggerView extends View { private final String swaggerAssetsPath; private final String contextPath; + private final SwaggerUIConfiguration config; - protected SwaggerView(String urlPattern) { + protected SwaggerView(String urlPattern, SwaggerUIConfiguration config) { super("index.ftl", Charsets.UTF_8); + this.config = config; if (urlPattern.equals("/")) { swaggerAssetsPath = Constants.SWAGGER_URI_PATH; @@ -61,4 +63,19 @@ public String getSwaggerAssetsPath() { public String getContextPath() { return contextPath; } + + @SuppressWarnings("unused") + public String getAuthName() { + return config.getAuthName(); + } + + @SuppressWarnings("unused") + public String getAuthKey() { + return config.getAuthKey(); + } + + @SuppressWarnings("unused") + public String getAuthKeyLocation() { + return config.getAuthKeyLocation(); + } } diff --git a/src/main/resources/io/federecio/dropwizard/swagger/index.ftl b/src/main/resources/io/federecio/dropwizard/swagger/index.ftl index 44dd16a4..344afc21 100644 --- a/src/main/resources/io/federecio/dropwizard/swagger/index.ftl +++ b/src/main/resources/io/federecio/dropwizard/swagger/index.ftl @@ -55,7 +55,7 @@ log("key: " + key); if(key && key.trim() != "") { log("added key " + key); - window.authorizations.add("api_key", new ApiKeyAuthorization("api_key", key, "query")); + window.authorizations.add("${authName}", new ApiKeyAuthorization("${authKey}", key, "${authKeyLocation}")); } } diff --git a/src/test/java/io/federecio/dropwizard/swagger/DropwizardTest.java b/src/test/java/io/federecio/dropwizard/swagger/DropwizardTest.java index 3c073e01..78bedf42 100644 --- a/src/test/java/io/federecio/dropwizard/swagger/DropwizardTest.java +++ b/src/test/java/io/federecio/dropwizard/swagger/DropwizardTest.java @@ -18,14 +18,11 @@ import com.google.common.base.Joiner; import com.google.common.base.Splitter; import com.jayway.restassured.RestAssured; -import com.wordnik.swagger.jaxrs.listing.ApiListingResource; import org.eclipse.jetty.http.HttpStatus; import org.hamcrest.core.StringContains; import org.junit.Before; -import org.junit.BeforeClass; import org.junit.Test; -import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -47,13 +44,6 @@ public void setPort() { RestAssured.port = port; } - @BeforeClass - public static void crap() throws Exception { - Field initialized = ApiListingResource.class.getDeclaredField("initialized"); - initialized.setAccessible(true); - initialized.set(null, false); - } - @Test public void resourceIsAvailable() throws Exception { RestAssured.expect().statusCode(HttpStatus.OK_200).when().get(Path.from(basePath, "test.json")); diff --git a/src/test/java/io/federecio/dropwizard/swagger/TestResource.java b/src/test/java/io/federecio/dropwizard/swagger/TestResource.java index 46feea6c..37b56dbc 100644 --- a/src/test/java/io/federecio/dropwizard/swagger/TestResource.java +++ b/src/test/java/io/federecio/dropwizard/swagger/TestResource.java @@ -15,8 +15,8 @@ */ package io.federecio.dropwizard.swagger; -import com.wordnik.swagger.annotations.Api; -import com.wordnik.swagger.annotations.ApiOperation; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; import javax.ws.rs.GET; import javax.ws.rs.Path;