@Override public Response toResponse(IllegalArgumentException e) { exceptions.mark(); if (e.getMessage().matches("Resource .* not found!")) { return Response .status(Response.Status.NOT_FOUND) // 404 .type(MediaType.APPLICATION_JSON_TYPE) .entity(new ErrorMessage(Response.Status.UNAUTHORIZED.getStatusCode(), e.getMessage())) .build(); } return Response .status(422) // UNPROCESSABLE_ENTITY .type(MediaType.APPLICATION_JSON_TYPE) .entity(new ErrorMessage(422, e.getMessage())) .build(); }
@POST public Response translateResponse(@NotNull @Valid TranslateSamlResponseBody translateSamlResponseBody) throws IOException { String entityId = entityIdService.getEntityId(translateSamlResponseBody); try { TranslatedResponseBody translatedResponseBody = responseService.convertTranslatedResponseBody( translateSamlResponseBody.getSamlResponse(), translateSamlResponseBody.getRequestId(), translateSamlResponseBody.getLevelOfAssurance(), entityId ); LOG.info(String.format("Translated response for entityId: %s, requestId: %s, got Scenario: %s", entityId, translateSamlResponseBody.getRequestId(), translatedResponseBody.getScenario())); return Response.ok(translatedResponseBody).build(); } catch (SamlResponseValidationException | SamlTransformationErrorException e) { LOG.warn(String.format("Error translating saml response for entityId: %s, requestId: %s, got Message: %s", entityId, translateSamlResponseBody.getRequestId(), e.getMessage())); return Response .status(BAD_REQUEST) .entity(new ErrorMessage(BAD_REQUEST.getStatusCode(), e.getMessage())) .build(); } }
@Test public void shouldReturnAnErrorWhenTranslatingLowerLoAThanRequested() { RequestResponseBody requestResponseBody = generateRequestService.generateAuthnRequest(application.getLocalPort()); Map<String, String> translateResponseRequestData = ImmutableMap.of( "samlResponse", complianceTool.createResponseFor(requestResponseBody.getSamlRequest(), BASIC_SUCCESSFUL_MATCH_WITH_LOA1_ID), "requestId", requestResponseBody.getRequestId(), "levelOfAssurance", LEVEL_2.name() ); Response response = client .target(String.format("http://localhost:%d/translate-response", application.getLocalPort())) .request() .buildPost(json(translateResponseRequestData)) .invoke(); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); ErrorMessage errorMessage = response.readEntity(ErrorMessage.class); assertThat(errorMessage.getCode()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(errorMessage.getMessage()).isEqualTo("Expected Level of Assurance to be at least LEVEL_2, but was LEVEL_1"); }
@Test public void shouldReturnAnErrorWhenInvalidEntityIdProvided() { RequestResponseBody requestResponseBody = generateRequestService.generateAuthnRequest(application.getLocalPort()); Map<String, String> translateResponseRequestData = ImmutableMap.of( "samlResponse", complianceTool.createResponseFor(requestResponseBody.getSamlRequest(), BASIC_SUCCESSFUL_MATCH_WITH_LOA2_ID), "requestId", requestResponseBody.getRequestId(), "levelOfAssurance", LEVEL_2.name(), "entityId", "invalidEntityId" ); Response response = client .target(String.format("http://localhost:%d/translate-response", application.getLocalPort())) .request() .buildPost(json(translateResponseRequestData)) .invoke(); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); ErrorMessage errorMessage = response.readEntity(ErrorMessage.class); assertThat(errorMessage.getCode()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(errorMessage.getMessage()).isEqualTo("Provided entityId: invalidEntityId is not listed in config"); }
@Test public void shouldReturn400IfNoEntityIdProvided() { complianceTool.initialiseWithEntityIdAndPid(configuredEntityIdOne, "some-expected-pid"); RequestResponseBody requestResponseBody = generateRequestService.generateAuthnRequest(application.getLocalPort(), configuredEntityIdOne); Map<String, String> translateResponseRequestData = ImmutableMap.of( "samlResponse", complianceTool.createResponseFor(requestResponseBody.getSamlRequest(), BASIC_SUCCESSFUL_MATCH_WITH_LOA2_ID), "requestId", requestResponseBody.getRequestId(), "levelOfAssurance", LEVEL_2.name() ); Response response = client .target(String.format("http://localhost:%d/translate-response", application.getLocalPort())) .request() .buildPost(json(translateResponseRequestData)) .invoke(); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(response.readEntity(ErrorMessage.class).getMessage()).isEqualTo("No entityId was provided, and there are several in config"); }
@Test public void shouldReturn400IfIncorrectEntityIdProvided() { complianceTool.initialiseWithEntityIdAndPid(configuredEntityIdTwo, "some-expected-pid"); RequestResponseBody requestResponseBody = generateRequestService.generateAuthnRequest(application.getLocalPort(), configuredEntityIdTwo); Map<String, String> translateResponseRequestData = ImmutableMap.of( "samlResponse", complianceTool.createResponseFor(requestResponseBody.getSamlRequest(), BASIC_SUCCESSFUL_MATCH_WITH_LOA2_ID), "requestId", requestResponseBody.getRequestId(), "levelOfAssurance", LEVEL_2.name(), "entityId", "http://incorrect-entity-id" ); Response response = client .target(String.format("http://localhost:%d/translate-response", application.getLocalPort())) .request() .buildPost(json(translateResponseRequestData)) .invoke(); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(response.readEntity(ErrorMessage.class).getMessage()).isEqualTo("Provided entityId: http://incorrect-entity-id is not listed in config"); }
@Test public void shouldRespondWithErrorWhenAssertionSignedByHub() { RequestResponseBody requestResponseBody = generateRequestService.generateAuthnRequest(application.getLocalPort()); Map<String, String> translateResponseRequestData = ImmutableMap.of( "samlResponse", complianceTool.createResponseFor(requestResponseBody.getSamlRequest(), BASIC_SUCCESSFUL_MATCH_WITH_ASSERTIONS_SIGNED_BY_HUB_ID), "requestId", requestResponseBody.getRequestId(), "levelOfAssurance", LEVEL_2.name() ); Response response = client .target(String.format("http://localhost:%d/translate-response", application.getLocalPort())) .request() .buildPost(json(translateResponseRequestData)) .invoke(); ErrorMessage errorBody = response.readEntity(ErrorMessage.class); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(errorBody.getCode()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(errorBody.getMessage()).contains("SAML Validation Specification: Signature was not valid."); }
@Test public void shouldReturn400WhenSamlValidationExceptionThrown() throws Exception { JSONObject translateResponseRequest = new JSONObject().put("samlResponse", "some-saml-response") .put("requestId", "some-request-id") .put("levelOfAssurance", LEVEL_2.name()); when(responseService.convertTranslatedResponseBody(any(), eq("some-request-id"), eq(LEVEL_2), eq(defaultEntityId))) .thenThrow(new SamlResponseValidationException("Some error.")); Response response = resources.client() .target("/translate-response") .request() .post(json(translateResponseRequest.toString())); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); ErrorMessage actualError = response.readEntity(ErrorMessage.class); assertThat(actualError.getCode()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(actualError.getMessage()).isEqualTo("Some error."); }
@Test public void shouldReturn400WhenSamlTransformationErrorExceptionThrown() throws Exception { JSONObject translateResponseRequest = new JSONObject().put("samlResponse", "some-saml-response") .put("requestId", "some-request-id") .put("levelOfAssurance", LEVEL_2.name()); when(responseService.convertTranslatedResponseBody(any(), eq("some-request-id"), eq(LEVEL_2), eq(defaultEntityId))) .thenThrow(new SamlTransformationErrorException("Some error.", Level.ERROR)); Response response = resources.client() .target("/translate-response") .request() .post(json(translateResponseRequest.toString())); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); ErrorMessage actualError = response.readEntity(ErrorMessage.class); assertThat(actualError.getCode()).isEqualTo(BAD_REQUEST.getStatusCode()); assertThat(actualError.getMessage()).isEqualTo("Some error."); }
@Test public void shouldReturn400WhenCalledWithEmptyJson() throws Exception { Response response = resources.client() .target("/translate-response") .request() .post(json("{}")); assertThat(response.getStatus()).isEqualTo(HttpStatus.SC_UNPROCESSABLE_ENTITY); ErrorMessage actualErrorMessage = response.readEntity(ErrorMessage.class); assertThat(actualErrorMessage.getCode()).isEqualTo(HttpStatus.SC_UNPROCESSABLE_ENTITY); Set<String> expectedErrors = ImmutableSet.of("requestId may not be null", "samlResponse may not be null", "levelOfAssurance may not be null"); Set<String> actualErrors = Arrays.stream(actualErrorMessage.getMessage().split(", ")).collect(Collectors.toSet()); assertThat(actualErrors).isEqualTo(expectedErrors); }
@GET @Path("/{runId}") @UnitOfWork @ApiOperation(value = "Get a specific run") @ApiResponses({ @ApiResponse(code = HttpStatus.OK_200, response = RunApiEntity.class, message = "OK"), @ApiResponse(code = HttpStatus.NOT_FOUND_404, response = ErrorMessage.class, message = "Not found"), @ApiResponse( code = HttpStatus.CONFLICT_409, response = ErrorMessage.class, message = "Event ID and Run ID are mismatched" ) }) public RunApiEntity getRun( @PathParam("eventId") @ApiParam(value = "Event ID", required = true) String eventId, @PathParam("runId") @ApiParam(value = "Run ID", required = true) String runId ) throws EntityMismatchException, EntityNotFoundException { Run domainRun = runEntityService.getByEventIdAndRunId(eventId, runId); return runMapper.toApiEntity(domainRun); }
@GET @Path("/{registrationId}") @UnitOfWork @ApiOperation(value = "Get a specific registration") @ApiResponses({ @ApiResponse(code = HttpStatus.OK_200, response = RegistrationApiEntity.class, message = "OK"), @ApiResponse(code = HttpStatus.NOT_FOUND_404, response = ErrorMessage.class, message = "Not found"), @ApiResponse( code = HttpStatus.CONFLICT_409, response = ErrorMessage.class, message = "Event ID and Registration ID are mismatched" ) }) public RegistrationApiEntity getRegistration( @PathParam("eventId") @ApiParam(value = "Event ID", required = true) String eventId, @PathParam("registrationId") @ApiParam(value = "Registration ID", required = true) String registrationId ) throws EntityMismatchException, EntityNotFoundException { Registration domainRegistration = eventRegistrationService.getByEventIdAndRegistrationId( eventId, registrationId ); return registrationMapper.toApiEntity(domainRegistration); }
@POST @Path("/{handicapGroupSetId}/handicapGroups/{handicapGroupId}") @UnitOfWork @ApiOperation(value = "Add a Handicap Group to a Handicap Group Set", response = HandicapGroupSetApiEntity.class) @ApiResponses({ @ApiResponse(code = HttpStatus.OK_200, response = HandicapGroupSetApiEntity.class, message = "OK"), @ApiResponse(code = HttpStatus.NOT_FOUND_404, response = ErrorMessage.class, message = "Not found"), }) public HandicapGroupSetApiEntity addHandicapGroupToHandicapGroupSet( @PathParam("handicapGroupSetId") @ApiParam(value = "Handicap Group Set ID", required = true) String handicapGroupSetId, @PathParam("handicapGroupId") @ApiParam(value = "Handicap Group ID", required = true) String handicapGroupId ) throws EntityNotFoundException { HandicapGroupSet domainSetEntity = handicapGroupSetService.getById(handicapGroupSetId); HandicapGroup domainEntity = handicapGroupEntityService.getById(handicapGroupId); handicapGroupSetService.addToHandicapGroups(domainSetEntity, domainEntity); return handicapGroupSetMapper.toApiEntity(domainSetEntity); }
@POST @Path("/{competitionGroupSetId}/competitionGroups/{competitionGroupId}") @UnitOfWork @ApiOperation( value = "Add a Competition Group to a Competition Group Set", response = CompetitionGroupSetApiEntity.class ) @ApiResponses({ @ApiResponse(code = HttpStatus.OK_200, response = CompetitionGroupSetApiEntity.class, message = "OK"), @ApiResponse(code = HttpStatus.NOT_FOUND_404, response = ErrorMessage.class, message = "Not found"), }) public CompetitionGroupSetApiEntity addCompetitionGroupToCompetitionGroupSet( @PathParam("competitionGroupSetId") @ApiParam(value = "Competition Group Set ID", required = true) String competitionGroupSetId, @PathParam("competitionGroupId") @ApiParam(value = "Competition Group ID", required = true) String competitionGroupId ) throws EntityNotFoundException { CompetitionGroupSet domainSetEntity = competitionGroupSetService.getById(competitionGroupSetId); CompetitionGroup domainEntity = competitionGroupEntityService.getById(competitionGroupId); competitionGroupSetService.addToCompetitionGroups(domainSetEntity, domainEntity); return competitionGroupSetMapper.toApiEntity(domainSetEntity); }
@Test public void itShouldFailToAddRunWhenMapperThrowsRuntimeExceptionWrappingEntityNotFoundException() { AddRunRequest apiRequest = ApiRequestTestUtils.fullAddRun(); Entity<AddRunRequest> requestEntity = Entity.json(apiRequest); when(runMapper.toDomainAddPayload(apiRequest, EVENT_ID)) .thenThrow(new RuntimeException(new EntityNotFoundException(Event.class, EVENT_ID))); Response response = resources.client() .target(UriBuilder.fromPath("/events/{eventId}/runs").build(EVENT_ID)) .request(MediaType.APPLICATION_JSON_TYPE) .post(requestEntity); verifyZeroInteractions(runEntityService); assertThat(response).isNotNull(); assertThat(response.getStatus()).isEqualTo(HttpStatus.NOT_FOUND_404); assertThat(response.readEntity(ErrorMessage.class)) .extracting(ErrorMessage::getCode, ErrorMessage::getMessage) .containsExactly(HttpStatus.NOT_FOUND_404, "Event entity not found with id " + EVENT_ID); }
@Test public void getMatchingService_returnsInternalServerError(){ String entityId = "not-found"; URI uri = configAppRule.getUri(Urls.ConfigUrls.MATCHING_SERVICE_RESOURCE).buildFromEncoded(StringEncoding.urlEncode(entityId).replace("+", "%20")); Response response = client.target(uri.toASCIIString()).request().get(); assertThat(response.getStatus()).isEqualTo(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); assertThat(response.readEntity(ErrorMessage.class).getMessage()).contains("There was an error processing your request."); }
@Override public Response toResponse(InvalidCredentialsException e) { exceptions.mark(); return Response .status(422) // UNPROCESSABLE_ENTITY .type(MediaType.APPLICATION_JSON_TYPE) .entity(new ErrorMessage(422, e.getMessage())) .build(); }
@Override public Response toResponse(AuthorizationException e) { exceptions.mark(); return Response .status(Response.Status.FORBIDDEN) .type(MediaType.APPLICATION_JSON_TYPE) .entity(new ErrorMessage(Response.Status.FORBIDDEN.getStatusCode(), null)) .build(); }
@Override public Response toResponse(NotAuthenticatedException e) { exceptions.mark(); return Response .status(Response.Status.UNAUTHORIZED) .type(MediaType.APPLICATION_JSON_TYPE) .entity(new ErrorMessage(Response.Status.UNAUTHORIZED.getStatusCode(), e.getMessage())) .build(); }
@Override public Response toResponse(JsonProcessingException exception) { LOG.warn(String.format("Unable to parse json in request body. %s", exception.getOriginalMessage())); return Response .status(HttpStatus.SC_UNPROCESSABLE_ENTITY) .entity(new ErrorMessage(HttpStatus.SC_UNPROCESSABLE_ENTITY, exception.getOriginalMessage())) .build(); }
@Override public Response toResponse(InvalidEntityIdException exception) { LOG.warn(String.format("Request invalid for this service provider. %s", exception.getMessage())); return Response .status(HttpStatus.SC_BAD_REQUEST) .entity(new ErrorMessage(HttpStatus.SC_BAD_REQUEST, exception.getMessage())) .build(); }
@Override public Response toResponse(JerseyViolationException exception) { final String errors = exception.getConstraintViolations() .stream().map(violation -> ConstraintMessage.getMessage(violation, exception.getInvocable())) .collect(Collectors.joining(", ")); LOG.warn(String.format("Request body was not valid: %s", errors)); return Response .status(HttpStatus.SC_UNPROCESSABLE_ENTITY) .entity(new ErrorMessage(HttpStatus.SC_UNPROCESSABLE_ENTITY, errors)) .build(); }
@Test public void shouldErrorIfOnlyVerifiedIsRequested() { Response response = getResponse(LEVEL_2, "DATE_OF_BIRTH_VERIFIED"); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); ErrorMessage errorResponse = response.readEntity(ErrorMessage.class); assertThat(errorResponse.getMessage()).isEqualTo("Invalid attributes request: Cannot request verification status without requesting attribute value"); }
@Test public void shouldErrorIfVerifiedIsNotRequested() { Response response = getResponse(LEVEL_2, "SURNAME"); assertThat(response.getStatus()).isEqualTo(BAD_REQUEST.getStatusCode()); ErrorMessage errorResponse = response.readEntity(ErrorMessage.class); assertThat(errorResponse.getMessage()).isEqualTo("Invalid attributes request: Cannot request attribute without requesting verification status. Please check your MSA configuration settings."); }
@Test public void returns422ForBadJson() { Response response = resources.target("/generate-request") .request() .post(Entity.entity("{}", MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(422); assertThat(response.readEntity(ErrorMessage.class)).isEqualTo(new ErrorMessage( 422, "levelOfAssurance may not be null") ); }
@Test public void returns422ForMalformedJson() { Response response = resources.target("/generate-request") .request() .post(Entity.entity("this is not json", MediaType.APPLICATION_JSON_TYPE)); assertThat(response.getStatus()).isEqualTo(422); assertThat(response.readEntity(ErrorMessage.class)).isEqualTo(new ErrorMessage( 422, "Unrecognized token 'this': was expecting 'null', 'true', 'false' or NaN") ); }
@Test public void returns500IfARuntimeExceptionIsThrown() { when(authnRequestFactory.build(any(), any())).thenThrow(RuntimeException.class); RequestGenerationBody requestGenerationBody = new RequestGenerationBody(LevelOfAssurance.LEVEL_2, null); Response response = resources.target("/generate-request").request().post(Entity.entity(requestGenerationBody, MediaType.APPLICATION_JSON_TYPE)); ErrorMessage responseEntity = response.readEntity(ErrorMessage.class); assertThat(responseEntity.getCode()).isEqualTo(500); assertThat(responseEntity.getMessage()).contains("There was an error processing your request. It has been logged (ID"); assertThat(responseEntity.getDetails()).isNullOrEmpty(); }
private void throwError(int statusCode, String msg){ ErrorMessage errorMessage = new ErrorMessage(statusCode, msg); throw new WebApplicationException(errorMessage.getMessage(), Response.status(statusCode) .entity(errorMessage) .type(MediaType.APPLICATION_JSON). build()); }
@Override public Response toResponse(DataException e) { LOGGER.error("Hibernate error", e); String message = e.getCause().getMessage().contains("EMAIL") ? "Wrong email" : "Wrong input"; return Response.status(Response.Status.BAD_REQUEST) .entity(new ErrorMessage(Response.Status.BAD_REQUEST.getStatusCode(), message)) .build(); }
@PATCH @RolesAllowed(Roles.EDIT) @Path("services/application/{id}") @ApiOperation(value = "Update application") @ApiResponses({ @ApiResponse(code = 200, message = "The application was successfully updated.", response = ApplicationLink.class), @ApiResponse(code = 404, message = "No application exists with the supplied id.", response = ErrorMessage.class), @ApiResponse(code = 412, message = "No application exists with the supplied id and hash.", response = ErrorMessage.class), @ApiResponse(code = 422, message = "The supplied application is not valid.", response = ErrorMessage.class), }) public Response updateApplication( @ApiParam("Application id") @PathParam("id") String id, @ApiParam("Application") Application application, @ApiParam("The number of levels to merge this update") @QueryParam("mergedepth") @DefaultValue(RestHelper.INTEGER_MAX) int mergeDepth, @Context UriInfo uriInfo, @Context Request request, @Context SecurityContext securityContext ) throws IOException { logger.info("Update application: {}", application); RestHelper.validate(application, Application.Update.class); final Document existing = getApplicationForUpdate(id); final MongoCollection<Document> collection = database.getCollection(Collections.APPLICATIONS); final Document updated = RestHelper.mergeAndUpdateMeta(existing, application, mergeDepth, collection, objectMapper, securityContext, request); return linkResponse(Status.OK, updated, uriInfo); }
@PUT @Path("services/group/{id}/group/{subGroupId}") @RolesAllowed(Roles.EDIT) @ApiOperation("Add an existing sub group to a group.") @ApiResponses({ @ApiResponse(code = 200, message = "The subgroup was successfully added to the group.", response = GroupLink.class), @ApiResponse(code = 404, message = "No group exists with the supplied id.", response = ErrorMessage.class), @ApiResponse(code = 412, message = "No group exists with the supplied id and hash.", response = ErrorMessage.class), @ApiResponse(code = 422, message = "The supplied subgroup id is not valid.", response = ErrorMessage.class), }) public Response addSubGroup( @ApiParam("Group id") @PathParam("id") String groupId, @ApiParam("Subgroup id") @PathParam("subGroupId") String subGroupId, @Context UriInfo uriInfo, @Context Request request, @Context SecurityContext securityContext ) { logger.info("Add subgroup {} to {}", subGroupId, groupId); final Document existing = getGroupForUpdate(groupId); final Optional<String> hash = RestHelper.verifyHash(existing, request); final Document update = JsonHelper.entityToBson(new Group(subGroupId), objectMapper); Mapper.upsertList(existing, update, "groups", (item) -> item.get("id").equals(subGroupId)); final User user = RestHelper.getUser(securityContext); JsonHelper.updateMetaForUpdate(existing, hash, user.name); MongoHelper.updateDocument(existing, existing, hash, database.getCollection(Collections.GROUPS)); return linkResponse(Status.OK, existing, uriInfo); }
@PATCH @RolesAllowed(Roles.EDIT) @Path("services/group/{id}") @ApiOperation(value = "Update group") @ApiResponses({ @ApiResponse(code = 200, message = "The group was successfully updated.", response = GroupLink.class), @ApiResponse(code = 404, message = "No group exists with the supplied id.", response = ErrorMessage.class), @ApiResponse(code = 412, message = "No group exists with the supplied id and hash.", response = ErrorMessage.class), @ApiResponse(code = 422, message = "The supplied group is not valid.", response = ErrorMessage.class), }) public Response updateGroup( @ApiParam("Group id") @PathParam("id") String id, @ApiParam("Group") Group group, @ApiParam("The number of levels to merge this update") @QueryParam("mergedepth") @DefaultValue(RestHelper.INTEGER_MAX) int mergeDepth, @Context UriInfo uriInfo, @Context Request request, @Context SecurityContext securityContext ) throws IOException { logger.info("Update group: {}", group); RestHelper.validate(group, Group.Update.class); final Document existing = getGroupForUpdate(id); final MongoCollection<Document> collection = database.getCollection(Collections.GROUPS); final Document updated = RestHelper.mergeAndUpdateMeta(existing, group, mergeDepth, collection, objectMapper, securityContext, request); return linkResponse(Status.OK, updated, uriInfo); }
@DELETE @Path("services/group/{id}/group/{subGroupId}") @RolesAllowed(Roles.EDIT) @ApiOperation("Remove sub group") @ApiResponses({ @ApiResponse(code = 200, message = "The subgroup was successfully removed from the group.", response = GroupLink.class), @ApiResponse(code = 404, message = "No group exists with the supplied id.", response = ErrorMessage.class), @ApiResponse(code = 412, message = "No group exists with the supplied id and hash.", response = ErrorMessage.class), @ApiResponse(code = 422, message = "The supplied subgroup id is not valid.", response = ErrorMessage.class), }) public Response removeSubGroup( @ApiParam("Group id") @PathParam("id") String groupId, @ApiParam("Subgroup id") @PathParam("subGroupId") String subGroupId, @Context UriInfo uriInfo, @Context Request request, @Context SecurityContext securityContext ) { logger.info("Remove subgroup {} from {}", subGroupId, groupId); final Document existing = getGroupForUpdate(groupId); final Optional<String> hash = RestHelper.verifyHash(existing, request); Mapper.removeFromList(existing, "groups", (item) -> item.get("id").equals(subGroupId)); final User user = RestHelper.getUser(securityContext); JsonHelper.updateMetaForUpdate(existing, hash, user.name); MongoHelper.updateDocument(existing, existing, hash, database.getCollection(Collections.GROUPS)); return linkResponse(Status.OK, existing, uriInfo); }
@PUT @Path("services/server/{environment}/{hostname}/deployment/{applicationId}") @RolesAllowed(Roles.EDIT) @ApiOperation(value = "Add a deployed applications to the server", response = ServerLink.class) @ApiResponses({ @ApiResponse(code = 200, message = "The deployment was successfully added to the server.", response = ServerLink.class), @ApiResponse(code = 404, message = "No server exists with the supplied environment and hostname.", response = ErrorMessage.class), @ApiResponse(code = 412, message = "No server exists with the supplied environment, hostname and hash.", response = ErrorMessage.class), @ApiResponse(code = 422, message = "The supplied deployment is not valid.", response = ErrorMessage.class), }) public Response addDeployment( @ApiParam("Server hostname") @PathParam("hostname") String hostname, @ApiParam("Environment") @PathParam("environment") String environment, @ApiParam("Application id") @PathParam("applicationId") String applicationId, @ApiParam("Deployment") Deployment deployment, @Context UriInfo uriInfo, @Context Request request, @Context SecurityContext securityContext ) { logger.info("Add deployment: {} to {}@{}, {}", applicationId, hostname, environment, deployment); RestHelper.validate(deployment); final Document existing = getServerForUpdate(hostname, environment); final Optional<String> hash = RestHelper.verifyHash(existing, request); final Document update = JsonHelper.entityToBson(deployment, objectMapper); Mapper.upsertList(existing, update, "deployments", (item) -> item.get("applicationId").equals(applicationId)); final User user = RestHelper.getUser(securityContext); JsonHelper.updateMetaForUpdate(existing, hash, user.name); MongoHelper.updateDocument(existing, existing, hash, database.getCollection(Collections.SERVERS)); return linkResponse(Status.OK, existing, uriInfo); }