Search in sources :

Example 1 with ResponseImpl

use of org.folio.rest.tools.utils.ResponseImpl in project raml-module-builder by folio-org.

the class RestVerticle method parseParams.

private void parseParams(RoutingContext rc, Iterator<Map.Entry<String, Object>> paramList, boolean[] validRequest, JsonArray consumes, Object[] paramArray, String[] pathParams, Map<String, String> okapiHeaders) {
    HttpServerRequest request = rc.request();
    MultiMap queryParams = request.params();
    int[] pathParamsIndex = new int[] { pathParams.length };
    paramList.forEachRemaining(entry -> {
        if (validRequest[0]) {
            String valueName = ((JsonObject) entry.getValue()).getString("value");
            String valueType = ((JsonObject) entry.getValue()).getString("type");
            String paramType = ((JsonObject) entry.getValue()).getString("param_type");
            int order = ((JsonObject) entry.getValue()).getInteger("order");
            Object defaultVal = ((JsonObject) entry.getValue()).getValue("default_value");
            boolean emptyNumeircParam = false;
            // to their async upload - so explicitly skip them
            if (AnnotationGrabber.NON_ANNOTATED_PARAM.equals(paramType) && !FILE_UPLOAD_PARAM.equals(valueType)) {
                try {
                    // this will also validate the json against the pojo created from the schema
                    Class<?> entityClazz = Class.forName(valueType);
                    if (!valueType.equals("io.vertx.core.Handler") && !valueType.equals("io.vertx.core.Context") && !valueType.equals("java.util.Map") && !valueType.equals("java.io.InputStream") && !valueType.equals("io.vertx.ext.web.RoutingContext")) {
                        // we have special handling for the Result Handler and context, it is also assumed that
                        // an inputsteam parameter occurs when application/octet is declared in the raml
                        // in which case the content will be streamed to he function
                        String bodyContent = rc.getBodyAsString();
                        log.debug(rc.request().path() + " -------- bodyContent -------- " + bodyContent);
                        if (bodyContent != null) {
                            if ("java.io.Reader".equals(valueType)) {
                                paramArray[order] = new StringReader(bodyContent);
                            } else if (bodyContent.length() > 0) {
                                try {
                                    paramArray[order] = MAPPER.readValue(bodyContent, entityClazz);
                                } catch (UnrecognizedPropertyException e) {
                                    log.error(e.getMessage(), e);
                                    endRequestWithError(rc, RTFConsts.VALIDATION_ERROR_HTTP_CODE, true, JsonUtils.entity2String(ValidationHelper.createValidationErrorMessage("", "", e.getMessage())), validRequest);
                                    return;
                                }
                            }
                        }
                        Errors errorResp = new Errors();
                        if (!allowEmptyObject(entityClazz, bodyContent)) {
                            // right now - because no way in raml to make body optional - do not validate
                            // TenantAttributes object as it may be empty
                            // is this request only to validate a field value and not an actual
                            // request for additional processing
                            List<String> field2validate = request.params().getAll("validate_field");
                            Object[] resp = isValidRequest(rc, paramArray[order], errorResp, validRequest, field2validate, entityClazz);
                            boolean isValid = (boolean) resp[0];
                            paramArray[order] = resp[1];
                            if (!isValid) {
                                endRequestWithError(rc, RTFConsts.VALIDATION_ERROR_HTTP_CODE, true, JsonUtils.entity2String(errorResp), validRequest);
                                return;
                            } else if (isValid && !field2validate.isEmpty()) {
                                // valid request for the field to validate request made
                                AsyncResponseResult arr = new AsyncResponseResult();
                                ResponseImpl ri = new ResponseImpl();
                                ri.setStatus(200);
                                arr.setResult(ri);
                                // right now this is the only flag available to stop
                                // any additional respones for this request. to fix
                                validRequest[0] = false;
                                sendResponse(rc, arr, 0, null);
                                return;
                            }
                        }
                        // complex rules validation here (drools) - after simpler validation rules pass -
                        Error error = new Error();
                        FactHandle handle = null;
                        FactHandle handleError = null;
                        try {
                            // if no /rules exist then drools session will be null
                            if (droolsSession != null && paramArray[order] != null && validRequest[0]) {
                                // add object to validate to session
                                handle = droolsSession.insert(paramArray[order]);
                                handleError = droolsSession.insert(error);
                                // run all rules in session on object
                                droolsSession.fireAllRules();
                            }
                        } catch (Exception e) {
                            error.setCode("-1");
                            error.setType(RTFConsts.VALIDATION_FIELD_ERROR);
                            errorResp.getErrors().add(error);
                            endRequestWithError(rc, RTFConsts.VALIDATION_ERROR_HTTP_CODE, true, JsonUtils.entity2String(errorResp), validRequest);
                        } finally {
                            // remove the object from the session
                            if (handle != null) {
                                droolsSession.delete(handle);
                                droolsSession.delete(handleError);
                            }
                        }
                        populateMetaData(paramArray[order], okapiHeaders, rc.request().path());
                    }
                } catch (Exception e) {
                    log.error(e);
                    endRequestWithError(rc, 400, true, "Json content error " + e.getMessage(), validRequest);
                }
            } else if (AnnotationGrabber.HEADER_PARAM.equals(paramType)) {
                // handle header params - read the header field from the
                // header (valueName) and get its value
                String value = request.getHeader(valueName);
                // set the value passed from the header as a param to the function
                paramArray[order] = value;
            } else if (AnnotationGrabber.PATH_PARAM.equals(paramType)) {
                // these are placeholder values in the path - for example
                // /patrons/{patronid} - this would be the patronid value
                paramArray[order] = pathParams[pathParamsIndex[0] - 1];
                pathParamsIndex[0] = pathParamsIndex[0] - 1;
            } else if (AnnotationGrabber.QUERY_PARAM.equals(paramType)) {
                String param = queryParams.get(valueName);
                // support enum, numbers or strings as query parameters
                try {
                    if (valueType.contains("String")) {
                        // regular string param in query string - just push value
                        if (param == null && defaultVal != null) {
                            // no value passed - check if there is a default value
                            paramArray[order] = defaultVal;
                        } else {
                            paramArray[order] = param;
                        }
                    } else if (valueType.contains("int") || valueType.contains("Integer")) {
                        // cant pass null to an int type
                        if (param == null) {
                            if (defaultVal != null) {
                                paramArray[order] = Integer.valueOf((String) defaultVal);
                            } else {
                                paramArray[order] = 0;
                            }
                        } else if ("".equals(param)) {
                            emptyNumeircParam = true;
                        } else {
                            paramArray[order] = Integer.valueOf(param);
                        }
                    } else if (valueType.contains("boolean") || valueType.contains("Boolean")) {
                        if (param == null) {
                            if (defaultVal != null) {
                                paramArray[order] = Boolean.valueOf((String) defaultVal);
                            }
                        } else {
                            paramArray[order] = Boolean.valueOf(param);
                        }
                    } else if (valueType.contains("List")) {
                        List<String> vals = queryParams.getAll(valueName);
                        if (vals == null) {
                            paramArray[order] = null;
                        } else {
                            paramArray[order] = vals;
                        }
                    } else if (valueType.contains("BigDecimal")) {
                        if (param == null) {
                            if (defaultVal != null) {
                                paramArray[order] = new BigDecimal((String) defaultVal);
                            } else {
                                paramArray[order] = null;
                            }
                        } else if ("".equals(param)) {
                            emptyNumeircParam = true;
                        } else {
                            // big decimal can contain ","
                            paramArray[order] = new BigDecimal(param.replaceAll(",", ""));
                        }
                    } else {
                        // enum object type
                        try {
                            String enumClazz = replaceLast(valueType, ".", "$");
                            Class<?> enumClazz1 = Class.forName(enumClazz);
                            if (enumClazz1.isEnum()) {
                                Object defaultEnum = null;
                                Object[] vals = enumClazz1.getEnumConstants();
                                for (int i = 0; i < vals.length; i++) {
                                    if (vals[i].toString().equals(defaultVal)) {
                                        defaultEnum = vals[i];
                                    }
                                    // in case no value was passed in the request
                                    if (param == null && defaultEnum != null) {
                                        paramArray[order] = defaultEnum;
                                        break;
                                    } else // make sure enum value is valid by converting the string to an enum
                                    if (vals[i].toString().equals(param)) {
                                        paramArray[order] = vals[i];
                                        break;
                                    }
                                    if (i == vals.length - 1) {
                                        // if enum passed is not valid, replace with default value
                                        paramArray[order] = defaultEnum;
                                    }
                                }
                            }
                        } catch (Exception ee) {
                            log.error(ee.getMessage(), ee);
                            endRequestWithError(rc, 400, true, ee.getMessage(), validRequest);
                        }
                    }
                    if (emptyNumeircParam) {
                        endRequestWithError(rc, 400, true, valueName + " does not have a default value in the RAML and has been passed empty", validRequest);
                    }
                } catch (Exception e) {
                    log.error(e.getMessage(), e);
                    endRequestWithError(rc, 400, true, e.getMessage(), validRequest);
                }
            }
        }
    });
}
Also used : FactHandle(org.kie.api.runtime.rule.FactHandle) HttpServerRequest(io.vertx.core.http.HttpServerRequest) JsonObject(io.vertx.core.json.JsonObject) UnrecognizedPropertyException(com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException) Error(org.folio.rest.jaxrs.model.Error) ResponseImpl(org.folio.rest.tools.utils.ResponseImpl) UnrecognizedPropertyException(com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException) MessagingException(javax.mail.MessagingException) IOException(java.io.IOException) BigDecimal(java.math.BigDecimal) MultiMap(io.vertx.core.MultiMap) Errors(org.folio.rest.jaxrs.model.Errors) StringReader(java.io.StringReader) AsyncResponseResult(org.folio.rest.tools.utils.AsyncResponseResult) JsonObject(io.vertx.core.json.JsonObject)

Aggregations

UnrecognizedPropertyException (com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException)1 MultiMap (io.vertx.core.MultiMap)1 HttpServerRequest (io.vertx.core.http.HttpServerRequest)1 JsonObject (io.vertx.core.json.JsonObject)1 IOException (java.io.IOException)1 StringReader (java.io.StringReader)1 BigDecimal (java.math.BigDecimal)1 MessagingException (javax.mail.MessagingException)1 Error (org.folio.rest.jaxrs.model.Error)1 Errors (org.folio.rest.jaxrs.model.Errors)1 AsyncResponseResult (org.folio.rest.tools.utils.AsyncResponseResult)1 ResponseImpl (org.folio.rest.tools.utils.ResponseImpl)1 FactHandle (org.kie.api.runtime.rule.FactHandle)1