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 <[hidden email]> 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; } } |
Free forum by Nabble | Edit this page |