Repository: cxf
Updated Branches:
  refs/heads/master e127bc912 -> 982556218


[CXF-7482] Let users customize Swagger2Feature with the external properties file


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/98255621
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/98255621
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/98255621

Branch: refs/heads/master
Commit: 982556218c86ad834a6bf76e62e0a77d055e291d
Parents: e127bc9
Author: Sergey Beryozkin <sberyoz...@gmail.com>
Authored: Tue Aug 22 16:43:16 2017 +0100
Committer: Sergey Beryozkin <sberyoz...@gmail.com>
Committed: Tue Aug 22 16:43:16 2017 +0100

----------------------------------------------------------------------
 .../jaxrs/swagger/AbstractSwaggerFeature.java   |   4 +-
 .../cxf/jaxrs/swagger/Swagger2Feature.java      | 232 +++++++++++++++----
 .../AbstractSwagger2ServiceDescriptionTest.java |  19 +-
 .../Swagger2CustomPropertiesTest.java           |  69 ++++++
 .../src/test/resources/files/swagger.properties |   5 +
 5 files changed, 280 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/98255621/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java
 
b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java
index d5135ae..11ba731 100644
--- 
a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java
+++ 
b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/AbstractSwaggerFeature.java
@@ -47,8 +47,8 @@ public abstract class AbstractSwaggerFeature extends 
AbstractFeature {
     private String title;
     private String description;
     private String contact;
-    private String license = "Apache 2.0 License";
-    private String licenseUrl = 
"http://www.apache.org/licenses/LICENSE-2.0.html";;
+    private String license;
+    private String licenseUrl;
     private String termsOfServiceUrl;
     private String filterClass;
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/98255621/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
----------------------------------------------------------------------
diff --git 
a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
 
b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
index 8260281..78bc676 100644
--- 
a/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
+++ 
b/rt/rs/description-swagger/src/main/java/org/apache/cxf/jaxrs/swagger/Swagger2Feature.java
@@ -19,6 +19,7 @@
 package org.apache.cxf.jaxrs.swagger;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.net.URI;
 import java.net.URL;
 import java.util.ArrayList;
@@ -28,6 +29,7 @@ import java.util.LinkedHashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.regex.Pattern;
 
@@ -53,6 +55,7 @@ import org.apache.cxf.Bus;
 import org.apache.cxf.annotations.Provider;
 import org.apache.cxf.annotations.Provider.Scope;
 import org.apache.cxf.annotations.Provider.Type;
+import org.apache.cxf.common.util.PropertyUtils;
 import org.apache.cxf.common.util.StringUtils;
 import org.apache.cxf.endpoint.Server;
 import org.apache.cxf.jaxrs.JAXRSServiceFactoryBean;
@@ -62,6 +65,7 @@ import org.apache.cxf.jaxrs.model.ApplicationInfo;
 import org.apache.cxf.jaxrs.model.ClassResourceInfo;
 import org.apache.cxf.jaxrs.provider.ServerProviderFactory;
 import org.apache.cxf.jaxrs.utils.InjectionUtils;
+import org.apache.cxf.jaxrs.utils.ResourceUtils;
 import org.apache.cxf.message.Message;
 
 import io.swagger.jaxrs.config.BeanConfig;
@@ -74,13 +78,27 @@ import io.swagger.models.auth.SecuritySchemeDefinition;
 
 @Provider(value = Type.Feature, scope = Scope.Server)
 public class Swagger2Feature extends AbstractSwaggerFeature {
-    
-    private String host;
-
-    private String[] schemes;
-
-    private boolean prettyPrint;
 
+    private static final String DEFAULT_LICENSE_VALUE = "Apache 2.0 License";
+    private static final String DEFAULT_LICENSE_URL = 
"http://www.apache.org/licenses/LICENSE-2.0.html";;
+    
+    private static final String DEFAULT_PROPS_LOCATION = "/swagger.properties";
+    private static final String RESOURCE_PACKAGE_PROPERTY = "resource.package";
+    private static final String TITLE_PROPERTY = "title";
+    private static final String SCHEMES_PROPERTY = "schemes";
+    private static final String VERSION_PROPERTY = "version";
+    private static final String DESCRIPTION_PROPERTY = "description";
+    private static final String CONTACT_PROPERTY = "contact";
+    private static final String LICENSE_PROPERTY = "license";
+    private static final String LICENSE_URL_PROPERTY = "license.url";
+    private static final String TERMS_URL_PROPERTY = "terms.url";
+    private static final String PRETTY_PRINT_PROPERTY = "pretty.print";
+    private static final String FILTER_CLASS_PROPERTY = "filter.class";
+    private static final String HOST_PROPERTY = "host";
+    private static final String USE_PATH_CFG_PROPERTY = 
"use.path.based.config";
+    
+    private boolean runAsFilter;
+    
     private boolean scanAllResources;
 
     private String ignoreRoutes;
@@ -93,13 +111,18 @@ public class Swagger2Feature extends 
AbstractSwaggerFeature {
 
     private Map<String, String> swaggerUiMediaTypes;
 
-    private boolean usePathBasedConfig;
-
     private boolean dynamicBasePath;
 
     private Map<String, SecuritySchemeDefinition> securityDefinitions;
     
     private Swagger2Customizer customizer;
+    
+    private String host;
+    private String[] schemes;
+    private Boolean prettyPrint;
+    private Boolean usePathBasedConfig;
+    
+    private String propertiesLocation = DEFAULT_PROPS_LOCATION;
 
     @Override
     protected void calculateDefaultBasePath(Server server) {
@@ -170,46 +193,159 @@ public class Swagger2Feature extends 
AbstractSwaggerFeature {
         customizer.setClassResourceInfos(cris);
         customizer.setDynamicBasePath(dynamicBasePath);
         
-        providers.add(new ReaderConfigFilter());
-
-        if (usePathBasedConfig) {
-            providers.add(new ServletConfigProvider());
-        }
-
-        ((ServerProviderFactory) server.getEndpoint().get(
-                
ServerProviderFactory.class.getName())).setUserProviders(providers);
         BeanConfig beanConfig = appInfo == null
             ? new BeanConfig()
             : new ApplicationBeanConfig(appInfo.getProvider());
-        beanConfig.setResourcePackage(getResourcePackage());
-        beanConfig.setUsePathBasedConfig(isUsePathBasedConfig());
-        beanConfig.setVersion(getVersion());
-        String basePath = getBasePath();
-        beanConfig.setBasePath(basePath);
-        beanConfig.setHost(getHost());
-        beanConfig.setSchemes(getSchemes());
-        beanConfig.setTitle(getTitle());
-        beanConfig.setDescription(getDescription());
-        beanConfig.setContact(getContact());
-        beanConfig.setLicense(getLicense());
-        beanConfig.setLicenseUrl(getLicenseUrl());
-        beanConfig.setTermsOfServiceUrl(getTermsOfServiceUrl());
-        beanConfig.setScan(isScan());
-        beanConfig.setPrettyPrint(isPrettyPrint());
-        beanConfig.setFilterClass(getFilterClass());
+        initBeanConfig(bus, beanConfig);
 
         Swagger swagger = beanConfig.getSwagger();
         if (swagger != null && securityDefinitions != null) {
             swagger.setSecurityDefinitions(securityDefinitions);
         }
         customizer.setBeanConfig(beanConfig);
+        
+        providers.add(new ReaderConfigFilter());
+
+        if (beanConfig.isUsePathBasedConfig()) {
+            providers.add(new ServletConfigProvider());
+        }
+
+        ((ServerProviderFactory) server.getEndpoint().get(
+                
ServerProviderFactory.class.getName())).setUserProviders(providers);
     }
 
-    public boolean isUsePathBasedConfig() {
+    protected void initBeanConfig(Bus bus, BeanConfig beanConfig) {
+        InputStream is = 
ResourceUtils.getClasspathResourceStream(propertiesLocation, 
+                                                 AbstractSwaggerFeature.class, 
+                                                 bus);
+        Properties props = null;
+        if (is != null) {
+            props = new Properties();
+            try {
+                props.load(is);
+            } catch (IOException ex) {
+                props = null;
+            }
+        }
+        // resource package
+        String theResourcePackage = getResourcePackage();
+        if (theResourcePackage == null && props != null) {
+            theResourcePackage = props.getProperty(RESOURCE_PACKAGE_PROPERTY);
+        }
+        beanConfig.setResourcePackage(theResourcePackage);
+        
+        // use path based configuration
+        Boolean theUsePathBasedConfig = isUsePathBasedConfig();
+        if (theUsePathBasedConfig == null && props != null) {
+            theUsePathBasedConfig = 
PropertyUtils.isTrue(props.get(USE_PATH_CFG_PROPERTY));
+        }
+        if (theUsePathBasedConfig == null) {
+            theUsePathBasedConfig = false;
+        }
+        beanConfig.setUsePathBasedConfig(theUsePathBasedConfig);
+        
+        // version 
+        String theVersion = getVersion();
+        if (theVersion == null && props != null) {
+            theVersion = props.getProperty(VERSION_PROPERTY);
+        }
+        beanConfig.setVersion(theVersion);
+        
+        // host
+        String theHost = getHost();
+        if (theHost == null && props != null) {
+            theHost = props.getProperty(HOST_PROPERTY);
+        }
+        beanConfig.setHost(theHost);
+        
+        // schemes
+        String[] theSchemes = getSchemes();
+        if (theSchemes == null && props != null && 
props.containsKey(SCHEMES_PROPERTY)) {
+            theSchemes = props.getProperty(SCHEMES_PROPERTY).split(",");
+        }
+        beanConfig.setSchemes(theSchemes);
+        
+        // title
+        String theTitle = getTitle();
+        if (theTitle == null && props != null) {
+            theTitle = props.getProperty(TITLE_PROPERTY);
+        }
+        beanConfig.setTitle(theTitle);
+        
+        // description
+        String theDescription = getDescription();
+        if (theDescription == null && props != null) {
+            theDescription = props.getProperty(DESCRIPTION_PROPERTY);
+        }
+        beanConfig.setDescription(theDescription);
+        
+        // contact
+        String theContact = getContact();
+        if (theContact == null && props != null) {
+            theContact = props.getProperty(CONTACT_PROPERTY);
+        }
+        beanConfig.setContact(theContact);
+        
+        // license
+        String theLicense = getLicense();
+        if (theLicense == null && props != null) {
+            theLicense = props.getProperty(LICENSE_PROPERTY);
+        }
+        if (theLicense == null) {
+            theLicense = DEFAULT_LICENSE_VALUE;
+        }
+        beanConfig.setLicense(theLicense);
+        
+        // license url
+        String theLicenseUrl = null;
+        if (!DEFAULT_LICENSE_VALUE.equals(theLicense)) {
+            theLicenseUrl = getLicenseUrl();
+            if (theLicenseUrl == null && props != null) {
+                theLicenseUrl = props.getProperty(LICENSE_URL_PROPERTY);
+            }
+        } else {
+            theLicenseUrl = DEFAULT_LICENSE_URL;
+        }
+        beanConfig.setLicenseUrl(theLicenseUrl);
+        
+        // terms of service url
+        String theTermsUrl = getTermsOfServiceUrl();
+        if (theTermsUrl == null && props != null) {
+            theContact = props.getProperty(TERMS_URL_PROPERTY);
+        }
+        beanConfig.setTermsOfServiceUrl(theTermsUrl);
+        
+        // pretty print
+        Boolean thePrettyPrint = isPrettyPrint();
+        if (thePrettyPrint == null && props != null) {
+            thePrettyPrint = 
PropertyUtils.isTrue(props.get(PRETTY_PRINT_PROPERTY));
+        }
+        if (thePrettyPrint == null) {
+            thePrettyPrint = false;
+        }
+        beanConfig.setPrettyPrint(thePrettyPrint);
+        
+        // filter class
+        String theFilterClass = getFilterClass();
+        if (theFilterClass == null && props != null) {
+            theFilterClass = props.getProperty(FILTER_CLASS_PROPERTY);
+        }
+        beanConfig.setFilterClass(theFilterClass);
+        
+        // scan 
+        //TODO: has no effect on Swagger which always scans and needs to be 
removed
+        beanConfig.setScan(isScan());
+        
+        // base path is calculated dynamically
+        beanConfig.setBasePath(getBasePath());
+        
+    }
+
+    public Boolean isUsePathBasedConfig() {
         return usePathBasedConfig;
     }
 
-    public void setUsePathBasedConfig(boolean usePathBasedConfig) {
+    public void setUsePathBasedConfig(Boolean usePathBasedConfig) {
         this.usePathBasedConfig = usePathBasedConfig;
     }
 
@@ -225,26 +361,26 @@ public class Swagger2Feature extends 
AbstractSwaggerFeature {
         return schemes;
     }
     
-    public Swagger2Customizer getCustomizer() {
-        return customizer;
-    }
-
-    public void setCustomizer(Swagger2Customizer customizer) {
-        this.customizer = customizer;
-    }
-
     public void setSchemes(String[] schemes) {
         this.schemes = schemes;
     }
 
-    public boolean isPrettyPrint() {
+    public Boolean isPrettyPrint() {
         return prettyPrint;
     }
 
-    public void setPrettyPrint(boolean prettyPrint) {
+    public void setPrettyPrint(Boolean prettyPrint) {
         this.prettyPrint = prettyPrint;
     }
+    
+    public Swagger2Customizer getCustomizer() {
+        return customizer;
+    }
 
+    public void setCustomizer(Swagger2Customizer customizer) {
+        this.customizer = customizer;
+    }
+    
     public boolean isScanAllResources() {
         return scanAllResources;
     }
@@ -297,6 +433,14 @@ public class Swagger2Feature extends 
AbstractSwaggerFeature {
         this.securityDefinitions = securityDefinitions;
     }
 
+    public String getPropertiesLocation() {
+        return propertiesLocation;
+    }
+
+    public void setPropertiesLocation(String propertiesLocation) {
+        this.propertiesLocation = propertiesLocation;
+    }
+    
     private class ServletConfigProvider implements 
ContextProvider<ServletConfig> {
 
         @Override

http://git-wip-us.apache.org/repos/asf/cxf/blob/98255621/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/AbstractSwagger2ServiceDescriptionTest.java
----------------------------------------------------------------------
diff --git 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/AbstractSwagger2ServiceDescriptionTest.java
 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/AbstractSwagger2ServiceDescriptionTest.java
index 2157ed1..7cc70aa 100644
--- 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/AbstractSwagger2ServiceDescriptionTest.java
+++ 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/AbstractSwagger2ServiceDescriptionTest.java
@@ -56,9 +56,14 @@ import org.junit.Test;
 import org.yaml.snakeyaml.Yaml;
 
 public abstract class AbstractSwagger2ServiceDescriptionTest extends 
AbstractBusClientServerTestBase {
-    private static final String CONTACT = "CXF unittest";
-    private static final String SECURITY_DEFINITION_NAME = "basicAuth";
-
+    static final String SECURITY_DEFINITION_NAME = "basicAuth";
+    
+    private static final String CONTACT = "c...@apache.org";
+    private static final String TITLE = "CXF unittest";
+    private static final String DESCRIPTION = "API Description";
+    private static final String LICENSE = "API License";
+    private static final String LICENSE_URL = "API License URL";
+    
     @Ignore
     public abstract static class Server extends AbstractBusTestServerBase {
         protected final String port;
@@ -88,6 +93,10 @@ public abstract class AbstractSwagger2ServiceDescriptionTest 
extends AbstractBus
             final Swagger2Feature feature = new Swagger2Feature();
             feature.setRunAsFilter(runAsFilter);
             feature.setContact(CONTACT);
+            feature.setTitle(TITLE);
+            feature.setDescription(DESCRIPTION);
+            feature.setLicense(LICENSE);
+            feature.setLicenseUrl(LICENSE_URL);
             
feature.setSecurityDefinitions(Collections.singletonMap(SECURITY_DEFINITION_NAME,
                new io.swagger.models.auth.BasicAuthDefinition()));
             return feature;
@@ -155,6 +164,10 @@ public abstract class 
AbstractSwagger2ServiceDescriptionTest extends AbstractBus
             assertEquals(ParameterType.PATH, delOpParams.get(0).getType());
 
             assertThat(swaggerJson, CoreMatchers.containsString(CONTACT));
+            assertThat(swaggerJson, CoreMatchers.containsString(TITLE));
+            assertThat(swaggerJson, CoreMatchers.containsString(DESCRIPTION));
+            assertThat(swaggerJson, CoreMatchers.containsString(LICENSE));
+            assertThat(swaggerJson, CoreMatchers.containsString(LICENSE_URL));
             assertThat(swaggerJson, 
CoreMatchers.containsString(SECURITY_DEFINITION_NAME));
         } finally {
             client.close();

http://git-wip-us.apache.org/repos/asf/cxf/blob/98255621/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/Swagger2CustomPropertiesTest.java
----------------------------------------------------------------------
diff --git 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/Swagger2CustomPropertiesTest.java
 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/Swagger2CustomPropertiesTest.java
new file mode 100644
index 0000000..c414c33
--- /dev/null
+++ 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/description/Swagger2CustomPropertiesTest.java
@@ -0,0 +1,69 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.cxf.systest.jaxrs.description;
+
+import java.util.Collections;
+
+import org.apache.cxf.jaxrs.swagger.Swagger2Feature;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class Swagger2CustomPropertiesTest extends 
AbstractSwagger2ServiceDescriptionTest {
+    private static final String PORT = 
allocatePort(Swagger2CustomPropertiesTest.class);
+
+    public static class SwaggerRegular extends Server {
+        public SwaggerRegular() {
+            super(PORT, false);
+        }
+
+        public static void main(String[] args) {
+            start(new SwaggerRegular());
+        }
+        
+        protected Swagger2Feature createSwagger2Feature() {
+            final Swagger2Feature feature = new Swagger2Feature();
+            feature.setRunAsFilter(runAsFilter);
+            feature.setPropertiesLocation("/files/swagger.properties");
+            
feature.setSecurityDefinitions(Collections.singletonMap(SECURITY_DEFINITION_NAME,
+               new io.swagger.models.auth.BasicAuthDefinition()));
+            return feature;
+        }
+    }
+
+    @BeforeClass
+    public static void startServers() throws Exception {
+        startServers(SwaggerRegular.class);
+    }
+
+    @Override
+    protected String getPort() {
+        return PORT;
+    }
+
+    @Override
+    protected String getExpectedFileYaml() {
+        return "swagger2-yaml.txt";
+    }
+
+    @Test
+    public void testApiListingIsProperlyReturnedJSON() throws Exception {
+        doTestApiListingIsProperlyReturnedJSON();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/98255621/systests/jaxrs/src/test/resources/files/swagger.properties
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/resources/files/swagger.properties 
b/systests/jaxrs/src/test/resources/files/swagger.properties
new file mode 100644
index 0000000..417045b
--- /dev/null
+++ b/systests/jaxrs/src/test/resources/files/swagger.properties
@@ -0,0 +1,5 @@
+contact=c...@apache.org
+title=CXF unittest
+description=API Description
+license=API License
+license.url=API License URL
\ No newline at end of file

Reply via email to