diff --git a/src/main/java/com/redhat/labs/lodestar/exception/mapper/LodeStarGitLabAPIServiceResponseMapper.java b/src/main/java/com/redhat/labs/lodestar/exception/mapper/LodeStarGitLabAPIServiceResponseMapper.java index af091885..5509b261 100644 --- a/src/main/java/com/redhat/labs/lodestar/exception/mapper/LodeStarGitLabAPIServiceResponseMapper.java +++ b/src/main/java/com/redhat/labs/lodestar/exception/mapper/LodeStarGitLabAPIServiceResponseMapper.java @@ -7,17 +7,21 @@ import javax.ws.rs.core.Response; import org.eclipse.microprofile.rest.client.ext.ResponseExceptionMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; @Priority(4000) public class LodeStarGitLabAPIServiceResponseMapper implements ResponseExceptionMapper { + private static final Logger LOGGER = LoggerFactory.getLogger(LodeStarGitLabAPIServiceResponseMapper.class); + @Override public RuntimeException toThrowable(Response response) { int status = response.getStatus(); - String msg = getBody(response); - return new WebApplicationException(msg, status); + LOGGER.error("Rest client response error {} {}", status, msg); + return new WebApplicationException(msg, status); } private String getBody(Response response) { diff --git a/src/main/java/com/redhat/labs/lodestar/model/ErrorMessage.java b/src/main/java/com/redhat/labs/lodestar/model/ErrorMessage.java new file mode 100644 index 00000000..3ed4447e --- /dev/null +++ b/src/main/java/com/redhat/labs/lodestar/model/ErrorMessage.java @@ -0,0 +1,17 @@ +package com.redhat.labs.lodestar.model; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +@AllArgsConstructor +public class ErrorMessage { + + String message; + + public ErrorMessage(String messasge, Object... substitutions) { + this.message = String.format(messasge, substitutions); + } +} diff --git a/src/main/java/com/redhat/labs/lodestar/model/HostingEnvOpenShfitRollup.java b/src/main/java/com/redhat/labs/lodestar/model/HostingEnvOpenShfitRollup.java new file mode 100644 index 00000000..c2c29905 --- /dev/null +++ b/src/main/java/com/redhat/labs/lodestar/model/HostingEnvOpenShfitRollup.java @@ -0,0 +1,15 @@ +package com.redhat.labs.lodestar.model; + +public enum HostingEnvOpenShfitRollup { + OCP_VERSION("ocpVersion"), OCP_VERSION_MAJOR("ocpMajorVersion"), OCP_VERSION_MINOR("ocpMinorVersion"); + + String depth; + + HostingEnvOpenShfitRollup(String column) { + this.depth = column; + } + + public final String getColumn() { + return depth; + } +} diff --git a/src/main/java/com/redhat/labs/lodestar/model/event/EventType.java b/src/main/java/com/redhat/labs/lodestar/model/event/EventType.java index 204c548a..1cb3a83f 100644 --- a/src/main/java/com/redhat/labs/lodestar/model/event/EventType.java +++ b/src/main/java/com/redhat/labs/lodestar/model/event/EventType.java @@ -22,13 +22,16 @@ private EventType() { public static final String GET_PAGE_OF_ENGAGEMENTS_EVENT_ADDRESS = "get.page.of.engagements.event"; public static final String PERSIST_ENGAGEMENT_LIST_EVENT_ADDRESS = "persist.engagement.list.event"; public static final String PERSIST_ENGAGEMENT_EVENT_ADDRESS = "persist.engagement.event"; + + public static final String UPDATE_ARTIFACTS_EVENT_ADDRESS = "update.artifacts.event"; public static final String UPDATE_COMMITS_EVENT_ADDRESS = "update.commits.event"; - public static final String UPDATE_STATUS_EVENT_ADDRESS = "update.status.event"; + public static final String UPDATE_HOSTING_EVENT_ADDRESS = "update.hosting.event"; public static final String UPDATE_PARTICIPANTS_EVENT_ADDESS = "update.participants.event"; - public static final String UPDATE_ARTIFACTS_EVENT_ADDRESS = "update.artifacts.event"; + public static final String UPDATE_STATUS_EVENT_ADDRESS = "update.status.event"; public static final String RELOAD_ACTIVITY_EVENT_ADDRESS = "reload.activity.event"; public static final String RELOAD_ARTIFACTS_EVENT_ADDRESS = "reload.artifacts.event"; + public static final String RELOAD_HOSTING_EVENT_ADDRESS = "reload.hosting.event"; public static final String RELOAD_PARTICIPANTS_EVENT_ADDRESS = "reload.participants.event"; } \ No newline at end of file diff --git a/src/main/java/com/redhat/labs/lodestar/model/filter/PagingOptions.java b/src/main/java/com/redhat/labs/lodestar/model/filter/PagingOptions.java new file mode 100644 index 00000000..3f1c8ac1 --- /dev/null +++ b/src/main/java/com/redhat/labs/lodestar/model/filter/PagingOptions.java @@ -0,0 +1,28 @@ +package com.redhat.labs.lodestar.model.filter; + +import javax.ws.rs.DefaultValue; +import javax.ws.rs.QueryParam; + +import org.eclipse.microprofile.openapi.annotations.parameters.Parameter; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class PagingOptions { + + @Parameter(description = "0 based page number") + @QueryParam("page") + @DefaultValue("0") + private int page; + + @QueryParam("pageSize") + @DefaultValue("100") + private int pageSize; + +} diff --git a/src/main/java/com/redhat/labs/lodestar/model/pagination/PagedHostingEnvironmentResults.java b/src/main/java/com/redhat/labs/lodestar/model/pagination/PagedHostingEnvironmentResults.java deleted file mode 100644 index dae8e33a..00000000 --- a/src/main/java/com/redhat/labs/lodestar/model/pagination/PagedHostingEnvironmentResults.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.redhat.labs.lodestar.model.pagination; - -import com.redhat.labs.lodestar.model.HostingEnvironment; - -import lombok.NoArgsConstructor; -import lombok.experimental.SuperBuilder; - -@SuperBuilder -@NoArgsConstructor -public class PagedHostingEnvironmentResults extends PagedResults { - -} \ No newline at end of file diff --git a/src/main/java/com/redhat/labs/lodestar/repository/EngagementRepository.java b/src/main/java/com/redhat/labs/lodestar/repository/EngagementRepository.java index 3cb8f135..ce656b58 100644 --- a/src/main/java/com/redhat/labs/lodestar/repository/EngagementRepository.java +++ b/src/main/java/com/redhat/labs/lodestar/repository/EngagementRepository.java @@ -5,8 +5,8 @@ import static com.mongodb.client.model.Filters.regex; import static com.mongodb.client.model.Projections.exclude; import static com.mongodb.client.model.Projections.include; -import static com.mongodb.client.model.Updates.set; import static com.mongodb.client.model.Updates.combine; +import static com.mongodb.client.model.Updates.set; import java.util.Arrays; import java.util.List; @@ -31,7 +31,6 @@ import com.redhat.labs.lodestar.model.Commit; import com.redhat.labs.lodestar.model.Engagement; import com.redhat.labs.lodestar.model.EngagementUserSummary; -import com.redhat.labs.lodestar.model.HostingEnvironment; import com.redhat.labs.lodestar.model.Score; import com.redhat.labs.lodestar.model.Status; import com.redhat.labs.lodestar.model.UseCase; @@ -40,7 +39,6 @@ import com.redhat.labs.lodestar.model.pagination.PagedArtifactResults; import com.redhat.labs.lodestar.model.pagination.PagedCategoryResults; import com.redhat.labs.lodestar.model.pagination.PagedEngagementResults; -import com.redhat.labs.lodestar.model.pagination.PagedHostingEnvironmentResults; import com.redhat.labs.lodestar.model.pagination.PagedScoreResults; import com.redhat.labs.lodestar.model.pagination.PagedStringResults; import com.redhat.labs.lodestar.model.pagination.PagedUseCaseResults; @@ -408,33 +406,6 @@ public PagedScoreResults findScores(ListFilterOptions filterOptions) { } - /** - * Returns the {@link PagedHostingEnvironmentResults} containing the - * {@link HostingEnvironment}s that match the given {@link ListFilterOptions}. - * - * @param filterOptions - * @return - */ - public PagedHostingEnvironmentResults findHostingEnvironments(ListFilterOptions filterOptions) { - - filterOptions.setUnwindFieldName(Optional.of("hostingEnvironments")); - filterOptions.setUnwindProjectFieldNames(Optional.of(ClassFieldUtils - .classFieldNamesAsCommaSeparatedString(HostingEnvironment.class, Optional.of("hostingEnvironments")))); - - List pipeline = MongoAggregationHelper.generatePagedAggregationPipeline(filterOptions); - Optional optional = findFirstFromIterable( - mongoCollection().aggregate(pipeline, PagedHostingEnvironmentResults.class)); - - PagedHostingEnvironmentResults results = optional - .orElse(PagedHostingEnvironmentResults.builder().results(Arrays.asList()).build()); - - results.setCurrentPage(filterOptions.getPage().orElse(1)); - results.setPerPage(filterOptions.getPerPage().orElse(20)); - - return results; - - } - /** * Returns the {@link PagedUseCaseResults} containing the {@link UseCase}s that * match the given {@link ListFilterOptions}. diff --git a/src/main/java/com/redhat/labs/lodestar/resource/EngagementHostingEnvironmentResource.java b/src/main/java/com/redhat/labs/lodestar/resource/EngagementHostingEnvironmentResource.java deleted file mode 100644 index 044b4229..00000000 --- a/src/main/java/com/redhat/labs/lodestar/resource/EngagementHostingEnvironmentResource.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.redhat.labs.lodestar.resource; - -import javax.enterprise.context.RequestScoped; -import javax.inject.Inject; -import javax.ws.rs.BeanParam; -import javax.ws.rs.Consumes; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.ResponseBuilder; -import javax.ws.rs.core.UriInfo; - -import org.eclipse.microprofile.jwt.JsonWebToken; -import org.eclipse.microprofile.metrics.MetricUnits; -import org.eclipse.microprofile.metrics.annotation.Counted; -import org.eclipse.microprofile.metrics.annotation.Timed; -import org.eclipse.microprofile.openapi.annotations.Operation; -import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; -import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; -import org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement; -import org.eclipse.microprofile.openapi.annotations.security.SecurityScheme; - -import com.redhat.labs.lodestar.model.filter.ListFilterOptions; -import com.redhat.labs.lodestar.model.pagination.PagedHostingEnvironmentResults; -import com.redhat.labs.lodestar.service.EngagementService; - -@RequestScoped -@Path("/engagements") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@SecurityScheme(securitySchemeName = "jwt", type = SecuritySchemeType.HTTP, scheme = "bearer", bearerFormat = "JWT") -public class EngagementHostingEnvironmentResource { - - @Inject - JsonWebToken jwt; - - @Inject - EngagementService engagementService; - - @GET - @Path("/hosting/environments") - @SecurityRequirement(name = "jwt", scopes = {}) - @APIResponses(value = { @APIResponse(responseCode = "401", description = "Missing or Invalid JWT"), - @APIResponse(responseCode = "200", description = "hosting environments have been returned.") }) - @Operation(summary = "Returns engagement hosting environments") - @Counted(name = "engagement-get-all-environments-counted") - @Timed(name = "engagement-get-all-environments-timer", unit = MetricUnits.MILLISECONDS) - public Response getHostingEnvironments(@Context UriInfo uriInfo, @BeanParam ListFilterOptions filterOptions) { - - PagedHostingEnvironmentResults page = engagementService.getHostingEnvironments(filterOptions); - ResponseBuilder builder = Response.ok(page.getResults()).links(page.getLinks(uriInfo.getAbsolutePathBuilder())); - page.getHeaders().entrySet().stream().forEach(e -> builder.header(e.getKey(), e.getValue())); - return builder.build(); - - } - -} \ No newline at end of file diff --git a/src/main/java/com/redhat/labs/lodestar/resource/HostingEnvironmentResource.java b/src/main/java/com/redhat/labs/lodestar/resource/HostingEnvironmentResource.java new file mode 100644 index 00000000..1a9501e0 --- /dev/null +++ b/src/main/java/com/redhat/labs/lodestar/resource/HostingEnvironmentResource.java @@ -0,0 +1,124 @@ +package com.redhat.labs.lodestar.resource; + +import java.util.List; + +import javax.enterprise.context.RequestScoped; +import javax.inject.Inject; +import javax.ws.rs.BeanParam; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; + +import org.eclipse.microprofile.jwt.JsonWebToken; +import org.eclipse.microprofile.metrics.MetricUnits; +import org.eclipse.microprofile.metrics.annotation.Timed; +import org.eclipse.microprofile.openapi.annotations.Operation; +import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponse; +import org.eclipse.microprofile.openapi.annotations.responses.APIResponses; +import org.eclipse.microprofile.openapi.annotations.security.SecurityRequirement; +import org.eclipse.microprofile.openapi.annotations.security.SecurityScheme; +import org.eclipse.microprofile.openapi.annotations.tags.Tag; + +import com.redhat.labs.lodestar.model.Engagement; +import com.redhat.labs.lodestar.model.HostingEnvOpenShfitRollup; +import com.redhat.labs.lodestar.model.HostingEnvironment; +import com.redhat.labs.lodestar.model.filter.PagingOptions; +import com.redhat.labs.lodestar.service.ConfigService; +import com.redhat.labs.lodestar.service.EngagementService; +import com.redhat.labs.lodestar.service.HostingService; +import com.redhat.labs.lodestar.util.JWTUtils; + +@RequestScoped +@Path("/hosting/environments") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@SecurityScheme(securitySchemeName = "jwt", type = SecuritySchemeType.HTTP, scheme = "bearer", bearerFormat = "JWT") +@Tag(name = "Hosting", description = "Hosting environment apis") +public class HostingEnvironmentResource { + + @Inject + JsonWebToken jwt; + + @Inject + JWTUtils jwtUtils; + + @Inject + EngagementService engagementService; + + @Inject + ConfigService configService; + + @Inject + HostingService hostingService; + + @GET + @SecurityRequirement(name = "jwt", scopes = {}) + @APIResponses(value = { @APIResponse(responseCode = "401", description = "Missing or Invalid JWT"), + @APIResponse(responseCode = "200", description = "hosting environments have been returned.") }) + @Operation(summary = "Returns engagement hosting environments") + @Timed(name = "hosting-get-all-timer", unit = MetricUnits.MILLISECONDS) + public Response getHostingEnvironments(@Context UriInfo uriInfo, @BeanParam PagingOptions pagingOptions) { + return hostingService.getHostingEnvironments(pagingOptions.getPage(), pagingOptions.getPageSize()); + } + + @GET + @Path("/engagements/{engagementUuid}") + @SecurityRequirement(name = "jwt", scopes = {}) + @Timed(name = "hosting-env-engagement-timer", unit = MetricUnits.MILLISECONDS) + public Response getHostingForEngagementUuid(@PathParam(value = "engagementUuid") String engagementUuid) { + return hostingService.getHostingEnvironments(engagementUuid); + } + + @PUT + @Path("/engagements/{engagementUuid}") + @SecurityRequirement(name = "jwt", scopes = {}) + @APIResponses(value = { @APIResponse(responseCode = "401", description = "Missing or Invalid JWT"), + @APIResponse(responseCode = "403", description = "No write access for type"), + @APIResponse(responseCode = "200", description = "hosting environments have been returned.") }) + @Timed(name = "hosting-update-timer", unit = MetricUnits.MILLISECONDS) + public Response updateHostingForEnagementUuid(@PathParam(value = "engagementUuid") String engagementUuid, + List hostingEnvironments) { + Engagement engagement = engagementService.getByUuid(engagementUuid); + + boolean writeable = jwtUtils.isAllowedToWriteEngagement(jwt, configService.getPermission(engagement.getType())); + + if (!writeable) { + return engagementService.getNotWriteableResponse(engagementUuid, engagement.getType()); + } + + String email = jwtUtils.getUserEmailFromToken(jwt); + String name = jwtUtils.getUsernameFromToken(jwt); + + return hostingService.updateHostingEnvironments(engagementUuid, name, email, hostingEnvironments); + } + + @GET + @Path("/openshift/versions") + @SecurityRequirement(name = "jwt", scopes = {}) + @Timed(name = "hosting-openshift-versions-timer", unit = MetricUnits.MILLISECONDS) + public Response getOpenShiftVersions(@QueryParam("depth") final HostingEnvOpenShfitRollup rollup, @QueryParam("region") List region) { + return hostingService.getOcpVersionRollup(rollup, region); + } + + @HEAD + @Path("/subdomain/valid/{engagementUuid}/{subdomain}") + @APIResponses(value = { @APIResponse(responseCode = "401", description = "Missing or Invalid JWT"), + @APIResponse(responseCode = "409", description = "Subdomain is taken by another engagement"), + @APIResponse(responseCode = "200", description = "Subdomain is able to be used by this engagement.") }) + @SecurityRequirement(name = "jwt", scopes = {}) + @Timed(name = "hosting-valid-subdomain-timer", unit = MetricUnits.MILLISECONDS) + public Response isSubdomainValid(@PathParam("engagementUuid") String engagementUuid, @PathParam("subdomain") String subdomain) { + return hostingService.isSubdomainValidResponse(engagementUuid, subdomain); + } + +} \ No newline at end of file diff --git a/src/main/java/com/redhat/labs/lodestar/resource/RefreshResource.java b/src/main/java/com/redhat/labs/lodestar/resource/RefreshResource.java index 7273aea0..82acaccb 100644 --- a/src/main/java/com/redhat/labs/lodestar/resource/RefreshResource.java +++ b/src/main/java/com/redhat/labs/lodestar/resource/RefreshResource.java @@ -11,7 +11,6 @@ import javax.ws.rs.core.Response; import org.eclipse.microprofile.metrics.MetricUnits; -import org.eclipse.microprofile.metrics.annotation.Counted; import org.eclipse.microprofile.metrics.annotation.Timed; import org.eclipse.microprofile.openapi.annotations.Operation; import org.eclipse.microprofile.openapi.annotations.enums.SecuritySchemeType; @@ -27,6 +26,7 @@ import com.redhat.labs.lodestar.rest.client.ActivityApiClient; import com.redhat.labs.lodestar.service.ArtifactService; import com.redhat.labs.lodestar.service.EngagementService; +import com.redhat.labs.lodestar.service.HostingService; import com.redhat.labs.lodestar.service.ParticipantService; import io.vertx.mutiny.core.eventbus.EventBus; @@ -47,6 +47,9 @@ public class RefreshResource { @Inject ArtifactService artifactService; + + @Inject + HostingService hostingService; @Inject @RestClient @@ -62,7 +65,6 @@ public class RefreshResource { @APIResponse(responseCode = "404", description = "UUID provided, but no engagement found in database."), @APIResponse(responseCode = "202", description = "The request was accepted and will be processed.") }) @Operation(summary = "Refreshes database with data in git, purging first if the query paramater set to true.") - @Counted(name = "engagement-put-refresh-counted") @Timed(name = "engagement-put-refresh-timer", unit = MetricUnits.MILLISECONDS) public Response refresh( @Parameter(description = "When set deletes engagements first.") @QueryParam("purgeFirst") Boolean purgeFirst, @@ -71,7 +73,8 @@ public Response refresh( @Parameter(description = "Refresh artifacts") @QueryParam("artifacts") boolean refreshArtifacts, @Parameter(description = "Refresh participants") @QueryParam("participants") boolean refreshParticipants, @Parameter(description = "Refresh activity") @QueryParam("activity") boolean refreshActivity, - @Parameter(description = "Refresh engagements") @QueryParam("engagements") boolean refreshEngagements) { + @Parameter(description = "Refresh engagements") @QueryParam("engagements") boolean refreshEngagements, + @Parameter(description = "Refresh hosting") @QueryParam("hosting") boolean refreshHosting) { boolean didPickSomething = false; @@ -90,6 +93,11 @@ public Response refresh( eventBus.sendAndForget(EventType.RELOAD_ARTIFACTS_EVENT_ADDRESS, EventType.RELOAD_ARTIFACTS_EVENT_ADDRESS); didPickSomething = true; } + + if(refreshHosting) { + eventBus.sendAndForget(EventType.RELOAD_HOSTING_EVENT_ADDRESS, EventType.RELOAD_ARTIFACTS_EVENT_ADDRESS); + didPickSomething = true; + } if (refreshEngagements) { engagementService.syncGitToDatabase(Boolean.TRUE.equals(purgeFirst), uuid, projectId); diff --git a/src/main/java/com/redhat/labs/lodestar/rest/client/HostingApiClient.java b/src/main/java/com/redhat/labs/lodestar/rest/client/HostingApiClient.java new file mode 100644 index 00000000..a25c4f0b --- /dev/null +++ b/src/main/java/com/redhat/labs/lodestar/rest/client/HostingApiClient.java @@ -0,0 +1,57 @@ +package com.redhat.labs.lodestar.rest.client; + +import java.util.List; + +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HEAD; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; + +import org.eclipse.microprofile.rest.client.annotation.ClientHeaderParam; +import org.eclipse.microprofile.rest.client.annotation.RegisterProvider; +import org.eclipse.microprofile.rest.client.inject.RegisterRestClient; + +import com.redhat.labs.lodestar.exception.mapper.LodeStarGitLabAPIServiceResponseMapper; +import com.redhat.labs.lodestar.model.HostingEnvOpenShfitRollup; +import com.redhat.labs.lodestar.model.HostingEnvironment; + +@ApplicationScoped +@RegisterRestClient(configKey = "lodestar.hosting.api") +@RegisterProvider(value = LodeStarGitLabAPIServiceResponseMapper.class, priority = 50) +@Produces("application/json") +@Consumes("application/json") +@ClientHeaderParam(name = "version", value = "v1") +@Path("/api/hosting") +public interface HostingApiClient { + + @GET + Response getHostingEnvironments(@QueryParam("page") int page, @QueryParam("pageSize") int pageSize); + + @GET + @Path("/engagements/{engagementUuid}") + Response getHostingEnvironmentsForEngagement(@PathParam("engagementUuid") String engagementUuid); + + @PUT + @Path("/engagements/{engagementUuid}") + Response updateHostingEnvironments(@PathParam(value = "engagementUuid") String engagementUuid, + @QueryParam(value = "authorEmail") String authorEmail, @QueryParam(value = "authorName") String authorName, + List hostingEnvironments); + + @Path("/openshift/versions") + @GET + public Response getOpenShiftVersions(@QueryParam("depth") final HostingEnvOpenShfitRollup rollup, @QueryParam("region") List region); + + @PUT + @Path("/refresh") + Response refreshHostingEnvironments(); + + @HEAD + @Path("/subdomain/valid/{engagementUuid}/{subdomain}") + Response isSubdomainValid(@PathParam("engagementUuid") String engagementUuid, @PathParam("subdomain") String subdomain); +} diff --git a/src/main/java/com/redhat/labs/lodestar/service/EngagementService.java b/src/main/java/com/redhat/labs/lodestar/service/EngagementService.java index 1e70a069..6ba21370 100644 --- a/src/main/java/com/redhat/labs/lodestar/service/EngagementService.java +++ b/src/main/java/com/redhat/labs/lodestar/service/EngagementService.java @@ -4,7 +4,6 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.EnumMap; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; @@ -14,8 +13,6 @@ import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; -import javax.json.JsonArray; -import javax.json.JsonObject; import javax.json.bind.Jsonb; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; @@ -36,6 +33,7 @@ import com.redhat.labs.lodestar.model.EngagementAttribute; import com.redhat.labs.lodestar.model.EngagementUser; import com.redhat.labs.lodestar.model.EngagementUserSummary; +import com.redhat.labs.lodestar.model.ErrorMessage; import com.redhat.labs.lodestar.model.Hook; import com.redhat.labs.lodestar.model.HostingEnvironment; import com.redhat.labs.lodestar.model.Launch; @@ -48,7 +46,6 @@ import com.redhat.labs.lodestar.model.pagination.PagedArtifactResults; import com.redhat.labs.lodestar.model.pagination.PagedCategoryResults; import com.redhat.labs.lodestar.model.pagination.PagedEngagementResults; -import com.redhat.labs.lodestar.model.pagination.PagedHostingEnvironmentResults; import com.redhat.labs.lodestar.model.pagination.PagedScoreResults; import com.redhat.labs.lodestar.model.pagination.PagedStringResults; import com.redhat.labs.lodestar.model.pagination.PagedUseCaseResults; @@ -240,6 +237,10 @@ public Engagement update(Engagement engagement) { if(commitMessageContains(copy, "artifacts")) { eventBus.sendAndForget(EventType.UPDATE_ARTIFACTS_EVENT_ADDRESS, message); } + + if(commitMessageContains(copy, "hosting_environments")) { + eventBus.sendAndForget(EventType.UPDATE_HOSTING_EVENT_ADDRESS, message); + } return updated; @@ -708,6 +709,14 @@ public Map getEngagementCountByStatus(LocalDateTime cu return statusCounts; } + + public Response getNotWriteableResponse(String engagementUuid, String type) { + return Response.status(403).entity(new ErrorMessage("User is not authorized to write to type %s for %s", type, engagementUuid)).build(); + } + + public Engagement getByUuid(String uuid) { + return getByUuid(uuid, new FilterOptions()); + } /** * Returns an {@link Engagement} if it is present in the data store. Otherwise, @@ -845,10 +854,6 @@ public PagedArtifactResults getArtifacts(ListFilterOptions filterOptions) { return repository.findArtifacts(filterOptions); } - public PagedHostingEnvironmentResults getHostingEnvironments(ListFilterOptions filterOptions) { - return repository.findHostingEnvironments(filterOptions); - } - public PagedScoreResults getScores(ListFilterOptions filterOptions) { return repository.findScores(filterOptions); } diff --git a/src/main/java/com/redhat/labs/lodestar/service/HostingService.java b/src/main/java/com/redhat/labs/lodestar/service/HostingService.java new file mode 100644 index 00000000..1adf371e --- /dev/null +++ b/src/main/java/com/redhat/labs/lodestar/service/HostingService.java @@ -0,0 +1,98 @@ +package com.redhat.labs.lodestar.service; + +import java.util.List; + +import javax.enterprise.context.ApplicationScoped; +import javax.inject.Inject; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; + +import org.eclipse.microprofile.rest.client.inject.RestClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.redhat.labs.lodestar.model.Engagement; +import com.redhat.labs.lodestar.model.HostingEnvOpenShfitRollup; +import com.redhat.labs.lodestar.model.HostingEnvironment; +import com.redhat.labs.lodestar.model.event.EventType; +import com.redhat.labs.lodestar.model.filter.FilterOptions; +import com.redhat.labs.lodestar.rest.client.HostingApiClient; + +import io.quarkus.vertx.ConsumeEvent; + +@ApplicationScoped +public class HostingService { + private static final Logger LOGGER = LoggerFactory.getLogger(HostingService.class); + + @Inject + @RestClient + HostingApiClient hostingApiClient; + + @Inject + EngagementService engagementService; + + public Response getHostingEnvironments(int page, int pageSize) { + return hostingApiClient.getHostingEnvironments(page, pageSize); + } + + public Response getHostingEnvironments(String engagementUuid) { + return hostingApiClient.getHostingEnvironmentsForEngagement(engagementUuid); + } + + public Response isSubdomainValidResponse(String engagementUuid, String subdomain) { + return hostingApiClient.isSubdomainValid(engagementUuid, subdomain); + } + + public Response getOcpVersionRollup(HostingEnvOpenShfitRollup rollup, List region) { + return hostingApiClient.getOpenShiftVersions(rollup, region); + } + + /** + * Sync - directly called api from the FE + * + * @param engagementUuid the engagement uuid to update + * @param authorName the name of the updater + * @param authorEmail the email of the user + * @param hostingEnvironments the full list of hostingEnvironments for an + * engagement + * @return A response value indicating success (200) or failure (anything else) + */ + public Response updateHostingEnvironments(String engagementUuid, String authorName, String authorEmail, + List hostingEnvironments) { + return hostingApiClient.updateHostingEnvironments(engagementUuid, authorName, authorEmail, hostingEnvironments); + } + + /** + * Async - with update engagement + * + * @param message Comma separated string of uuid, name, email + */ + @ConsumeEvent(value = EventType.UPDATE_HOSTING_EVENT_ADDRESS, blocking = true) + public void updateHostingEnvironments(String message) { + LOGGER.debug("hosting update via engagement save {}", message); + String[] uuidNameEmail = message.split(","); + + Engagement engagement = engagementService.getByUuid(uuidNameEmail[0], new FilterOptions()); + + try { + hostingApiClient.updateHostingEnvironments(engagement.getUuid(), uuidNameEmail[1], uuidNameEmail[2], engagement.getHostingEnvironments()); + LOGGER.debug("Updated hosting for engagement {}", engagement.getUuid()); + } catch (WebApplicationException wae) { + LOGGER.error("Failed to update hosting for engagement {} {}", wae.getResponse().getStatus(), message); + } catch (RuntimeException wae) { + LOGGER.error("Failed to update hosting for engagement {}", message, wae); + } + + } + + @ConsumeEvent(value = EventType.RELOAD_HOSTING_EVENT_ADDRESS, blocking = true) + public void refesh(String message) { + try { + LOGGER.debug("refresh {}", message); + Response response = hostingApiClient.refreshHostingEnvironments(); + LOGGER.debug("refresh {} completed. Hosting count is {} ", message, response.getHeaderString("x-total-hosting")); + } catch (WebApplicationException wae) { // without catching this it will fail silently + LOGGER.error("Failed to refresh hosting environments {}", wae.getResponse(), wae); + } + } +} diff --git a/src/main/java/com/redhat/labs/lodestar/util/JWTUtils.java b/src/main/java/com/redhat/labs/lodestar/util/JWTUtils.java index ad55bcbf..a4791508 100644 --- a/src/main/java/com/redhat/labs/lodestar/util/JWTUtils.java +++ b/src/main/java/com/redhat/labs/lodestar/util/JWTUtils.java @@ -52,7 +52,7 @@ public String getUserEmailFromToken(JsonWebToken jwt) { } public boolean isAllowedToWriteEngagement(JsonWebToken jwt, List allowedGroups) { - return jwt.getGroups().stream().filter(allowedGroups::contains).findAny().isPresent(); + return jwt.getGroups().stream().anyMatch(allowedGroups::contains); } public Optional claimIsValid(JsonWebToken jwt, String claimName) { diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f7eb6983..cc87a47e 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -36,12 +36,12 @@ quarkus.http.auth.permission.read.paths=/config quarkus.http.auth.permission.read.policy=role-reader # set the /engagements/* endpoint(s) to writer for PUT and POST methods -quarkus.http.auth.permission.writer.paths=/engagements/* +quarkus.http.auth.permission.writer.paths=/engagements/*,/hosting/*,/participants/*,/artifacts/* quarkus.http.auth.permission.writer.policy=role-writer quarkus.http.auth.permission.writer.methods=PUT,POST # set the /engagements/* endpoint(s) to reader for other methods -quarkus.http.auth.permission.reader.paths=/engagements/* +quarkus.http.auth.permission.reader.paths=/engagements/*,/hosting/*,/participants/*,/artifacts/* quarkus.http.auth.permission.reader.policy=role-reader quarkus.cache.caffeine.rbac-cache.expire-after-write=600S @@ -63,6 +63,7 @@ lodestar.config.api/mp-rest/url=${LODESTAR_CONFIG_API_URL:http://lodestar-config lodestar.activity.api/mp-rest/url=${LODESTAR_ACTIVITY_API_URL:http://lodestar-activity:8080} lodestar.artifacts.api/mp-rest/url=${LODESTAR_ARTIFACTS_API_URL:http://lodestar-artifacts:8080} lodestar.participants.api/mp-rest/url=${LODESTAR_PARTICIPANTS_API_URL:http://lodestar-participants:8080} +lodestar.hosting.api/mp-rest/url=${LODESTAR_HOSTING_API_URL:http://lodestar-hosting:8080} lodestar.gitlab.api/mp-rest/scope=javax.inject.Singleton lodestar.status.api/mp-rest/scope=javax.inject.Singleton @@ -70,6 +71,8 @@ lodestar.config.api/mp-rest/scope=javax.inject.Singleton lodestar.activity.api/mp-rest/scope=javax.inject.Singleton lodestar.artifacts.api/mp-rest/scope=javax.inject.Singleton lodestar.participants.api/mp-rest/scope=javax.inject.Singleton +lodestar.hosting.api/mp-rest/scope=javax.inject.Singleton + webhook.token=${WEBHOOK_TOKEN:t} cleanup.token=${CLEANUP_TOKEN:OFF} diff --git a/src/test/java/com/redhat/labs/lodestar/zrepository/EngagementRepositoryTest.java b/src/test/java/com/redhat/labs/lodestar/repository/EngagementRepositoryTest.java similarity index 95% rename from src/test/java/com/redhat/labs/lodestar/zrepository/EngagementRepositoryTest.java rename to src/test/java/com/redhat/labs/lodestar/repository/EngagementRepositoryTest.java index aa66c8da..ca8f4f0e 100644 --- a/src/test/java/com/redhat/labs/lodestar/zrepository/EngagementRepositoryTest.java +++ b/src/test/java/com/redhat/labs/lodestar/repository/EngagementRepositoryTest.java @@ -1,4 +1,4 @@ -package com.redhat.labs.lodestar.zrepository; +package com.redhat.labs.lodestar.repository; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; @@ -36,7 +36,6 @@ import com.redhat.labs.lodestar.model.pagination.PagedArtifactResults; import com.redhat.labs.lodestar.model.pagination.PagedCategoryResults; import com.redhat.labs.lodestar.model.pagination.PagedEngagementResults; -import com.redhat.labs.lodestar.model.pagination.PagedHostingEnvironmentResults; import com.redhat.labs.lodestar.model.pagination.PagedScoreResults; import com.redhat.labs.lodestar.model.pagination.PagedStringResults; import com.redhat.labs.lodestar.model.pagination.PagedUseCaseResults; @@ -1315,67 +1314,6 @@ void testFindUseCasesFiltered() { } - @Test - void testFindHostingEnvironmentsAll() { - - HostingEnvironment h1 = MockUtils.mockHostingEnvironment("env 1", "envone"); - Engagement e1 = MockUtils.mockMinimumEngagement("c1", "p1", "1111"); - e1.setHostingEnvironments(Arrays.asList(h1)); - - HostingEnvironment h2 = MockUtils.mockHostingEnvironment("env 2", "envtwo"); - Engagement e2 = MockUtils.mockMinimumEngagement("c2", "p2", "2222"); - e2.setHostingEnvironments(Arrays.asList(h2)); - - repository.persist(e1, e2); - - ListFilterOptions options = ListFilterOptions.builder().build(); - - PagedHostingEnvironmentResults pagedResults = repository.findHostingEnvironments(options); - assertNotNull(pagedResults); - assertNotNull(pagedResults.getResults()); - - List results = pagedResults.getResults(); - assertEquals(2, results.size()); - - results.stream().forEach(a -> { - - if ("1111".equals(a.getEngagementUuid())) { - assertEquals("env 1", a.getEnvironmentName()); - } else if ("2222".equals(a.getEngagementUuid())) { - assertEquals("env 2", a.getEnvironmentName()); - } else { - fail("unknown use case: " + a); - } - - }); - - } - - @Test - void testFindHostingEnvironmentsFiltered() { - - HostingEnvironment h1 = MockUtils.mockHostingEnvironment("env 1", "envone"); - Engagement e1 = MockUtils.mockMinimumEngagement("c1", "p1", "1111"); - e1.setHostingEnvironments(Arrays.asList(h1)); - - HostingEnvironment h2 = MockUtils.mockHostingEnvironment("env 2", "envtwo"); - Engagement e2 = MockUtils.mockMinimumEngagement("c2", "p2", "2222"); - e2.setHostingEnvironments(Arrays.asList(h2)); - - repository.persist(e1, e2); - - ListFilterOptions options = ListFilterOptions.builder().search("uuid=1111").build(); - - PagedHostingEnvironmentResults pagedResults = repository.findHostingEnvironments(options); - assertNotNull(pagedResults); - assertNotNull(pagedResults.getResults()); - - List results = pagedResults.getResults(); - assertEquals(1, results.size()); - assertEquals("env 1", results.get(0).getEnvironmentName()); - - } - // create test data engagements private void createAndInsertRangeEngagementData() { diff --git a/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceGetTest.java b/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceGetTest.java index f94268d5..d2aca2f5 100644 --- a/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceGetTest.java +++ b/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceGetTest.java @@ -31,7 +31,6 @@ import com.redhat.labs.lodestar.model.Engagement; import com.redhat.labs.lodestar.model.EngagementArtifact; import com.redhat.labs.lodestar.model.EngagementUserSummary; -import com.redhat.labs.lodestar.model.HostingEnvironment; import com.redhat.labs.lodestar.model.Launch; import com.redhat.labs.lodestar.model.Score; import com.redhat.labs.lodestar.model.UseCase; @@ -41,7 +40,6 @@ import com.redhat.labs.lodestar.model.pagination.PagedArtifactResults; import com.redhat.labs.lodestar.model.pagination.PagedCategoryResults; import com.redhat.labs.lodestar.model.pagination.PagedEngagementResults; -import com.redhat.labs.lodestar.model.pagination.PagedHostingEnvironmentResults; import com.redhat.labs.lodestar.model.pagination.PagedScoreResults; import com.redhat.labs.lodestar.model.pagination.PagedStringResults; import com.redhat.labs.lodestar.model.pagination.PagedUseCaseResults; @@ -430,29 +428,6 @@ void testGetScores() throws Exception { } - @Test - void testGetHostingEnvironments() throws Exception { - - HashMap timeClaims = new HashMap<>(); - String token = TokenUtils.generateTokenString("/JwtClaimsWriter.json", timeClaims); - - HostingEnvironment he = MockUtils.mockHostingEnvironment("env1", "env-one"); - PagedHostingEnvironmentResults pagedResults = PagedHostingEnvironmentResults.builder().results(Arrays.asList(he)).build(); - Mockito.when(eRepository.findHostingEnvironments(Mockito.any(ListFilterOptions.class))).thenReturn(pagedResults); - - given() - .auth() - .oauth2(token) - .contentType(ContentType.JSON) - .when() - .get("engagements/hosting/environments") - .then() - .statusCode(200) - .body(containsString("env1")) - .body(containsString("env-one")); - - } - @Test void testGetUseCase() throws Exception { diff --git a/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceTest.java b/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceTest.java index 7fb5db75..e4245678 100644 --- a/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceTest.java +++ b/src/test/java/com/redhat/labs/lodestar/resource/EngagementResourceTest.java @@ -66,5 +66,10 @@ class ParticipantResource extends ParticipantResourceTest { class RefreshResource extends RefreshResourceTest { } + + @Nested + class HostingResource extends HostingResourceTest { + + } } diff --git a/src/test/java/com/redhat/labs/lodestar/resource/HostingResourceTest.java b/src/test/java/com/redhat/labs/lodestar/resource/HostingResourceTest.java new file mode 100644 index 00000000..72d8930b --- /dev/null +++ b/src/test/java/com/redhat/labs/lodestar/resource/HostingResourceTest.java @@ -0,0 +1,133 @@ +package com.redhat.labs.lodestar.resource; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.equalTo; + +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import javax.ws.rs.core.Response; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Tag; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.mockito.Mockito; + +import com.redhat.labs.lodestar.model.Engagement; +import com.redhat.labs.lodestar.model.HostingEnvOpenShfitRollup; +import com.redhat.labs.lodestar.model.HostingEnvironment; +import com.redhat.labs.lodestar.model.filter.FilterOptions; +import com.redhat.labs.lodestar.utils.IntegrationTestHelper; +import com.redhat.labs.lodestar.utils.MockUtils; +import com.redhat.labs.lodestar.utils.TokenUtils; + +import io.quarkus.test.junit.QuarkusTest; +import io.restassured.http.ContentType; + +@QuarkusTest +@Tag("nested") +class HostingResourceTest extends IntegrationTestHelper { + + static String validToken; + + @BeforeAll + static void setUp() throws Exception { + validToken = TokenUtils.generateTokenString("/JwtClaimsWriter.json"); + } + + @Test + void testGetHostingEnvironments() { + + HostingEnvironment he = MockUtils.mockHostingEnvironment("env1", "env-one"); + Response r = Response.ok(Collections.singletonList(he)).build(); + + Mockito.when(hostingApiClient.getHostingEnvironments(0, 10)).thenReturn(r); + + given().queryParam("pageSize", 10).when().auth().oauth2(validToken).get("/hosting/environments").then().statusCode(200) + .body("[0].environment_name", equalTo("env1")).body("[0].ocp_sub_domain", equalTo("env-one")); + + } + + @Test + void testGetHostingEnvironmentByUuid() { + + HostingEnvironment he = MockUtils.mockHostingEnvironment("env1", "env-one"); + Response r = Response.ok(Collections.singletonList(he)).build(); + + Mockito.when(hostingApiClient.getHostingEnvironmentsForEngagement("uuid")).thenReturn(r); + + given().pathParam("engagementUuid", "uuid").when().auth().oauth2(validToken).get("/hosting/environments/engagements/{engagementUuid}").then() + .statusCode(200).body("[0].environment_name", equalTo("env1")).body("[0].ocp_sub_domain", equalTo("env-one")); + } + + @Test + void testGetVersions() { + + String version = "{ \"All\": 15, \"4.7.2\": 2, \"4.4.15\": 14 }"; + + Response versionResponse = Response.ok(version).build(); + + Mockito.when(hostingApiClient.getOpenShiftVersions(HostingEnvOpenShfitRollup.OCP_VERSION, Collections.emptyList())) + .thenReturn(versionResponse); + + given().queryParam("depth", "OCP_VERSION").when().auth().oauth2(validToken).get("/hosting/environments/openshift/versions").then() + .statusCode(200).body("All", equalTo(15)).body("'4.4.15'", equalTo(14)).body("'4.7.2'", equalTo(2)); + + } + + @Test + void testGetVersionsForRegion() { + + String version = "{ \"All\": 15, \"4.7.2\": 2, \"4.4.15\": 14 }"; + + Response versionResponse = Response.ok(version).build(); + + Mockito.when(hostingApiClient.getOpenShiftVersions(HostingEnvOpenShfitRollup.OCP_VERSION, Collections.emptyList())) + .thenReturn(versionResponse); + + given().queryParam("depth", "OCP_VERSION").when().auth().oauth2(validToken).get("/hosting/environments/openshift/versions").then() + .statusCode(200).body("All", equalTo(15)).body("'4.4.15'", equalTo(14)).body("'4.7.2'", equalTo(2)); + + } + + @ParameterizedTest + @CsvSource(value = { "200", "409" }) + void testValidSubdomain(int status) { + Mockito.when(hostingApiClient.isSubdomainValid("uuid", "subd")).thenReturn(Response.status(status).build()); + + given().pathParam("engagementUuid", "uuid").pathParam("subdomain", "subd").when().auth().oauth2(validToken).when() + .head("/hosting/environments/subdomain/valid/{engagementUuid}/{subdomain}").then().statusCode(status); + } + + @Test + void testUpdateEngagementNotWriteable() { + Map> permissions = new HashMap<>(); + Engagement e = Engagement.builder().uuid("uuid").type("DO500").build(); + Mockito.when(configApiClient.getPermission()).thenReturn(permissions); + Mockito.when(eRepository.findByUuid("uuid", new FilterOptions())).thenReturn(Optional.of(e)); + + given().contentType(ContentType.JSON).body(Collections.singletonList(e)).pathParam("engagementUuid", "uuid").when().auth().oauth2(validToken) + .put("/hosting/environments/engagements/{engagementUuid}").then().statusCode(403); + + } + + @Test + void testUpdateEngagementWriteable() { + Mockito.when(hostingApiClient.updateHostingEnvironments(Mockito.eq("uuid"), Mockito.anyString(), Mockito.anyString(), Mockito.anyList())) + .thenReturn(Response.ok().build()); + + Map> permissions = new HashMap<>(); + permissions.put("DO500", Collections.singletonList("writer")); + Engagement e = Engagement.builder().uuid("uuid").type("DO500").build(); + Mockito.when(configApiClient.getPermission()).thenReturn(permissions); + Mockito.when(eRepository.findByUuid("uuid", new FilterOptions())).thenReturn(Optional.of(e)); + + given().contentType(ContentType.JSON).body(Collections.singletonList(e)).pathParam("engagementUuid", "uuid").when().auth().oauth2(validToken) + .put("/hosting/environments/engagements/{engagementUuid}").then().statusCode(200); + } +} diff --git a/src/test/java/com/redhat/labs/lodestar/resource/RefreshResourceTest.java b/src/test/java/com/redhat/labs/lodestar/resource/RefreshResourceTest.java index b125299f..619663e5 100644 --- a/src/test/java/com/redhat/labs/lodestar/resource/RefreshResourceTest.java +++ b/src/test/java/com/redhat/labs/lodestar/resource/RefreshResourceTest.java @@ -52,7 +52,7 @@ void testParticipantReload() throws Exception { @Test void testParticipantReloadFail() throws Exception { - Mockito.when(participantClient.refreshParticipants()).thenReturn(Response.serverError().build()); + Mockito.when(participantClient.refreshParticipants()).thenReturn(Response.status(403).build()); given().queryParam("participants", true).when().auth().oauth2(validToken) .put("/engagements/refresh").then().statusCode(202); @@ -62,13 +62,24 @@ void testParticipantReloadFail() throws Exception { @Test void testArtifactsReload() throws Exception { - + given().queryParam("artifacts", true).when().auth().oauth2(validToken) .put("/engagements/refresh").then().statusCode(202); Mockito.verify(artifactClient, Mockito.timeout(1000)).refreshArtifacts(); } + @Test + void testHostingReload() throws Exception { + Response r = Response.ok().header("x-total-hosting", 1000000000).build(); + Mockito.when(hostingApiClient.refreshHostingEnvironments()).thenReturn(r); + + given().queryParam("hosting", true).when().auth().oauth2(validToken) + .put("/engagements/refresh").then().statusCode(202); + + Mockito.verify(hostingApiClient, Mockito.timeout(1000)).refreshHostingEnvironments(); + } + @Test void testDbRefreshWithPurge() throws Exception { diff --git a/src/test/java/com/redhat/labs/lodestar/service/ArtifactServiceTest.java b/src/test/java/com/redhat/labs/lodestar/service/ArtifactServiceTest.java index 764f1e59..344bcbeb 100644 --- a/src/test/java/com/redhat/labs/lodestar/service/ArtifactServiceTest.java +++ b/src/test/java/com/redhat/labs/lodestar/service/ArtifactServiceTest.java @@ -35,6 +35,8 @@ void setUp() { Mockito.when(engagementService.getByUuid(Mockito.eq("uuid3"), Mockito.any(FilterOptions.class))).thenThrow(new WebApplicationException("test", 500)); Mockito.when(artifactClient.updateArtifacts("uuid1", artifacts, "Mitch", "mitch@mitch.com")).thenReturn(Response.ok().build()); + Mockito.when(artifactClient.refreshArtifacts()).thenThrow(new WebApplicationException()); + artifactService = new ArtifactService(); artifactService.artifactRestClient = artifactClient; artifactService.engagementService = engagementService; @@ -64,4 +66,10 @@ void testSendUpdateWebError() { Mockito.verify(artifactClient, Mockito.never()).updateArtifacts("uuid3", artifacts, "Mitch", "mitch@mitch.com"); } + + @Test + void testRefresh() { + artifactService.refesh("no"); + Mockito.verify(artifactClient).refreshArtifacts(); + } } diff --git a/src/test/java/com/redhat/labs/lodestar/service/HostingServiceTest.java b/src/test/java/com/redhat/labs/lodestar/service/HostingServiceTest.java new file mode 100644 index 00000000..9ef978d8 --- /dev/null +++ b/src/test/java/com/redhat/labs/lodestar/service/HostingServiceTest.java @@ -0,0 +1,64 @@ +package com.redhat.labs.lodestar.service; + +import java.util.Collections; +import java.util.List; + +import javax.ws.rs.WebApplicationException; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +import com.redhat.labs.lodestar.model.Engagement; +import com.redhat.labs.lodestar.model.HostingEnvironment; +import com.redhat.labs.lodestar.model.filter.FilterOptions; +import com.redhat.labs.lodestar.rest.client.HostingApiClient; + +class HostingServiceTest { + + HostingService hostingService; + + HostingApiClient client; + + EngagementService engagementService; + + List hostingEnvironments; + + @BeforeEach + void setup() { + engagementService = Mockito.mock(EngagementService.class); + client = Mockito.mock(HostingApiClient.class); + + hostingService = new HostingService(); + hostingService.hostingApiClient = client; + hostingService.engagementService = engagementService; + + hostingEnvironments = Collections.singletonList(HostingEnvironment.builder().engagementUuid("uuid1").build()); + + Engagement engagement = Engagement.builder().uuid("uuid1").region("na").hostingEnvironments(hostingEnvironments).build(); + Mockito.when(engagementService.getByUuid(Mockito.eq("uuid1"), Mockito.any(FilterOptions.class))).thenReturn(engagement); + + Mockito.when(client.updateHostingEnvironments("uuid1", "wae@email.com", "name", hostingEnvironments)).thenThrow(new WebApplicationException()); + Mockito.when(client.updateHostingEnvironments("uuid1", "re@email.com", "name", hostingEnvironments)).thenThrow(new RuntimeException()); + + Mockito.when(client.refreshHostingEnvironments()).thenThrow(new WebApplicationException()); + } + + @Test + void testUpdate() { + hostingService.updateHostingEnvironments("uuid1,email@email.com,name"); + Mockito.verify(client).updateHostingEnvironments("uuid1", "email@email.com", "name", hostingEnvironments); + + hostingService.updateHostingEnvironments("uuid1,wae@email.com,name"); + Mockito.verify(client).updateHostingEnvironments("uuid1", "wae@email.com", "name", hostingEnvironments); + + hostingService.updateHostingEnvironments("uuid1,re@email.com,name"); + Mockito.verify(client).updateHostingEnvironments("uuid1", "re@email.com", "name", hostingEnvironments); + } + + @Test + void testRefresh() { + hostingService.refesh("no"); + Mockito.verify(client).refreshHostingEnvironments(); + } +} diff --git a/src/test/java/com/redhat/labs/lodestar/service/ParticipantServiceTest.java b/src/test/java/com/redhat/labs/lodestar/service/ParticipantServiceTest.java index 7a2c1343..81bf320f 100644 --- a/src/test/java/com/redhat/labs/lodestar/service/ParticipantServiceTest.java +++ b/src/test/java/com/redhat/labs/lodestar/service/ParticipantServiceTest.java @@ -38,6 +38,7 @@ void setup() { Mockito.when(participantClient.updateParticipants("1", "na", "x", "c", users)).thenThrow(new WebApplicationException()); Mockito.when(participantClient.updateParticipants("1", "na", "z", "c", users)).thenThrow(new RuntimeException()); + Mockito.when(participantClient.refreshParticipants()).thenThrow(new WebApplicationException()); participantService = new ParticipantService(); participantService.engagementService = engagementService; participantService.participantRestClient = participantClient; @@ -54,4 +55,10 @@ void testUpdateParticipants() { participantService.updateParticipants("1,z,c"); Mockito.verify(participantClient).updateParticipants("1", "na", "z", "c", users); } + + @Test + void testRefresh() { + participantService.refesh("no"); + Mockito.verify(participantClient).refreshParticipants(); + } } diff --git a/src/test/java/com/redhat/labs/lodestar/utils/IntegrationTestHelper.java b/src/test/java/com/redhat/labs/lodestar/utils/IntegrationTestHelper.java index 99d0ad97..4009e78a 100644 --- a/src/test/java/com/redhat/labs/lodestar/utils/IntegrationTestHelper.java +++ b/src/test/java/com/redhat/labs/lodestar/utils/IntegrationTestHelper.java @@ -12,6 +12,7 @@ import com.redhat.labs.lodestar.rest.client.ArtifactApiClient; import com.redhat.labs.lodestar.rest.client.ActivityApiClient; import com.redhat.labs.lodestar.rest.client.ConfigApiClient; +import com.redhat.labs.lodestar.rest.client.HostingApiClient; import com.redhat.labs.lodestar.rest.client.LodeStarGitApiClient; import com.redhat.labs.lodestar.rest.client.LodeStarStatusApiClient; import com.redhat.labs.lodestar.rest.client.ParticipantApiClient; @@ -37,6 +38,10 @@ public class IntegrationTestHelper { @InjectMock @RestClient public LodeStarStatusApiClient statusApiClient; + + @InjectMock + @RestClient + public HostingApiClient hostingApiClient; @InjectMock @RestClient diff --git a/src/test/java/com/redhat/labs/lodestar/utils/TokenUtils.java b/src/test/java/com/redhat/labs/lodestar/utils/TokenUtils.java index 87d5f124..67884724 100644 --- a/src/test/java/com/redhat/labs/lodestar/utils/TokenUtils.java +++ b/src/test/java/com/redhat/labs/lodestar/utils/TokenUtils.java @@ -10,6 +10,7 @@ import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; +import java.util.HashMap; import java.util.Map; import org.eclipse.microprofile.jwt.Claims; @@ -41,6 +42,15 @@ public static String generateTokenString(String jsonResName, Map t PrivateKey pk = readPrivateKey("/privateKey.pem"); return generateTokenString(pk, "/privateKey.pem", jsonResName, timeClaims); } + + public static String generateTokenString(String jsonResName) { + Map timeClaims = new HashMap<>(); + try { + return generateTokenString(jsonResName, timeClaims); + } catch (Exception e) { + throw new RuntimeException("Couldn't generate fake token"); + } + } @SuppressWarnings("deprecation") public static String generateTokenString(PrivateKey privateKey, String kid, diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 3ee72d40..435cd456 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -14,11 +14,11 @@ quarkus.http.auth.policy.role-writer.roles-allowed=writer quarkus.http.auth.permission.read.paths=/config quarkus.http.auth.permission.read.policy=role-reader # set the /engagements/* endpoint(s) to writer for PUT and POST methods -quarkus.http.auth.permission.writer.paths=/engagements/* +quarkus.http.auth.permission.writer.paths=/engagements/*,/hosting/*,/participants/*,/artifacts/* quarkus.http.auth.permission.writer.policy=role-writer quarkus.http.auth.permission.writer.methods=PUT,POST # set the /engagements/* endpoint(s) to reader for other methods -quarkus.http.auth.permission.reader.paths=/engagements/* +quarkus.http.auth.permission.reader.paths=/engagements/*,/hosting/*,/participants/*,/artifacts/* quarkus.http.auth.permission.reader.policy=role-reader # mongo #quarkus.mongodb.connect-timeout=1