You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by gr...@apache.org on 2020/08/23 06:28:25 UTC
[ofbiz-plugins] branch trunk updated: Added support to read
children attributes of the service for rendering openapi spec (#40)
This is an automated email from the ASF dual-hosted git repository.
grv pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/ofbiz-plugins.git
The following commit(s) were added to refs/heads/trunk by this push:
new dce5c97 Added support to read children attributes of the service for rendering openapi spec (#40)
dce5c97 is described below
commit dce5c976f7b1e509bc8d2f4046b2c370ca0adc45
Author: girishvasmatkar <47...@users.noreply.github.com>
AuthorDate: Sun Aug 23 11:58:19 2020 +0530
Added support to read children attributes of the service for rendering openapi spec (#40)
---
.../ofbiz/ws/rs/openapi/OFBizOpenApiReader.java | 48 +-----
.../ws/rs/resources/AuthenticationResource.java | 8 +-
.../ws/rs/resources/OFBizServiceResource.java | 5 +-
.../org/apache/ofbiz/ws/rs/util/OpenApiUtil.java | 169 ++++++++++++++++++++-
4 files changed, 177 insertions(+), 53 deletions(-)
diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
index de1c9e8..20b9301 100644
--- a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
+++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/openapi/OFBizOpenApiReader.java
@@ -44,13 +44,9 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
-import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Content;
-import io.swagger.v3.oas.models.media.IntegerSchema;
import io.swagger.v3.oas.models.media.MediaType;
-import io.swagger.v3.oas.models.media.ObjectSchema;
import io.swagger.v3.oas.models.media.Schema;
-import io.swagger.v3.oas.models.media.StringSchema;
import io.swagger.v3.oas.models.parameters.QueryParameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
@@ -159,7 +155,6 @@ public final class OFBizOpenApiReader extends Reader implements OpenApiReader {
openApi.setPaths(paths);
openApi.setComponents(components);
-
return openApi;
}
@@ -193,50 +188,11 @@ public final class OFBizOpenApiReader extends Reader implements OpenApiReader {
}
private void setOutSchemaForService(ModelService service) {
- Schema<Object> parentSchema = new Schema<Object>();
- parentSchema.setDescription("Out Schema for service: " + service.getName() + " response");
- parentSchema.setType("object");
- parentSchema.addProperties("statusCode", new IntegerSchema().description("HTTP Status Code"));
- parentSchema.addProperties("statusDescription", new StringSchema().description("HTTP Status Code Description"));
- parentSchema.addProperties("successMessage", new StringSchema().description("Success Message"));
- ObjectSchema dataSchema = new ObjectSchema();
- parentSchema.addProperties("data", dataSchema);
- service.getOutParamNamesMap().forEach((name, type) -> {
- Schema<?> schema = null;
- Class<?> schemaClass = OpenApiUtil.getOpenApiSchema(type);
- if (schemaClass == null) {
- return;
- }
- try {
- schema = (Schema<?>) schemaClass.newInstance();
- } catch (InstantiationException | IllegalAccessException e) {
- }
- if (schema instanceof ArraySchema) {
- ArraySchema arraySchema = (ArraySchema) schema;
- arraySchema.items(new StringSchema());
- }
- dataSchema.addProperties(name, schema.description(name));
- });
- schemas.put(service.getName() + "Response", parentSchema);
+ schemas.put(service.getName() + "Response", OpenApiUtil.getOutSchema(service));
}
private void setInSchemaForService(ModelService service) {
- Schema<Object> parentSchema = new Schema<Object>();
- parentSchema.setDescription("In Schema for service: " + service.getName() + " request");
- parentSchema.setType("object");
- service.getInParamNamesMap().forEach((name, type) -> {
- Schema<?> schema = null;
- Class<?> schemaClass = OpenApiUtil.getOpenApiSchema(type);
- if (schemaClass == null) {
- return;
- }
- try {
- schema = (Schema<?>) schemaClass.newInstance();
- } catch (InstantiationException | IllegalAccessException e) {
- }
- parentSchema.addProperties(name, schema.description(name));
- });
- schemas.put(service.getName() + "Request", parentSchema);
+ schemas.put(service.getName() + "Request", OpenApiUtil.getInSchema(service));
}
}
diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
index c675e7d..b2a0671 100644
--- a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
+++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/AuthenticationResource.java
@@ -22,10 +22,12 @@ import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.HeaderParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
+import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
@@ -38,6 +40,8 @@ import org.apache.ofbiz.ws.rs.security.AuthToken;
import org.apache.ofbiz.ws.rs.util.RestApiUtil;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
@@ -61,7 +65,9 @@ public class AuthenticationResource extends OFBizResource {
@AuthToken
@Operation(security = @SecurityRequirement(name = "basicAuth"),
operationId = "getAuthToken", description = "Generates JWT token for subsequent API calles.")
- public Response getAuthToken() {
+ public Response getAuthToken(@Parameter(in = ParameterIn.HEADER, name = "Authorization",
+ description = "Authorization header using Basic Authentication", example = HttpHeaders.AUTHORIZATION + ": Basic YWRtaW46b2ZiaXo=")
+ @HeaderParam(HttpHeaders.AUTHORIZATION) String creds) {
httpRequest.setAttribute("delegator", getDelegator());
httpRequest.setAttribute("dispatcher", getDispatcher());
GenericValue userLogin = (GenericValue) httpRequest.getAttribute("userLogin");
diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
index 0a3a9c5..c51887c 100644
--- a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
+++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/resources/OFBizServiceResource.java
@@ -81,7 +81,8 @@ public class OFBizServiceResource extends OFBizResource {
Map<String, Object> serviceMap = new LinkedHashMap<String, Object>();
serviceMap.put("name", service.getName());
serviceMap.put("description", service.getDescription());
- Link selfLink = Link.fromUriBuilder(uriInfo.getAbsolutePathBuilder().path(service.getName())).type(service.getAction()).rel("self").build();
+ Link selfLink = Link.fromUriBuilder(uriInfo.getAbsolutePathBuilder().path(service.getName()))
+ .type(service.getAction()).rel("self").build();
serviceMap.put("link", selfLink);
serviceList.add(serviceMap);
}
@@ -108,7 +109,6 @@ public class OFBizServiceResource extends OFBizResource {
return processor.process(
UtilMisc.toMap("serviceName", serviceName, "httpVerb", HttpMethod.GET, "requestMap", serviceRequest.getInParams(), "dispatcher",
getDispatcher(), "request", httpRequest));
-
}
/**
@@ -128,6 +128,5 @@ public class OFBizServiceResource extends OFBizResource {
return processor.process(
UtilMisc.toMap("serviceName", serviceName, "httpVerb", HttpMethod.POST, "requestMap", serviceInParams, "dispatcher", getDispatcher(),
"request", httpRequest));
-
}
}
diff --git a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/util/OpenApiUtil.java b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/util/OpenApiUtil.java
index 7e32226..c8d98f2 100644
--- a/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/util/OpenApiUtil.java
+++ b/ofbiz-rest-impl/src/main/java/org/apache/ofbiz/ws/rs/util/OpenApiUtil.java
@@ -19,24 +19,40 @@
package org.apache.ofbiz.ws.rs.util;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import org.apache.ofbiz.base.util.Debug;
+import org.apache.ofbiz.base.util.UtilValidate;
+import org.apache.ofbiz.entity.Delegator;
+import org.apache.ofbiz.entity.model.ModelEntity;
+import org.apache.ofbiz.entity.model.ModelField;
+import org.apache.ofbiz.service.ModelParam;
+import org.apache.ofbiz.service.ModelService;
+import org.apache.ofbiz.webapp.WebAppUtil;
+import org.apache.ofbiz.ws.rs.listener.ApiContextListener;
+
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.BooleanSchema;
import io.swagger.v3.oas.models.media.DateSchema;
import io.swagger.v3.oas.models.media.IntegerSchema;
import io.swagger.v3.oas.models.media.MapSchema;
import io.swagger.v3.oas.models.media.NumberSchema;
+import io.swagger.v3.oas.models.media.ObjectSchema;
+import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.media.StringSchema;
public final class OpenApiUtil {
+ private static final String MODULE = OpenApiUtil.class.getName();
+
private OpenApiUtil() {
}
private static final Map<String, String> CLASS_ALIAS = new HashMap<>();
private static final Map<String, Class<?>> JAVA_OPEN_API_MAP = new HashMap<>();
+ private static final Map<String, String> FIELD_TYPE_MAP = new HashMap<String, String>();
static {
CLASS_ALIAS.put("String", "String");
@@ -50,7 +66,7 @@ public final class OpenApiUtil {
CLASS_ALIAS.put("Timestamp", "Timestamp");
CLASS_ALIAS.put("java.sql.Timestamp", "Timestamp");
CLASS_ALIAS.put("Integer", "Integer");
- CLASS_ALIAS.put("java.lang.Integer", "Int");
+ CLASS_ALIAS.put("java.lang.Integer", "Integer");
CLASS_ALIAS.put("Long", "Long");
CLASS_ALIAS.put("java.lang.Long", "Long");
CLASS_ALIAS.put("BigInteger", "BigInteger");
@@ -98,10 +114,157 @@ public final class OpenApiUtil {
JAVA_OPEN_API_MAP.put("BigInteger", IntegerSchema.class);
JAVA_OPEN_API_MAP.put("Timestamp", DateSchema.class);
+ FIELD_TYPE_MAP.put("id", "String");
+ FIELD_TYPE_MAP.put("indicator", "String");
+ FIELD_TYPE_MAP.put("date", "String");
+ FIELD_TYPE_MAP.put("id-vlong", "String");
+ FIELD_TYPE_MAP.put("description", "String");
+ FIELD_TYPE_MAP.put("numeric", "Int"); //
+ FIELD_TYPE_MAP.put("long-varchar", "String");
+ FIELD_TYPE_MAP.put("id-long", "String");
+ FIELD_TYPE_MAP.put("currency-amount", "BigDecimal");
+ FIELD_TYPE_MAP.put("value", "value");
+ FIELD_TYPE_MAP.put("email", "String");
+ FIELD_TYPE_MAP.put("currency-precise", "BigDecimal");
+ FIELD_TYPE_MAP.put("very-short", "String");
+ FIELD_TYPE_MAP.put("date-time", "Timestamp");
+ FIELD_TYPE_MAP.put("credit-card-date", "String");
+ FIELD_TYPE_MAP.put("url", "String");
+ FIELD_TYPE_MAP.put("credit-card-number", "String");
+ FIELD_TYPE_MAP.put("fixed-point", "BigDecimal");
+ FIELD_TYPE_MAP.put("name", "String");
+ FIELD_TYPE_MAP.put("short-varchar", "String");
+ FIELD_TYPE_MAP.put("comment", "String");
+ FIELD_TYPE_MAP.put("time", "String");
+ FIELD_TYPE_MAP.put("very-long", "String");
+ FIELD_TYPE_MAP.put("floating-point", "Float");
+ FIELD_TYPE_MAP.put("object", "Byte");
+ FIELD_TYPE_MAP.put("byte-array", "Byte");
+ FIELD_TYPE_MAP.put("blob", "Byte");
+
+ }
+
+ public static Class<?> getOpenApiTypeForAttributeType(String attributeType) {
+ return JAVA_OPEN_API_MAP.get(CLASS_ALIAS.get(attributeType));
+ }
+
+ public static Class<?> getOpenApiTypeForFieldType(String fieldType) {
+ return JAVA_OPEN_API_MAP.get(FIELD_TYPE_MAP.get(fieldType));
+ }
+
+ public static Schema<Object> getInSchema(ModelService service) {
+ Schema<Object> parentSchema = new Schema<Object>();
+ parentSchema.setDescription("In Schema for service: " + service.getName() + " request");
+ parentSchema.setType("object");
+ service.getInParamNamesMap().forEach((name, type) -> {
+ Schema<?> attrSchema = getAttributeSchema(service, service.getParam(name));
+ if (attrSchema != null) {
+ parentSchema.addProperties(name, getAttributeSchema(service, service.getParam(name)));
+ }
+ });
+ return parentSchema;
}
+ private static Schema<?> getAttributeSchema(ModelService service, ModelParam param) {
+ Schema<?> schema = null;
+ Class<?> schemaClass = getOpenApiTypeForAttributeType(param.getType());
+ if (schemaClass == null) {
+ Debug.logWarning("Attribute '" + param.getName() + "' ignored as it is declared as '" + param.getType()
+ + "' and corresponding OpenApi Type Mapping not found.", MODULE);
+ return null;
+ }
+ try {
+ schema = (Schema<?>) schemaClass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+
+ List<ModelParam> children = param.getChildren();
+ Delegator delegator = WebAppUtil.getDelegator(ApiContextListener.getApplicationCntx());
+ if (schema instanceof ArraySchema) {
+ ((ArraySchema) schema).setItems(getAttributeSchema(service, children.get(0)));
+ } else if (schema instanceof MapSchema) {
+ if (isTypeGenericEntityOrGenericValue(param.getType())) {
+ if (UtilValidate.isEmpty(param.getEntityName())) {
+ Debug.logWarning(
+ "Attribute '" + param.getName() + "' ignored as it is declared as '" + param.getType() + "' but does not have "
+ + "entity-name defined.",
+ MODULE);
+ return null;
+ } else {
+ schema = getSchemaForEntity(delegator.getModelEntity(param.getEntityName()));
+ }
+ } else if (UtilValidate.isEmpty(param.getChildren())) {
+ Debug.logWarning(
+ "Attribute '" + param.getName() + "' ignored as it is declared as '" + param.getType() + "' but does not have "
+ + "any child attributes.",
+ MODULE);
+ return null;
+ } else {
+ for (ModelParam childParam : children) {
+ schema.addProperties(childParam.getName(), getAttributeSchema(service, childParam));
+ }
+
+ }
+
+ }
+ return schema;
+ }
+
+ public static Schema<Object> getOutSchema(ModelService service) {
+ Schema<Object> parentSchema = new Schema<Object>();
+ parentSchema.setDescription("Out Schema for service: " + service.getName() + " response");
+ parentSchema.setType("object");
+ parentSchema.addProperties("statusCode", new IntegerSchema().description("HTTP Status Code"));
+ parentSchema.addProperties("statusDescription", new StringSchema().description("HTTP Status Code Description"));
+ parentSchema.addProperties("successMessage", new StringSchema().description("Success Message"));
+ ObjectSchema dataSchema = new ObjectSchema();
+ parentSchema.addProperties("data", dataSchema);
+ service.getOutParamNamesMap().forEach((name, type) -> {
+ Schema<?> schema = null;
+ Class<?> schemaClass = getOpenApiTypeForAttributeType(type);
+ if (schemaClass == null) {
+ return;
+ }
+ try {
+ schema = (Schema<?>) schemaClass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ if (schema instanceof ArraySchema) {
+ ArraySchema arraySchema = (ArraySchema) schema;
+ arraySchema.items(new StringSchema());
+ }
+ dataSchema.addProperties(name, schema.description(name));
+ });
+ return parentSchema;
+ }
+
+ private static boolean isTypeGenericEntityOrGenericValue(String type) {
+ if (type == null) {
+ return false;
+ }
+ return type.matches("org.apache.ofbiz.entity.GenericValue|GenericValue|org.apache.ofbiz.entity.GenericEntity|GenericEntity");
+ }
- public static Class<?> getOpenApiSchema(String type) {
- return JAVA_OPEN_API_MAP.get(CLASS_ALIAS.get(type));
+ private static Schema<?> getSchemaForEntity(ModelEntity entity) {
+ Schema<?> dataSchema = new Schema<>();
+ dataSchema.setType("object");
+ List<String> fields = entity.getAllFieldNames();
+ for (String fieldNm : fields) {
+ ModelField field = entity.getField(fieldNm);
+ Schema<?> schema = null;
+ Class<?> schemaClass = getOpenApiTypeForFieldType(field.getType());
+ if (schemaClass == null) {
+ continue;
+ }
+ try {
+ schema = (Schema<?>) schemaClass.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ e.printStackTrace();
+ }
+ dataSchema.addProperties(fieldNm, schema.description(fieldNm));
+ }
+ return dataSchema;
}
}