Search in sources :

Example 6 with Errors

use of org.folio.rest.jaxrs.model.Errors in project raml-module-builder by folio-org.

the class ValidationHelperTest method dupMsgTest.

@Test
public void dupMsgTest(TestContext context) {
    Async async = context.async();
    String msg = "duplicate _id value violates unique constraint: 55835c7c-2885-44f4-96ac-f03525b8e608";
    Throwable t = new PgException("duplicate key value violates unique constraint \"123456\"", null, "23505", "Key (_id)=(55835c7c-2885-44f4-96ac-f03525b8e608) already exists.");
    ValidationHelper.handleError(t, r -> {
        String responseMsg = ((Errors) r.result().getEntity()).getErrors().get(0).getMessage();
        context.assertEquals(msg, responseMsg);
        async.complete();
    });
}
Also used : Errors(org.folio.rest.jaxrs.model.Errors) Async(io.vertx.ext.unit.Async) PgException(io.vertx.pgclient.PgException) Test(org.junit.Test)

Example 7 with Errors

use of org.folio.rest.jaxrs.model.Errors 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)

Example 8 with Errors

use of org.folio.rest.jaxrs.model.Errors in project raml-module-builder by folio-org.

the class PgUtilIT method responseUniqueViolationNoMatch422.

@Test
public void responseUniqueViolationNoMatch422(TestContext testContext) throws Exception {
    Exception genericDatabaseException = new PgException("", null, "", "fooMessage");
    PgExceptionFacade exception = new PgExceptionFacade(genericDatabaseException);
    Method respond400 = ResponseImpl.class.getMethod("respond400WithTextPlain", Object.class);
    Method respond500 = ResponseImpl.class.getMethod("respond500WithTextPlain", Object.class);
    Method respond422 = PgUtil.respond422method(ResponseWith422.class);
    Future<Response> future = PgUtil.responseUniqueViolation("mytable", "myid", exception, respond422, respond400, respond500);
    assertTrue(future.succeeded());
    assertThat(future.result().getStatus(), is(422));
    Errors errors = (Errors) future.result().getEntity();
    assertThat(errors.getErrors().get(0).getMessage(), containsString("fooMessage"));
}
Also used : Response(javax.ws.rs.core.Response) PostUsersResponse(org.folio.rest.jaxrs.model.Users.PostUsersResponse) Errors(org.folio.rest.jaxrs.model.Errors) Method(java.lang.reflect.Method) PgException(io.vertx.pgclient.PgException) ExpectedException(org.junit.rules.ExpectedException) PgException(io.vertx.pgclient.PgException) Test(org.junit.Test)

Example 9 with Errors

use of org.folio.rest.jaxrs.model.Errors in project raml-module-builder by folio-org.

the class PgUtilIT method postDuplicateId422.

