diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIConfig.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIConfig.java
index b3b880b251..17a2c1f464 100644
--- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIConfig.java
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIConfig.java
@@ -28,17 +28,17 @@ import java.util.Set;
/**
* This bean class carries the properties used by some API that needs to be published within the underlying
* API-Management infrastructure.
- *
+ *
* A sample API configuration accepted by this particular bean class would look like what's shown below.
* e.g.
*
*
- * enrollment
- * admin
- * /enrol
- * 1.0.0
- * http://localhost:9763/
- * http,https
+ * enrollment
+ * admin
+ * /enrol
+ * 1.0.0
+ * http://localhost:9763/
+ * http,https
*
*/
@XmlRootElement(name = "API")
@@ -47,6 +47,9 @@ public class APIConfig {
private String name;
private String owner;
private String context;
+ private String apiDocumentationName;
+ private String apiDocumentationSummary;
+ private String apiDocumentationSourceFile;
private String endpoint;
private String version;
private String policy;
@@ -82,6 +85,33 @@ public class APIConfig {
this.name = name;
}
+ @XmlElement(name = "ApiDocumentationName", required = false)
+ public String getApiDocumentationName() {
+ return apiDocumentationName;
+ }
+
+ public void setApiDocumentationName(String apiDocumentationName) {
+ this.apiDocumentationName = apiDocumentationName;
+ }
+
+ @XmlElement(name = "ApiDocumentationSummary", required = false)
+ public String getApiDocumentationSummary() {
+ return apiDocumentationSummary;
+ }
+
+ public void setApiDocumentationSummary(String apiDocumentationSummary) {
+ this.apiDocumentationSummary = apiDocumentationSummary;
+ }
+
+ @XmlElement(name = "ApiDocumentationSourceFile", required = false)
+ public String getApiDocumentationSourceFile() {
+ return apiDocumentationSourceFile;
+ }
+
+ public void setApiDocumentationSourceFile(String apiDocumentationSourceFile) {
+ this.apiDocumentationSourceFile = apiDocumentationSourceFile;
+ }
+
@XmlElement(name = "Owner", required = true)
public String getOwner() {
return owner;
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java
index 5135e439bd..0dcc92e638 100644
--- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java
@@ -21,6 +21,8 @@ package org.wso2.carbon.apimgt.webapp.publisher;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.wso2.carbon.apimgt.api.model.Documentation;
+import org.wso2.carbon.apimgt.api.model.DocumentationType;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.api.APIProvider;
import org.wso2.carbon.apimgt.api.FaultGatewaysException;
@@ -66,18 +68,19 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.Date;
/**
* This class represents the concrete implementation of the APIPublisherService that corresponds to providing all
* API publishing related operations.
*/
public class APIPublisherServiceImpl implements APIPublisherService {
+ public static final APIManagerFactory API_MANAGER_FACTORY = APIManagerFactory.getInstance();
private static final String UNLIMITED_TIER = "Unlimited";
private static final String WS_UNLIMITED_TIER = "AsyncUnlimited";
private static final String API_PUBLISH_ENVIRONMENT = "Default";
private static final String CREATED_STATUS = "CREATED";
private static final String PUBLISH_ACTION = "Publish";
- public static final APIManagerFactory API_MANAGER_FACTORY = APIManagerFactory.getInstance();
private static final Log log = LogFactory.getLog(APIPublisherServiceImpl.class);
@Override
@@ -293,7 +296,45 @@ public class APIPublisherServiceImpl implements APIPublisherService {
}
}
}
- } catch (FaultGatewaysException | APIManagementException e) {
+ if (apiConfig.getApiDocumentationSourceFile() != null) {
+ API api = getAPI(apiConfig, true);
+
+ String fileName =
+ CarbonUtils.getCarbonHome() + File.separator + "repository" +
+ File.separator + "resources" + File.separator + "api-docs" + File.separator +
+ apiConfig.getApiDocumentationSourceFile();
+
+ BufferedReader br = new BufferedReader(new FileReader(fileName));
+ StringBuilder stringBuilder = new StringBuilder();
+ String line = null;
+ String ls = System.lineSeparator();
+ while ((line = br.readLine()) != null) {
+ stringBuilder.append(line);
+ stringBuilder.append(ls);
+ }
+ stringBuilder.deleteCharAt(stringBuilder.length() - 1);
+ br.close();
+ String docContent = stringBuilder.toString();
+
+ Documentation apiDocumentation = new Documentation(DocumentationType.HOWTO, apiConfig.getApiDocumentationName());
+ apiDocumentation.setVisibility(Documentation.DocumentVisibility.API_LEVEL);
+ apiDocumentation.setSourceType(Documentation.DocumentSourceType.MARKDOWN);
+ apiDocumentation.setCreatedDate(new Date());
+ apiDocumentation.setLastUpdated(new Date());
+ apiDocumentation.setSummary(apiConfig.getApiDocumentationSummary());
+ apiDocumentation.setOtherTypeName(null);
+
+ try {
+ //Including below code lines inside the try block because 'getDocumentation' method returns an APIManagementException exception when it doesn't have any existing doc
+ Documentation existingDoc = apiProvider.getDocumentation(api.getId(), DocumentationType.HOWTO, apiConfig.getApiDocumentationName());
+ apiProvider.removeDocumentation(api.getId(), existingDoc.getId(), null);
+ } catch (APIManagementException e) {
+ log.info("There is no any existing api documentation.");
+ }
+ apiProvider.addDocumentation(api.getId(), apiDocumentation);
+ apiProvider.addDocumentationContent(api, apiConfig.getApiDocumentationName(), docContent);
+ }
+ } catch (FaultGatewaysException | APIManagementException | IOException e) {
String msg = "Error occurred while publishing api";
log.error(msg, e);
throw new APIManagerPublisherException(e);
@@ -327,7 +368,7 @@ public class APIPublisherServiceImpl implements APIPublisherService {
try {
String fileName =
CarbonUtils.getCarbonConfigDirPath() + File.separator + "etc"
- + File.separator + tenantDomain + ".csv";
+ + File.separator + tenantDomain + ".csv";
if (Files.exists(Paths.get(fileName))) {
BufferedReader br = new BufferedReader(new FileReader(fileName));
int lineNumber = 0;
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java
index b7ad837ed8..438afef943 100644
--- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherUtil.java
@@ -64,7 +64,7 @@ public class APIPublisherUtil {
}
public static String getWsServerBaseUrl() {
- return getServerBaseUrl().replace("https","wss");
+ return getServerBaseUrl().replace("https", "wss");
}
public static String getApiEndpointUrl(String context) {
@@ -104,7 +104,32 @@ public class APIPublisherUtil {
}
apiConfig.setVersion(version);
+ String apiDocumentationName = apiDef.getApiDocumentationName();
+ if (apiDocumentationName == null || apiDocumentationName.isEmpty()) {
+ if (log.isDebugEnabled()) {
+ log.debug("'API Documentation not set in @SwaggerDefinition Annotation'");
+ }
+ } else {
+ apiConfig.setApiDocumentationName(apiDef.getApiDocumentationName());
+ }
+
+ String apiDocumentationSummary = apiDef.getApiDocumentationSummary();
+ if (apiDocumentationSummary == null || apiDocumentationSummary.isEmpty()) {
+ if (log.isDebugEnabled()) {
+ log.debug("'API Documentation summary not set in @SwaggerDefinition Annotation'");
+ }
+ } else {
+ apiConfig.setApiDocumentationSummary(apiDef.getApiDocumentationSummary());
+ }
+ String apiDocumentationSourceFile = apiDef.getApiDocumentationSourceFile();
+ if (apiDocumentationSourceFile == null || apiDocumentationSourceFile.isEmpty()) {
+ if (log.isDebugEnabled()) {
+ log.debug("'API Documentation source file not set in @SwaggerDefinition Annotation'");
+ }
+ } else {
+ apiConfig.setApiDocumentationSourceFile(apiDef.getApiDocumentationSourceFile());
+ }
String context = apiDef.getContext();
if (context == null || context.isEmpty()) {
if (log.isDebugEnabled()) {
@@ -302,20 +327,19 @@ public class APIPublisherUtil {
public static void setResourceAuthTypes(ServletContext servletContext, APIConfig apiConfig) {
List resourcesList = null;
String nonSecuredResources = servletContext.getInitParameter(NON_SECURED_RESOURCES);
- if(null != nonSecuredResources){
+ if (null != nonSecuredResources) {
resourcesList = Arrays.asList(nonSecuredResources.split(","));
}
Set templates = apiConfig.getUriTemplates();
- if(null != resourcesList) {
+ if (null != resourcesList) {
for (ApiUriTemplate template : templates) {
String fullPaath = "";
if (!template.getUriTemplate().equals(AnnotationProcessor.WILD_CARD)) {
fullPaath = apiConfig.getContext() + template.getUriTemplate();
- }
- else{
+ } else {
fullPaath = apiConfig.getContext();
}
- for(String context : resourcesList) {
+ for (String context : resourcesList) {
if (context.trim().equals(fullPaath)) {
template.setAuthType(AUTH_TYPE_NON_SECURED);
}
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/APIResourceConfiguration.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/APIResourceConfiguration.java
index 49b66e6db9..1fb2ab7880 100644
--- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/APIResourceConfiguration.java
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/config/APIResourceConfiguration.java
@@ -25,60 +25,92 @@ import java.util.List;
@XmlRootElement(name = "ResourceConfiguration")
public class APIResourceConfiguration {
- private String name;
- private String context;
- private String version;
- private List resources;
- private String[] tags;
+ private String name;
+ private String context;
+ private String apiDocumentationName;
+ private String apiDocumentationSummary;
+ private String apiDocumentationSourceFile;
+ private String version;
+ private List resources;
+ private String[] tags;
private String endpointType;
private String inSequenceName;
private String inSequenceConfig;
private String asyncApiDefinition;
public List getResources() {
- return resources;
- }
-
- @XmlElement(name = "Resources", required = true)
- public void setResources(List resources) {
- this.resources = resources;
- }
-
- public String getContext() {
- return context;
- }
-
- @XmlElement(name = "Context", required = true)
- public void setContext(String context) {
- this.context = context;
- }
-
- public String getName() {
- return name;
- }
-
- @XmlElement(name = "Name")
- public void setName(String name) {
- this.name = name;
- }
-
- public String getVersion() {
- return version;
- }
-
- @XmlElement(name = "Version")
- public void setVersion(String version) {
- this.version = version;
- }
-
- public String[] getTags() {
- return tags;
- }
-
- @XmlElement(name = "Tags")
- public void setTags(String[] tags) {
- this.tags = tags;
- }
+ return resources;
+ }
+
+ @XmlElement(name = "Resources", required = true)
+ public void setResources(List resources) {
+ this.resources = resources;
+ }
+
+ public String getContext() {
+ return context;
+ }
+
+ @XmlElement(name = "Context", required = true)
+ public void setContext(String context) {
+ this.context = context;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @XmlElement(name = "Name")
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getApiDocumentationName() {
+ return apiDocumentationName;
+ }
+
+ @XmlElement(name = "ApiDocumentation")
+
+
+ public void setApiDocumentationName(String apiDocumentationName) {
+ this.apiDocumentationName = apiDocumentationName;
+ }
+
+ public String getApiDocumentationSummary() {
+ return apiDocumentationSummary;
+ }
+
+ @XmlElement(name = "ApiDocumentationSummary")
+ public void setApiDocumentationSummary(String apiDocumentationSummary) {
+ this.apiDocumentationSummary = apiDocumentationSummary;
+ }
+
+ public String getApiDocumentationSourceFile() {
+ return apiDocumentationSourceFile;
+ }
+
+ @XmlElement(name = "ApiDocumentationSourceFile")
+ public void setApiDocumentationSourceFile(String apiDocumentationSourceFile) {
+ this.apiDocumentationSourceFile = apiDocumentationSourceFile;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ @XmlElement(name = "Version")
+ public void setVersion(String version) {
+ this.version = version;
+ }
+
+ public String[] getTags() {
+ return tags;
+ }
+
+ @XmlElement(name = "Tags")
+ public void setTags(String[] tags) {
+ this.tags = tags;
+ }
public String getEndpointType() {
return endpointType;
@@ -110,6 +142,7 @@ public class APIResourceConfiguration {
public String getAsyncApiDefinition() {
return asyncApiDefinition;
}
+
@XmlElement(name = "asyncApiDefinition")
public void setAsyncApiDefinition(String asyncApiDefinition) {
this.asyncApiDefinition = asyncApiDefinition;
diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java
index 6774aa29bd..1784d487e3 100644
--- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java
+++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/lifecycle/util/AnnotationProcessor.java
@@ -52,16 +52,14 @@ import java.util.*;
public class AnnotationProcessor {
+ public static final String WILD_CARD = "/*";
private static final Log log = LogFactory.getLog(AnnotationProcessor.class);
-
private static final String AUTH_TYPE = "Application & Application User";
private static final String STRING_ARR = "string_arr";
private static final String STRING = "string";
private static final String PACKAGE_ORG_APACHE = "org.apache";
private static final String PACKAGE_ORG_CODEHAUS = "org.codehaus";
private static final String PACKAGE_ORG_SPRINGFRAMEWORK = "org.springframework";
- public static final String WILD_CARD = "/*";
-
private static final String SWAGGER_ANNOTATIONS_INFO = "info";
private static final String SWAGGER_ANNOTATIONS_TAGS = "tags";
private static final String SWAGGER_ANNOTATIONS_EXTENSIONS = "extensions";
@@ -73,6 +71,9 @@ public class AnnotationProcessor {
private static final String SWAGGER_ANNOTATIONS_PROPERTIES_ROLES = "roles";
private static final String SWAGGER_ANNOTATIONS_PROPERTIES_VERSION = "version";
private static final String SWAGGER_ANNOTATIONS_PROPERTIES_CONTEXT = "context";
+ private static final String SWAGGER_ANNOTATIONS_PROPERTIES_API_DOCUMENTATION_NAME = "apiDocumentationName";
+ private static final String SWAGGER_ANNOTATIONS_PROPERTIES_API_DOCUMENTATION_SUMMARY = "apiDocumentationSummary";
+ private static final String SWAGGER_ANNOTATIONS_PROPERTIES_API_DOCUMENTATION_SOURCE_FILE = "apiDocumentationSourceFile";
private static final String SWAGGER_ANNOTATIONS_PROPERTIES_ENDPOINT_TYPE = "endpointType";
private static final String SWAGGER_ANNOTATIONS_PROPERTIES_IN_SEQUENCE_NAME = "inSequenceName";
private static final String SWAGGER_ANNOTATIONS_PROPERTIES_IN_SEQUENCE_CONFIG = "inSequenceConfig";
@@ -112,26 +113,46 @@ public class AnnotationProcessor {
pathClazz = (Class) classLoader.loadClass(Path.class.getName());
consumesClass = (Class) classLoader.loadClass(Consumes.class.getName());
producesClass = (Class) classLoader.loadClass(Produces.class.getName());
- apiClazz= (Class)classLoader.loadClass((SwaggerDefinition.class.getName()));
- infoClass = (Class)classLoader
+ apiClazz = (Class) classLoader.loadClass((SwaggerDefinition.class.getName()));
+ infoClass = (Class) classLoader
.loadClass((io.swagger.annotations.Info.class.getName()));
- tagClass = (Class)classLoader
+ tagClass = (Class) classLoader
.loadClass((io.swagger.annotations.Tag.class.getName()));
- extensionClass = (Class)classLoader
+ extensionClass = (Class) classLoader
.loadClass((io.swagger.annotations.Extension.class.getName()));
- extensionPropertyClass = (Class)classLoader
+ extensionPropertyClass = (Class) classLoader
.loadClass(io.swagger.annotations.ExtensionProperty.class.getName());
scopeClass = (Class) classLoader
.loadClass(org.wso2.carbon.apimgt.annotations.api.Scope.class.getName());
scopesClass = (Class) classLoader
.loadClass(org.wso2.carbon.apimgt.annotations.api.Scopes.class.getName());
- apiOperation = (Class)classLoader
+ apiOperation = (Class) classLoader
.loadClass((ApiOperation.class.getName()));
} catch (ClassNotFoundException e) {
log.error("An error has occurred while loading classes ", e);
}
}
+ /**
+ * Find the URL pointing to "/WEB-INF/classes" This method may not work in conjunction with IteratorFactory
+ * if your servlet container does not extract the /WEB-INF/classes into a real file-based directory
+ *
+ * @param servletContext
+ * @return null if cannot determin /WEB-INF/classes
+ */
+ private static URL findWebInfClassesPath(ServletContext servletContext) {
+ String path = servletContext.getRealPath("/WEB-INF/classes");
+ if (path == null) return null;
+ File fp = new File(path);
+ if (fp.exists() == false) return null;
+ try {
+ URI uri = fp.toURI();
+ return uri.toURL();
+ } catch (MalformedURLException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
public Set scanStandardContext(String className) throws IOException {
ExtendedAnnotationDB db = new ExtendedAnnotationDB();
db.addIgnoredPackages(PACKAGE_ORG_APACHE);
@@ -166,7 +187,7 @@ public class AnnotationProcessor {
if (Scopes != null) {
apiScopes = processAPIScopes(Scopes);
}
- if(apiResourceConfig != null){
+ if (apiResourceConfig != null) {
String rootContext = servletContext.getContextPath();
pathClazzMethods = pathClazz.getMethods();
Annotation rootContectAnno = clazz.getAnnotation(pathClazz);
@@ -199,21 +220,21 @@ public class AnnotationProcessor {
" This API will not be published.";
log.error(msg, e1);
} catch (RuntimeException e) {
- log.error("Unexpected error has been occurred while publishing "+ className
- +"hence, this API will not be published.");
+ log.error("Unexpected error has been occurred while publishing " + className
+ + "hence, this API will not be published.");
throw new RuntimeException(e);
}
return apiResourceConfig;
}
});
- if(apiResourceConfiguration !=null)
+ if (apiResourceConfiguration != null)
apiResourceConfigs.add(apiResourceConfiguration);
}
}
return apiResourceConfigs;
}
- private Map processAPIScopes(Annotation annotation) throws Throwable {
+ private Map processAPIScopes(Annotation annotation) throws Throwable {
Map scopes = new HashMap<>();
InvocationHandler methodHandler = Proxy.getInvocationHandler(annotation);
@@ -225,7 +246,7 @@ public class AnnotationProcessor {
StringBuilder aggregatedPermissions;
String roles[];
StringBuilder aggregatedRoles;
- for(int i=0; i