@Test
public void postDuplicateId422(TestContext testContext) {
    String uuid = randomUuid();
    post(testContext, "Snow-White", uuid, 201);
    PgUtil.post("users", new User().withUsername("Rose-Red").withId(uuid), okapiHeaders, vertx.getOrCreateContext(), ResponseWith422.class, asyncAssertSuccess(testContext, 422, response -> {
        Errors errors = (Errors) response.result().getEntity();
        assertThat(errors.getErrors(), hasSize(1));
        Error error = errors.getErrors().get(0);
        assertThat(error.getMessage(), containsString("id value already exists in table users: " + uuid));
        assertThat(error.getParameters(), hasSize(1));
        assertThat(error.getParameters().get(0).getKey(), is("id"));
        assertThat(error.getParameters().get(0).getValue(), is(uuid));
    }));
}
Also used : TestContext(io.vertx.ext.unit.TestContext) CoreMatchers(org.hamcrest.CoreMatchers) Arrays(java.util.Arrays) XOkapiHeaders(org.folio.okapi.common.XOkapiHeaders) RoutingContext(io.vertx.ext.web.RoutingContext) VertxUtils(org.folio.rest.tools.utils.VertxUtils) Users(org.folio.rest.jaxrs.model.Users) User(org.folio.rest.jaxrs.model.User) Map(java.util.Map) UtilityClassTester(org.folio.okapi.testing.UtilityClassTester) JsonObject(io.vertx.core.json.JsonObject) Method(java.lang.reflect.Method) Errors(org.folio.rest.jaxrs.model.Errors) AfterClass(org.junit.AfterClass) UUID(java.util.UUID) Future(io.vertx.core.Future) IsCollectionWithSize.hasSize(org.hamcrest.collection.IsCollectionWithSize.hasSize) List(java.util.List) Response(javax.ws.rs.core.Response) Buffer(io.vertx.core.buffer.Buffer) PostUsersResponse(org.folio.rest.jaxrs.model.Users.PostUsersResponse) Mockito.mock(org.mockito.Mockito.mock) PgException(io.vertx.pgclient.PgException) Strictness(org.mockito.quality.Strictness) Async(io.vertx.ext.unit.Async) Json(io.vertx.core.json.Json) RestVerticle(org.folio.rest.RestVerticle) BeforeClass(org.junit.BeforeClass) PostgresTesterContainer(org.folio.postgres.testing.PostgresTesterContainer) RunWith(org.junit.runner.RunWith) SchemaMaker(org.folio.rest.persist.ddlgen.SchemaMaker) Mockito.timeout(org.mockito.Mockito.timeout) Answer(org.mockito.stubbing.Answer) ResponseDelegate(org.folio.rest.jaxrs.resource.support.ResponseDelegate) Timeout(org.junit.rules.Timeout) Referencing(org.folio.rest.jaxrs.model.Referencing) MockitoJUnit(org.mockito.junit.MockitoJUnit) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) AsyncResult(io.vertx.core.AsyncResult) Mockito.anyString(org.mockito.Mockito.anyString) ExpectedException(org.junit.rules.ExpectedException) Matchers.greaterThanOrEqualTo(org.hamcrest.Matchers.greaterThanOrEqualTo) Vertx(io.vertx.core.Vertx) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) AssertionFailedError(junit.framework.AssertionFailedError) Mockito.when(org.mockito.Mockito.when) VertxUnitRunner(io.vertx.ext.unit.junit.VertxUnitRunner) UserdataCollection(org.folio.rest.jaxrs.model.UserdataCollection) Mockito.verify(org.mockito.Mockito.verify) Error(org.folio.rest.jaxrs.model.Error) Mockito(org.mockito.Mockito) Rule(org.junit.Rule) TreeMap(java.util.TreeMap) MockitoRule(org.mockito.junit.MockitoRule) Handler(io.vertx.core.Handler) Collections(java.util.Collections) Errors(org.folio.rest.jaxrs.model.Errors) User(org.folio.rest.jaxrs.model.User) AssertionFailedError(junit.framework.AssertionFailedError) Error(org.folio.rest.jaxrs.model.Error) Mockito.anyString(org.mockito.Mockito.anyString) Test(org.junit.Test)

Example 10 with Errors

use of org.folio.rest.jaxrs.model.Errors in project raml-module-builder by folio-org.

the class RestRoutingTest method isValidRequestFail.

@Test
void isValidRequestFail() {
    Errors errors = new Errors();
    RestRouting.isValidRequest(null, new Foo(null, null), errors, List.of(), null);
    assertThat(errors.getErrors().get(0).getCode(), is("javax.validation.constraints.NotNull.message"));
}
Also used : Errors(org.folio.rest.jaxrs.model.Errors) Test(org.junit.jupiter.api.Test)

Aggregations

Errors (org.folio.rest.jaxrs.model.Errors)14 Test (org.junit.Test)7 PgException (io.vertx.pgclient.PgException)6 Method (java.lang.reflect.Method)6 Response (javax.ws.rs.core.Response)6 JsonObject (io.vertx.core.json.JsonObject)5 Error (org.folio.rest.jaxrs.model.Error)5 PostUsersResponse (org.folio.rest.jaxrs.model.Users.PostUsersResponse)5 ExpectedException (org.junit.rules.ExpectedException)5 Async (io.vertx.ext.unit.Async)4 AsyncResult (io.vertx.core.AsyncResult)3 Future (io.vertx.core.Future)3 Handler (io.vertx.core.Handler)3 Vertx (io.vertx.core.Vertx)3 Buffer (io.vertx.core.buffer.Buffer)3 Json (io.vertx.core.json.Json)3 TestContext (io.vertx.ext.unit.TestContext)3 VertxUnitRunner (io.vertx.ext.unit.junit.VertxUnitRunner)3 RoutingContext (io.vertx.ext.web.RoutingContext)3 Arrays (java.util.Arrays)3