diff --git a/service/src/main/java/org/kiwiproject/champagne/App.java b/service/src/main/java/org/kiwiproject/champagne/App.java index 50668000..b6d4ab83 100644 --- a/service/src/main/java/org/kiwiproject/champagne/App.java +++ b/service/src/main/java/org/kiwiproject/champagne/App.java @@ -18,6 +18,7 @@ import org.kiwiproject.champagne.dao.AuditRecordDao; import org.kiwiproject.champagne.dao.BuildDao; import org.kiwiproject.champagne.dao.ComponentDao; +import org.kiwiproject.champagne.dao.DeployableSystemDao; import org.kiwiproject.champagne.dao.DeploymentEnvironmentDao; import org.kiwiproject.champagne.dao.HostDao; import org.kiwiproject.champagne.dao.ReleaseDao; @@ -35,6 +36,7 @@ import org.kiwiproject.champagne.resource.HostConfigurationResource; import org.kiwiproject.champagne.resource.TaskResource; import org.kiwiproject.champagne.resource.UserResource; +import org.kiwiproject.champagne.resource.filter.DeployableSystemRequestFilter; import org.kiwiproject.champagne.service.ManualTaskService; import org.kiwiproject.dropwizard.error.ErrorContextBuilder; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; @@ -99,6 +101,7 @@ public void run(AppConfig configuration, Environment environment) { var hostDao = jdbi.onDemand(HostDao.class); var componentDao = jdbi.onDemand(ComponentDao.class); var errorDao = setupApplicationErrors(jdbi, configuration, environment); + var deployableSystemDao = jdbi.onDemand(DeployableSystemDao.class); var jsonHelper = JsonHelper.newDropwizardJsonHelper(); jdbi.registerRowMapper(Build.class, new BuildMapper(jsonHelper)); @@ -119,6 +122,8 @@ public void run(AppConfig configuration, Environment environment) { // Setup jobs var cleanOutAuditsJob = new CleanOutAuditsJob(auditRecordDao, configuration.getAuditRecordsMaxRetain().toMilliseconds()); registerJob(environment, "Clean Out Audits", configuration.getAuditCleanup(), cleanOutAuditsJob); + + environment.jersey().register(new DeployableSystemRequestFilter(deployableSystemDao)); } private static void setupJsonProcessing(Environment environment) { diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/AuditRecordDao.java b/service/src/main/java/org/kiwiproject/champagne/dao/AuditRecordDao.java index d8fd4d6e..cda86bdb 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/AuditRecordDao.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/AuditRecordDao.java @@ -15,16 +15,16 @@ @RegisterRowMapper(AuditRecordMapper.class) public interface AuditRecordDao { - @SqlUpdate("insert into audit_records (user_system_identifier, action, record_type, record_id) " + - "values (:userSystemIdentifier, :action, :recordType, :recordId)") + @SqlUpdate("insert into audit_records (user_system_identifier, action, record_type, record_id, deployable_system_id) " + + "values (:userSystemIdentifier, :action, :recordType, :recordId, :deployableSystemId)") @GetGeneratedKeys long insertAuditRecord(@BindBean AuditRecord auditRecord); - @SqlQuery("select * from audit_records order by audit_timestamp desc offset :offset limit :limit") - List findPagedAuditRecords(@Bind("offset") int offset, @Bind("limit") int limit); + @SqlQuery("select * from audit_records where deployable_system_id = :systemId order by audit_timestamp desc offset :offset limit :limit") + List findPagedAuditRecords(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("systemId") Long systemId); - @SqlQuery("select count(*) from audit_records") - long countAuditRecords(); + @SqlQuery("select count(*) from audit_records where deployable_system_id = :systemId") + long countAuditRecords(@Bind("systemId") Long systemId); @SqlUpdate("delete from audit_records where audit_timestamp < :maxRetainDate") int deleteAuditRecordsOlderThan(@Bind("maxRetainDate") Instant maxRetainDate); diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/BuildDao.java b/service/src/main/java/org/kiwiproject/champagne/dao/BuildDao.java index cb8a54c2..c720ab17 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/BuildDao.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/BuildDao.java @@ -15,66 +15,66 @@ public interface BuildDao { - default List findPagedBuilds(int offset, int limit, String componentIdentifierFilter, String componentVersionFilter) { + default List findPagedBuilds(int offset, int limit, Long systemId, String componentIdentifierFilter, String componentVersionFilter) { if (isBlank(componentIdentifierFilter) && isBlank(componentVersionFilter)) { // No filtering - return findPagedBuildsNoFilter(offset, limit); + return findPagedBuildsNoFilter(offset, limit, systemId); } else if (isBlank(componentIdentifierFilter)) { // Version only filter - return findPagedBuildsWithVersionFilter(offset, limit, f(LIKE_QUERY_FORMAT, componentVersionFilter)); + return findPagedBuildsWithVersionFilter(offset, limit, systemId, f(LIKE_QUERY_FORMAT, componentVersionFilter)); } else if (isBlank(componentVersionFilter)) { // Name only filter - return findPagedBuildsWithIdentiferFilter(offset, limit, f(LIKE_QUERY_FORMAT, componentIdentifierFilter)); + return findPagedBuildsWithIdentiferFilter(offset, limit, systemId, f(LIKE_QUERY_FORMAT, componentIdentifierFilter)); } // Both name and version filtering - return findPagedBuildsWithVersionAndIdentifierFilters(offset, limit, componentIdentifierFilter, componentVersionFilter); + return findPagedBuildsWithVersionAndIdentifierFilters(offset, limit, systemId, componentIdentifierFilter, componentVersionFilter); } - @SqlQuery("select * from builds order by created_at desc offset :offset limit :limit") - List findPagedBuildsNoFilter(@Bind("offset") int offset, @Bind("limit") int limit); + @SqlQuery("select * from builds where deployable_system_id = :systemId order by created_at desc offset :offset limit :limit") + List findPagedBuildsNoFilter(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("systemId") Long systemId); - @SqlQuery("select * from builds where component_version like :version order by created_at desc offset :offset limit :limit") - List findPagedBuildsWithVersionFilter(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("version") String componentVersionFilter); + @SqlQuery("select * from builds where builds.deployable_system_id = :systemId and component_version like :version order by created_at desc offset :offset limit :limit") + List findPagedBuildsWithVersionFilter(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("systemId") Long systemId, @Bind("version") String componentVersionFilter); - @SqlQuery("select * from builds where component_identifier like :identifier order by created_at desc offset :offset limit :limit") - List findPagedBuildsWithIdentiferFilter(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("identifier") String componentIdentifierFilter); + @SqlQuery("select * from builds where builds.deployable_system_id = :systemId and component_identifier like :identifier order by created_at desc offset :offset limit :limit") + List findPagedBuildsWithIdentiferFilter(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("systemId") Long systemId, @Bind("identifier") String componentIdentifierFilter); - @SqlQuery("select * from builds where component_version like :version and component_identifier like :identifier order by created_at desc offset :offset limit :limit") - List findPagedBuildsWithVersionAndIdentifierFilters(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("identifier") String componentIdentifierFilter, @Bind("version") String componentVersionFilter); + @SqlQuery("select * from builds where builds.deployable_system_id = :systemId and component_version like :version and component_identifier like :identifier order by created_at desc offset :offset limit :limit") + List findPagedBuildsWithVersionAndIdentifierFilters(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("systemId") Long systemId, @Bind("identifier") String componentIdentifierFilter, @Bind("version") String componentVersionFilter); - default long countBuilds(String componentIdentifierFilter, String componentVersionFilter) { + default long countBuilds(Long systemId, String componentIdentifierFilter, String componentVersionFilter) { if (isBlank(componentIdentifierFilter) && isBlank(componentVersionFilter)) { // No filtering - return countBuildsNoFilter(); + return countBuildsNoFilter(systemId); } else if (isBlank(componentIdentifierFilter)) { // Version only filter - return countBuildsWithVersionFilter(componentVersionFilter); + return countBuildsWithVersionFilter(systemId, componentVersionFilter); } else if (isBlank(componentVersionFilter)) { // Name only filter - return countBuildsWithIdentifierFilter(componentIdentifierFilter); + return countBuildsWithIdentifierFilter(systemId, componentIdentifierFilter); } // Both name and version filtering - return countBuildsWithVersionAndIdentifierFilters(componentVersionFilter, componentIdentifierFilter); + return countBuildsWithVersionAndIdentifierFilters(systemId, componentVersionFilter, componentIdentifierFilter); } - @SqlQuery("select count(*) from builds") - long countBuildsNoFilter(); + @SqlQuery("select count(*) from builds where deployable_system_id = :systemId") + long countBuildsNoFilter(@Bind("systemId") Long systemId); - @SqlQuery("select count(*) from builds where component_version like :version") - long countBuildsWithVersionFilter(@Bind("version") String componentVersionFilter); + @SqlQuery("select count(*) from builds where builds.deployable_system_id = :systemId and component_version like :version") + long countBuildsWithVersionFilter(@Bind("systemId") Long systemId, @Bind("version") String componentVersionFilter); - @SqlQuery("select count(*) from builds where component_identifier like :identifier") - long countBuildsWithIdentifierFilter(@Bind("identifier") String componentIdentifierFilter); + @SqlQuery("select count(*) from builds where builds.deployable_system_id = :systemId and component_identifier like :identifier") + long countBuildsWithIdentifierFilter(@Bind("systemId") Long systemId, @Bind("identifier") String componentIdentifierFilter); - @SqlQuery("select count(*) from builds where component_version like :version and component_identifier like :identifier") - long countBuildsWithVersionAndIdentifierFilters(@Bind("version") String componentVersionFilter, @Bind("identifier") String componentIdentifierFilter); + @SqlQuery("select count(*) from builds where builds.deployable_system_id = :systemId and component_version like :version and component_identifier like :identifier") + long countBuildsWithVersionAndIdentifierFilters(@Bind("systemId") Long systemId, @Bind("version") String componentVersionFilter, @Bind("identifier") String componentIdentifierFilter); @SqlUpdate("insert into builds " - + "(repo_namespace, repo_name, commit_ref, commit_user, source_branch, component_identifier, component_version, distribution_location, extra_deployment_info, change_log, git_provider) " + + "(repo_namespace, repo_name, commit_ref, commit_user, source_branch, component_identifier, component_version, distribution_location, extra_deployment_info, change_log, git_provider, deployable_system_id) " + "values " - + "(:repoNamespace, :repoName, :commitRef, :commitUser, :sourceBranch, :componentIdentifier, :componentVersion, :distributionLocation, :extraData, :changeLog, :gitProvider)") + + "(:repoNamespace, :repoName, :commitRef, :commitUser, :sourceBranch, :componentIdentifier, :componentVersion, :distributionLocation, :extraData, :changeLog, :gitProvider, :deployableSystemId)") @GetGeneratedKeys long insertBuild(@BindBean Build build, @Bind("extraData") String extraDataJson); } diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/DeployableSystemDao.java b/service/src/main/java/org/kiwiproject/champagne/dao/DeployableSystemDao.java index 7a179b02..17acc4de 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/DeployableSystemDao.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/DeployableSystemDao.java @@ -40,4 +40,7 @@ public interface DeployableSystemDao { @SqlQuery("select system_admin from users_deployable_systems where user_id = :userId and deployable_system_id = :systemId") boolean isUserAdminOfSystem(@Bind("userId") long userId, @Bind("systemId") long systemId); + + @SqlQuery("select true from users_deployable_systems uds join users u on u.id = uds.user_id join deployable_systems ds on ds.id = uds.deployable_system_id where u.system_identifier = :userName and ds.id = :systemId") + boolean isUserBySystemIdentifierInSystem(@Bind("userName") String systemIdentifier, @Bind("systemId") long systemId); } diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDao.java b/service/src/main/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDao.java index 906bf5eb..e0438fdb 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDao.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDao.java @@ -13,15 +13,15 @@ @RegisterRowMapper(DeploymentEnvironmentMapper.class) public interface DeploymentEnvironmentDao { - @SqlUpdate("insert into deployment_environments (environment_name) values (:name)") + @SqlUpdate("insert into deployment_environments (environment_name, deployable_system_id) values (:name, :deployableSystemId)") @GetGeneratedKeys long insertEnvironment(@BindBean DeploymentEnvironment env); @SqlUpdate("update deployment_environments set environment_name = :name, updated_at = current_timestamp where id = :id") int updateEnvironment(@BindBean DeploymentEnvironment env); - @SqlQuery("select * from deployment_environments") - List findAllEnvironments(); + @SqlQuery("select * from deployment_environments where deployable_system_id = :systemId") + List findAllEnvironments(@Bind("systemId") Long systemId); @SqlUpdate("delete from deployment_environments where id = :id") int hardDeleteById(@Bind("id") long id); diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/HostDao.java b/service/src/main/java/org/kiwiproject/champagne/dao/HostDao.java index 73378be8..ad355987 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/HostDao.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/HostDao.java @@ -15,10 +15,10 @@ @RegisterRowMapper(HostMapper.class) public interface HostDao { - @SqlQuery("select * from hosts where environment_id = :envId") - List findHostsByEnvId(@Bind("envId") Long envId); + @SqlQuery("select * from hosts where environment_id = :envId and deployable_system_id = :systemId") + List findHostsByEnvId(@Bind("envId") Long envId, @Bind("systemId") Long systemId); - @SqlUpdate("insert into hosts (environment_id, hostname, tags, source) values (:environmentId, :hostname, :tagCsv, :source)") + @SqlUpdate("insert into hosts (environment_id, hostname, tags, source, deployable_system_id) values (:environmentId, :hostname, :tagCsv, :source, :deployableSystemId)") @GetGeneratedKeys long insertHost(@BindBean Host host, @Bind("tagCsv") String tagCsv); diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/ReleaseDao.java b/service/src/main/java/org/kiwiproject/champagne/dao/ReleaseDao.java index c59a26ad..3d8de61a 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/ReleaseDao.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/ReleaseDao.java @@ -14,15 +14,15 @@ @RegisterRowMapper(ReleaseMapper.class) public interface ReleaseDao { - @SqlUpdate("insert into manual_deployment_task_releases (release_number) values (:releaseNumber)") + @SqlUpdate("insert into manual_deployment_task_releases (release_number, deployable_system_id) values (:releaseNumber, :deployableSystemId)") @GetGeneratedKeys long insertRelease(@BindBean Release release); - @SqlQuery("select count(*) from manual_deployment_task_releases") - long countReleases(); + @SqlQuery("select count(*) from manual_deployment_task_releases where deployable_system_id = :systemId") + long countReleases(@Bind("systemId") long systemId); - @SqlQuery("select * from manual_deployment_task_releases order by release_number desc offset :offset limit :limit") - List findPagedReleases(@Bind("offset") int offset, @Bind("limit") int limit); + @SqlQuery("select * from manual_deployment_task_releases where deployable_system_id = :systemId order by release_number desc offset :offset limit :limit") + List findPagedReleases(@Bind("offset") int offset, @Bind("limit") int limit, @Bind("systemId") long systemId); @SqlUpdate("delete from manual_deployment_task_releases where id = :id") void deleteById(@Bind("id") long id); diff --git a/service/src/main/java/org/kiwiproject/champagne/dao/mappers/AuditRecordMapper.java b/service/src/main/java/org/kiwiproject/champagne/dao/mappers/AuditRecordMapper.java index bb0fbabf..9e22bfaa 100644 --- a/service/src/main/java/org/kiwiproject/champagne/dao/mappers/AuditRecordMapper.java +++ b/service/src/main/java/org/kiwiproject/champagne/dao/mappers/AuditRecordMapper.java @@ -20,6 +20,7 @@ public AuditRecord map(ResultSet rs, StatementContext ctx) throws SQLException { .action(enumValueOrNull(rs, "action", AuditRecord.Action.class)) .recordType(rs.getString("record_type")) .recordId(rs.getLong("record_id")) + .deployableSystemId(rs.getLong("deployable_system_id")) .build(); } } diff --git a/service/src/main/java/org/kiwiproject/champagne/model/Build.java b/service/src/main/java/org/kiwiproject/champagne/model/Build.java index 556770a7..7f891ec5 100644 --- a/service/src/main/java/org/kiwiproject/champagne/model/Build.java +++ b/service/src/main/java/org/kiwiproject/champagne/model/Build.java @@ -7,6 +7,7 @@ import lombok.Builder; import lombok.Getter; +import lombok.With; /** * Model used to represent the build of a particular deployment artifact. @@ -42,5 +43,6 @@ public class Build { /** * The Deployable System that this build is tied to */ + @With Long deployableSystemId; } diff --git a/service/src/main/java/org/kiwiproject/champagne/model/Component.java b/service/src/main/java/org/kiwiproject/champagne/model/Component.java index 84fc563d..ae7f3a4c 100644 --- a/service/src/main/java/org/kiwiproject/champagne/model/Component.java +++ b/service/src/main/java/org/kiwiproject/champagne/model/Component.java @@ -4,6 +4,7 @@ import lombok.Builder; import lombok.Value; +import lombok.With; /** * Representation of a deployable component in the system. @@ -29,6 +30,7 @@ public class Component { /** * The Deployable System that this component is tied to */ + @With Long deployableSystemId; } diff --git a/service/src/main/java/org/kiwiproject/champagne/model/DeployableSystemThreadLocal.java b/service/src/main/java/org/kiwiproject/champagne/model/DeployableSystemThreadLocal.java index d7405009..c4311b7a 100644 --- a/service/src/main/java/org/kiwiproject/champagne/model/DeployableSystemThreadLocal.java +++ b/service/src/main/java/org/kiwiproject/champagne/model/DeployableSystemThreadLocal.java @@ -17,8 +17,8 @@ public static void setCurrentDeployableSystem(Long id) { THREAD_LOCAL.set(id); } - public static void clearCurrentDeployableSystem() { + public static void clearDeployableSystem() { THREAD_LOCAL.remove(); } - + } diff --git a/service/src/main/java/org/kiwiproject/champagne/model/DeploymentEnvironment.java b/service/src/main/java/org/kiwiproject/champagne/model/DeploymentEnvironment.java index 5dceca12..2a1b64bb 100644 --- a/service/src/main/java/org/kiwiproject/champagne/model/DeploymentEnvironment.java +++ b/service/src/main/java/org/kiwiproject/champagne/model/DeploymentEnvironment.java @@ -6,6 +6,7 @@ import lombok.Builder; import lombok.Value; +import lombok.With; /** * The core model used to track environments in the system (e.g. dev, test, production). @@ -32,6 +33,7 @@ public class DeploymentEnvironment { /** * The Deployable System that this env is tied to */ + @With Long deployableSystemId; } diff --git a/service/src/main/java/org/kiwiproject/champagne/model/Host.java b/service/src/main/java/org/kiwiproject/champagne/model/Host.java index e1773209..ca517e1a 100644 --- a/service/src/main/java/org/kiwiproject/champagne/model/Host.java +++ b/service/src/main/java/org/kiwiproject/champagne/model/Host.java @@ -5,6 +5,7 @@ import lombok.Builder; import lombok.Value; +import lombok.With; /** * Representation of a host used to deploy components. A Host could be created and stored in the database or @@ -45,5 +46,6 @@ public enum Source { /** * The Deployable System that this host is tied to */ + @With Long deployableSystemId; } diff --git a/service/src/main/java/org/kiwiproject/champagne/model/manualdeployment/Release.java b/service/src/main/java/org/kiwiproject/champagne/model/manualdeployment/Release.java index cb4c7dc8..b22abe11 100644 --- a/service/src/main/java/org/kiwiproject/champagne/model/manualdeployment/Release.java +++ b/service/src/main/java/org/kiwiproject/champagne/model/manualdeployment/Release.java @@ -8,6 +8,7 @@ import lombok.Builder; import lombok.Value; +import lombok.With; /** * The top-level container for all manual deployment tasks for a specific release. @@ -28,5 +29,6 @@ public class Release { /** * The Deployable System that this release is tied to */ + @With Long deployableSystemId; } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/AuditRecordResource.java b/service/src/main/java/org/kiwiproject/champagne/resource/AuditRecordResource.java index 39471e83..fd4a5b92 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/AuditRecordResource.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/AuditRecordResource.java @@ -14,6 +14,8 @@ import javax.ws.rs.core.Response; import org.kiwiproject.champagne.dao.AuditRecordDao; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; +import org.kiwiproject.jaxrs.exception.JaxrsBadRequestException; import org.kiwiproject.spring.data.KiwiPage; import com.codahale.metrics.annotation.ExceptionMetered; @@ -37,8 +39,11 @@ public class AuditRecordResource { public Response getPagedAudits(@QueryParam("pageNumber") @DefaultValue("1") int pageNumber, @QueryParam("pageSize") @DefaultValue("50") int pageSize) { - var audits = auditRecordDao.findPagedAuditRecords(zeroBasedOffset(pageNumber, pageSize), pageSize); - var totalCount = auditRecordDao.countAuditRecords(); + var systemId = DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); + + var audits = auditRecordDao.findPagedAuditRecords(zeroBasedOffset(pageNumber, pageSize), pageSize, systemId); + var totalCount = auditRecordDao.countAuditRecords(systemId); return Response.ok(KiwiPage.of(pageNumber, pageSize, totalCount, audits).usingOneAsFirstPage()).build(); } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/AuditableResource.java b/service/src/main/java/org/kiwiproject/champagne/resource/AuditableResource.java index 1b770428..6c630e85 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/AuditableResource.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/AuditableResource.java @@ -8,12 +8,13 @@ import org.kiwiproject.champagne.model.AuditRecord.Action; import lombok.extern.slf4j.Slf4j; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.dropwizard.error.ApplicationErrorThrower; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; @Slf4j public abstract class AuditableResource { - + private final AuditRecordDao auditRecordDao; private final ApplicationErrorThrower applicationErrorThrower; @@ -34,11 +35,12 @@ protected void auditAction(long recordId, Class recordClass, Action action) { } var auditRecord = AuditRecord.builder() - .recordId(recordId) - .recordType(recordClass.getSimpleName()) - .action(action) - .userSystemIdentifier(principal.getName()) - .build(); + .recordId(recordId) + .recordType(recordClass.getSimpleName()) + .action(action) + .userSystemIdentifier(principal.getName()) + .deployableSystemId(DeployableSystemThreadLocal.getCurrentDeployableSystem().orElse(null)) + .build(); auditRecordDao.insertAuditRecord(auditRecord); } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/BuildResource.java b/service/src/main/java/org/kiwiproject/champagne/resource/BuildResource.java index 9ca97c53..cc5b6a9e 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/BuildResource.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/BuildResource.java @@ -1,5 +1,6 @@ package org.kiwiproject.champagne.resource; +import static java.util.Objects.isNull; import static org.kiwiproject.search.KiwiSearching.zeroBasedOffset; import javax.annotation.security.PermitAll; @@ -14,6 +15,8 @@ import org.kiwiproject.champagne.dao.BuildDao; import org.kiwiproject.champagne.model.Build; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; +import org.kiwiproject.jaxrs.exception.JaxrsBadRequestException; import org.kiwiproject.json.JsonHelper; import org.kiwiproject.spring.data.KiwiPage; @@ -40,11 +43,14 @@ public Response listBuilds(@QueryParam("pageNumber") @DefaultValue("1") int page @QueryParam("pageSize") @DefaultValue("50") int pageSize, @QueryParam("componentIdentifierFilter") String componentIdentifierFilter, @QueryParam("componentVersionFilter") String componentVersionFilter) { + + var systemId = DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); var offset = zeroBasedOffset(pageNumber, pageSize); - var builds = buildDao.findPagedBuilds(offset, pageSize, componentIdentifierFilter, componentVersionFilter); - var total = buildDao.countBuilds(componentIdentifierFilter, componentVersionFilter); + var builds = buildDao.findPagedBuilds(offset, pageSize, systemId, componentIdentifierFilter, componentVersionFilter); + var total = buildDao.countBuilds(systemId, componentIdentifierFilter, componentVersionFilter); return Response.ok(KiwiPage.of(pageNumber, pageSize, total, builds)).build(); } @@ -53,6 +59,13 @@ public Response listBuilds(@QueryParam("pageNumber") @DefaultValue("1") int page @Timed @ExceptionMetered public Response recordNewBuild(Build build) { + + if (isNull(build.getDeployableSystemId())) { + var systemId = DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); + build = build.withDeployableSystemId(systemId); + } + buildDao.insertBuild(build, jsonHelper.toJson(build.getExtraDeploymentInfo())); return Response.accepted().build(); } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResource.java b/service/src/main/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResource.java index 26449536..3d0b2f47 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResource.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResource.java @@ -1,5 +1,6 @@ package org.kiwiproject.champagne.resource; +import static java.util.Objects.isNull; import static javax.ws.rs.core.MediaType.APPLICATION_JSON; import static org.kiwiproject.base.KiwiPreconditions.requireNotNull; @@ -17,6 +18,7 @@ import org.kiwiproject.champagne.dao.AuditRecordDao; import org.kiwiproject.champagne.dao.DeploymentEnvironmentDao; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.model.DeploymentEnvironment; import org.kiwiproject.champagne.model.AuditRecord.Action; import org.kiwiproject.champagne.service.ManualTaskService; @@ -24,6 +26,7 @@ import com.codahale.metrics.annotation.ExceptionMetered; import com.codahale.metrics.annotation.Timed; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; +import org.kiwiproject.jaxrs.exception.JaxrsBadRequestException; @Path("/environments") @Produces(APPLICATION_JSON) @@ -45,7 +48,10 @@ public DeploymentEnvironmentResource(DeploymentEnvironmentDao deploymentEnvironm @Timed @ExceptionMetered public Response listEnvironments() { - var envs = deploymentEnvironmentDao.findAllEnvironments(); + var systemId = DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); + + var envs = deploymentEnvironmentDao.findAllEnvironments(systemId); return Response.ok(envs).build(); } @@ -54,6 +60,12 @@ public Response listEnvironments() { @Timed @ExceptionMetered public Response createEnvironment(@Valid DeploymentEnvironment deploymentEnvironment) { + if (isNull(deploymentEnvironment.getDeployableSystemId())) { + var systemId = DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); + deploymentEnvironment = deploymentEnvironment.withDeployableSystemId(systemId); + } + var id = deploymentEnvironmentDao.insertEnvironment(deploymentEnvironment); auditAction(id, DeploymentEnvironment.class, Action.CREATED); diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/HostConfigurationResource.java b/service/src/main/java/org/kiwiproject/champagne/resource/HostConfigurationResource.java index 30af9215..550f67e1 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/HostConfigurationResource.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/HostConfigurationResource.java @@ -1,5 +1,6 @@ package org.kiwiproject.champagne.resource; +import static java.util.Objects.isNull; import static org.apache.commons.lang3.StringUtils.isBlank; import java.util.List; @@ -21,9 +22,11 @@ import org.kiwiproject.champagne.dao.ComponentDao; import org.kiwiproject.champagne.dao.HostDao; import org.kiwiproject.champagne.model.Component; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.model.Host; import org.kiwiproject.champagne.model.AuditRecord.Action; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; +import org.kiwiproject.jaxrs.exception.JaxrsBadRequestException; import org.kiwiproject.jaxrs.exception.JaxrsNotFoundException; import com.codahale.metrics.annotation.ExceptionMetered; @@ -50,7 +53,8 @@ public HostConfigurationResource(HostDao hostDao, ComponentDao componentDao, Aud @Timed @ExceptionMetered public Response listHostsForEnvironment(@PathParam("environment") Long envId, @QueryParam("componentFilter") String componentFilter) { - var hosts = isBlank(componentFilter) ? hostDao.findHostsByEnvId(envId) : List.of(); + var systemId = getSystemId(); + var hosts = isBlank(componentFilter) ? hostDao.findHostsByEnvId(envId, systemId) : List.of(); return Response.ok(hosts).build(); } @@ -59,6 +63,11 @@ public Response listHostsForEnvironment(@PathParam("environment") Long envId, @Q @Timed @ExceptionMetered public Response createHost(Host host) { + if (isNull(host.getDeployableSystemId())) { + var systemId = getSystemId(); + host = host.withDeployableSystemId(systemId); + } + var hostId = hostDao.insertHost(host, StringUtils.join(host.getTags(), ",")); auditAction(hostId, Host.class, Action.CREATED); @@ -96,6 +105,11 @@ public Response listComponentsForHost(@PathParam("hostId") Long hostId) { @Timed @ExceptionMetered public Response createComponent(Component component) { + if (isNull(component.getDeployableSystemId())) { + var systemId = getSystemId(); + component = component.withDeployableSystemId(systemId); + } + var componentId = componentDao.insertComponent(component); auditAction(componentId, Component.class, Action.CREATED); @@ -116,4 +130,9 @@ public Response deleteComponent(@PathParam("componentId") Long componentId) { return Response.accepted().build(); } + + private long getSystemId() { + return DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); + } } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/TaskResource.java b/service/src/main/java/org/kiwiproject/champagne/resource/TaskResource.java index 16ae255d..04925825 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/TaskResource.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/TaskResource.java @@ -1,5 +1,6 @@ package org.kiwiproject.champagne.resource; +import static java.util.Objects.isNull; import static java.util.function.Function.identity; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toMap; @@ -12,6 +13,7 @@ import com.google.common.annotations.VisibleForTesting; import org.kiwiproject.champagne.model.AuditRecord.Action; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.model.manualdeployment.DeploymentTaskStatus; import org.kiwiproject.champagne.model.manualdeployment.Release; import org.kiwiproject.champagne.model.manualdeployment.ReleaseStage; @@ -25,6 +27,7 @@ import org.kiwiproject.champagne.dao.TaskDao; import org.kiwiproject.champagne.dao.TaskStatusDao; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; +import org.kiwiproject.jaxrs.exception.JaxrsBadRequestException; import org.kiwiproject.jaxrs.exception.JaxrsNotFoundException; import org.kiwiproject.spring.data.KiwiPage; @@ -83,12 +86,13 @@ public TaskResource (ReleaseDao releaseDao, public Response getPagedReleases(@QueryParam("pageNumber") @DefaultValue("1") int pageNumber, @QueryParam("pageSize") @DefaultValue("50") int pageSize) { - var releases = releaseDao.findPagedReleases(zeroBasedOffset(pageNumber, pageSize), pageSize); + var systemId = getSystemId(); + var releases = releaseDao.findPagedReleases(zeroBasedOffset(pageNumber, pageSize), pageSize, systemId); var releasesWithStatus = releases.stream() .map(this::buildReleaseWithStatusFrom) .toList(); - var totalCount = releaseDao.countReleases(); + var totalCount = releaseDao.countReleases(systemId); return Response.ok(KiwiPage.of(pageNumber, pageSize, totalCount, releasesWithStatus).usingOneAsFirstPage()).build(); } @@ -131,10 +135,17 @@ private TaskWithStatus buildTaskWithStatusFrom(Task task) { @Timed @ExceptionMetered public Response addNewRelease(@Valid @NotNull Release release) { + var systemId = release.getDeployableSystemId(); + + if (isNull(release.getDeployableSystemId())) { + systemId = getSystemId(); + release = release.withDeployableSystemId(systemId); + } + var releaseId = releaseDao.insertRelease(release); auditAction(releaseId, Release.class, Action.CREATED); - deploymentEnvironmentDao.findAllEnvironments().forEach(env -> { + deploymentEnvironmentDao.findAllEnvironments(systemId).forEach(env -> { var status = ReleaseStatus.builder() .releaseId(releaseId) .environmentId(env.getId()) @@ -152,10 +163,11 @@ public Response addNewRelease(@Valid @NotNull Release release) { @Timed @ExceptionMetered public Response addNewTask(@Valid @NotNull Task task) { + var systemId = getSystemId(); var taskId = taskDao.insertTask(task); auditAction(taskId, Task.class, Action.CREATED); - deploymentEnvironmentDao.findAllEnvironments().forEach(env -> { + deploymentEnvironmentDao.findAllEnvironments(systemId).forEach(env -> { var status = TaskStatus.builder() .taskId(taskId) .environmentId(env.getId()) @@ -300,4 +312,9 @@ public Response deleteTask(@PathParam("taskId") long taskId) { public Response getReleaseStages() { return Response.ok(ReleaseStage.values()).build(); } + + private long getSystemId() { + return DeployableSystemThreadLocal.getCurrentDeployableSystem() + .orElseThrow(() -> new JaxrsBadRequestException("Missing deployable system")); + } } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilter.java b/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilter.java index 2d4efe2c..f8fc7d00 100644 --- a/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilter.java +++ b/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilter.java @@ -1,25 +1,32 @@ package org.kiwiproject.champagne.resource.filter; -import java.io.IOException; +import org.apache.commons.lang3.StringUtils; +import org.kiwiproject.champagne.dao.DeployableSystemDao; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; -import org.apache.commons.lang3.StringUtils; -import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; - public class DeployableSystemRequestFilter implements ContainerRequestFilter { private static final String DEPLOYABLE_SYSTEM_HEADER_NAME = "DeployableSystem"; + private final DeployableSystemDao deployableSystemDao; + + public DeployableSystemRequestFilter(DeployableSystemDao deployableSystemDao) { + this.deployableSystemDao = deployableSystemDao; + } + @Override - public void filter(ContainerRequestContext requestContext) throws IOException { + public void filter(ContainerRequestContext requestContext) { var system = requestContext.getHeaderString(DEPLOYABLE_SYSTEM_HEADER_NAME); - // TODO: Need to validate that user is in system - if (StringUtils.isNotBlank(system)) { - DeployableSystemThreadLocal.setCurrentDeployableSystem(Long.valueOf(system)); + var userName = requestContext.getSecurityContext().getUserPrincipal().getName(); + + if (deployableSystemDao.isUserBySystemIdentifierInSystem(userName, Long.parseLong(system))) { + DeployableSystemThreadLocal.setCurrentDeployableSystem(Long.valueOf(system)); + } } } diff --git a/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemResponseFilter.java b/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemResponseFilter.java new file mode 100644 index 00000000..3721f440 --- /dev/null +++ b/service/src/main/java/org/kiwiproject/champagne/resource/filter/DeployableSystemResponseFilter.java @@ -0,0 +1,15 @@ +package org.kiwiproject.champagne.resource.filter; + +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; + +public class DeployableSystemResponseFilter implements ContainerResponseFilter { + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) { + DeployableSystemThreadLocal.clearDeployableSystem(); + } +} diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/AuditRecordDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/AuditRecordDaoTest.java index 6fa7af97..8949b7b1 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/AuditRecordDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/AuditRecordDaoTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.kiwiproject.champagne.util.TestObjects.insertAuditRecord; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import org.jdbi.v3.core.Handle; import org.junit.jupiter.api.BeforeEach; @@ -42,11 +43,14 @@ class InsertAuditRecord { @Test void shouldInsertAuditRecordSuccessfully() { + insertDeployableSystem(handle, "kiwi"); + var auditRecordToInsert = AuditRecord.builder() .action(AuditRecord.Action.CREATED) .userSystemIdentifier("jdoe") .recordType("User") .recordId(1L) + .deployableSystemId(1L) .build(); var id = dao.insertAuditRecord(auditRecordToInsert); @@ -71,17 +75,19 @@ class FindPagedAuditRecords { @Test void shouldReturnListOfAuditRecords() { - insertAuditRecord(handle); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertAuditRecord(handle, systemId); - var audits = dao.findPagedAuditRecords(0, 10); + var audits = dao.findPagedAuditRecords(0, 10, systemId); assertThat(audits).hasSize(1); } @Test void shouldReturnEmptyListWhenNoAuditRecordsFound() { - insertAuditRecord(handle); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertAuditRecord(handle, systemId); - var audits = dao.findPagedAuditRecords(10, 10); + var audits = dao.findPagedAuditRecords(10, 10, systemId); assertThat(audits).isEmpty(); } } @@ -91,15 +97,16 @@ class CountAuditRecords { @Test void shouldReturnCountOfAuditRecords() { - insertAuditRecord(handle); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertAuditRecord(handle, systemId); - var count = dao.countAuditRecords(); + var count = dao.countAuditRecords(systemId); assertThat(count).isOne(); } @Test void shouldReturnZeroWhenNoAuditRecordsFound() { - var count = dao.countAuditRecords(); + var count = dao.countAuditRecords(1L); assertThat(count).isZero(); } } @@ -109,7 +116,8 @@ class DeleteAuditRecordsOlderThan { @Test void shouldDeleteFoundRecords() { - insertAuditRecord(handle); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertAuditRecord(handle, systemId); var deleteDate = Instant.now().plusSeconds(60); diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/BuildDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/BuildDaoTest.java index 9ef876be..07970468 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/BuildDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/BuildDaoTest.java @@ -3,6 +3,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; import static org.kiwiproject.champagne.util.TestObjects.insertBuildRecord; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.constants.KiwiTestConstants.JSON_HELPER; import static org.kiwiproject.test.util.DateTimeTestHelper.assertTimeDifferenceWithinTolerance; @@ -103,9 +104,10 @@ class FindPagedBuilds { "champagne-service, 42.0" }) void shouldReturnListOfBuilds(String componentIdentifierFilter, String componentVersionFilter) { - insertBuildRecord(handle, "champagne-service", "42.0"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertBuildRecord(handle, "champagne-service", "42.0", systemId); - var builds = dao.findPagedBuilds(0, 10, componentIdentifierFilter, componentVersionFilter); + var builds = dao.findPagedBuilds(0, 10, systemId, componentIdentifierFilter, componentVersionFilter); assertThat(builds) .extracting("componentIdentifier", "componentVersion") .contains(tuple("champagne-service", "42.0")); @@ -113,9 +115,10 @@ void shouldReturnListOfBuilds(String componentIdentifierFilter, String component @Test void shouldReturnEmptyListWhenNoBuildsFound() { - insertBuildRecord(handle, "champagne-service", "42.0"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertBuildRecord(handle, "champagne-service", "42.0", systemId); - var builds = dao.findPagedBuilds(10, 10, null, null); + var builds = dao.findPagedBuilds(10, 10, systemId, null, null); assertThat(builds).isEmpty(); } } @@ -131,15 +134,16 @@ class CountBuilds { "champagne-service, 42.0" }) void shouldReturnCountOfBuilds(String componentIdentifierFilter, String componentVersionFilter) { - insertBuildRecord(handle, "champagne-service", "42.0"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertBuildRecord(handle, "champagne-service", "42.0", systemId); - var builds = dao.countBuilds(componentIdentifierFilter, componentVersionFilter); + var builds = dao.countBuilds(systemId, componentIdentifierFilter, componentVersionFilter); assertThat(builds).isOne(); } @Test void shouldReturnEmptyListWhenNoBuildsFound() { - var builds = dao.countBuilds(null, null); + var builds = dao.countBuilds(1L, null, null); assertThat(builds).isZero(); } } diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/DeployableSystemDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/DeployableSystemDaoTest.java index 9ccb7cd9..d460c428 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/DeployableSystemDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/DeployableSystemDaoTest.java @@ -139,7 +139,8 @@ class UpdateDevEnvironment { @Test void shouldUpdateTheDevEnvOfAGivenRecord() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); var deployableSystemId = insertDeployableSystem(handle, "kiwi"); dao.updateDevEnvironment(deployableSystemId, envId); diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDaoTest.java index 6eceb4ca..19b81352 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/DeploymentEnvironmentDaoTest.java @@ -1,21 +1,19 @@ package org.kiwiproject.champagne.dao; import static org.assertj.core.api.Assertions.assertThat; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.champagne.util.TestObjects.insertDeploymentEnvironmentRecord; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.util.DateTimeTestHelper.assertTimeDifferenceWithinTolerance; -import org.assertj.core.api.SoftAssertions; -import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; import org.jdbi.v3.core.Handle; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.junit.jupiter.api.extension.RegisterExtension; -import org.kiwiproject.champagne.model.DeploymentEnvironment; import org.kiwiproject.champagne.dao.mappers.DeploymentEnvironmentMapper; +import org.kiwiproject.champagne.model.DeploymentEnvironment; import org.kiwiproject.test.junit.jupiter.Jdbi3DaoExtension; import org.kiwiproject.test.junit.jupiter.PostgresLiquibaseTestExtension; @@ -23,7 +21,6 @@ import java.time.ZonedDateTime; @DisplayName("DeploymentEnvironmentDao") -@ExtendWith(SoftAssertionsExtension.class) class DeploymentEnvironmentDaoTest { @RegisterExtension @@ -78,7 +75,8 @@ class UpdateUser { @Test void shouldUpdateDeploymentEnvironmentSuccessfully() { - long envId = insertDeploymentEnvironmentRecord(handle, "TEST"); + var systemId = insertDeployableSystem(handle, "kiwi"); + long envId = insertDeploymentEnvironmentRecord(handle, "TEST", systemId); var envToUpdate = DeploymentEnvironment.builder() .id(envId) @@ -103,9 +101,10 @@ class FindAllEnvironments { @Test void shouldReturnListOfDeploymentEnvironments() { - insertDeploymentEnvironmentRecord(handle, "DEV"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertDeploymentEnvironmentRecord(handle, "DEV", systemId); - var environments = dao.findAllEnvironments(); + var environments = dao.findAllEnvironments(systemId); assertThat(environments) .extracting("name") .contains("DEV"); @@ -113,7 +112,7 @@ void shouldReturnListOfDeploymentEnvironments() { @Test void shouldReturnEmptyListWhenNoDeploymentEnvironmentsFound() { - var environments = dao.findAllEnvironments(); + var environments = dao.findAllEnvironments(1L); assertThat(environments).isEmpty(); } } @@ -123,7 +122,8 @@ class HardDeleteById { @Test void shouldDeleteDeploymentEnvironmentSuccessfully() { - long envId = insertDeploymentEnvironmentRecord(handle, "TRAINING"); + var systemId = insertDeployableSystem(handle, "kiwi"); + long envId = insertDeploymentEnvironmentRecord(handle, "TRAINING", systemId); dao.hardDeleteById(envId); @@ -137,8 +137,9 @@ void shouldDeleteDeploymentEnvironmentSuccessfully() { class SoftDeleteById { @Test - void shouldSoftDeleteDeploymentEnvironmentSuccessfully(SoftAssertions softly) { - var id = insertDeploymentEnvironmentRecord(handle, "TEST"); + void shouldSoftDeleteDeploymentEnvironmentSuccessfully() { + var systemId = insertDeployableSystem(handle, "kiwi"); + var id = insertDeploymentEnvironmentRecord(handle, "TEST", systemId); dao.softDeleteById(id); @@ -149,8 +150,8 @@ void shouldSoftDeleteDeploymentEnvironmentSuccessfully(SoftAssertions softly) { assertThat(envs).hasSize(1); var user = first(envs); - softly.assertThat(user.getId()).isEqualTo(id); - softly.assertThat(user.isDeleted()).isEqualTo(true); + assertThat(user.getId()).isEqualTo(id); + assertThat(user.isDeleted()).isTrue(); } } @@ -159,8 +160,9 @@ void shouldSoftDeleteDeploymentEnvironmentSuccessfully(SoftAssertions softly) { class UnDeleteById { @Test - void shouldUnDeleteDeploymentEnvironmentSuccessfully(SoftAssertions softly) { - var id = insertDeploymentEnvironmentRecord(handle, "TEST"); + void shouldUnDeleteDeploymentEnvironmentSuccessfully() { + var systemId = insertDeployableSystem(handle, "kiwi"); + var id = insertDeploymentEnvironmentRecord(handle, "TEST", systemId); handle.execute("update deployment_environments set deleted=true where id = ?", id); dao.unSoftDeleteById(id); @@ -172,8 +174,8 @@ void shouldUnDeleteDeploymentEnvironmentSuccessfully(SoftAssertions softly) { assertThat(envs).hasSize(1); var user = first(envs); - softly.assertThat(user.getId()).isEqualTo(id); - softly.assertThat(user.isDeleted()).isEqualTo(false); + assertThat(user.getId()).isEqualTo(id); + assertThat(user.isDeleted()).isFalse(); } } diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/HostDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/HostDaoTest.java index 62832f84..f3e708b9 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/HostDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/HostDaoTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.champagne.util.TestObjects.insertDeploymentEnvironmentRecord; import static org.kiwiproject.champagne.util.TestObjects.insertHostRecord; import static org.kiwiproject.collect.KiwiLists.first; @@ -49,7 +50,8 @@ class InsertHost { @Test void shouldInsertHostSuccessfully() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); var beforeInsert = ZonedDateTime.now(); var hostToInsert = Host.builder() @@ -85,10 +87,11 @@ class FindHostsByEnvId { @Test void shouldReturnListOfHosts() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); - var hostId = insertHostRecord(handle, "localhost", envId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); + var hostId = insertHostRecord(handle, "localhost", envId, systemId); - var hosts = dao.findHostsByEnvId(envId); + var hosts = dao.findHostsByEnvId(envId, systemId); assertThat(hosts) .extracting("id", "hostname", "environmentId") .contains(tuple(hostId, "localhost", envId)); @@ -96,11 +99,12 @@ void shouldReturnListOfHosts() { @Test void shouldReturnEmptyListWhenNoHostsFound() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); - var envId2 = insertDeploymentEnvironmentRecord(handle, "test"); - insertHostRecord(handle, "localhost", envId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); + var envId2 = insertDeploymentEnvironmentRecord(handle, "test", systemId); + insertHostRecord(handle, "localhost", envId, systemId); - var hosts = dao.findHostsByEnvId(envId2); + var hosts = dao.findHostsByEnvId(envId2, systemId); assertThat(hosts).isEmpty(); } } @@ -110,8 +114,9 @@ class DeleteHost { @Test void shouldDeleteHostSuccessfully() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); - var hostId = insertHostRecord(handle, "localhost", envId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); + var hostId = insertHostRecord(handle, "localhost", envId, systemId); dao.deleteHost(hostId); @@ -126,8 +131,9 @@ class FindById { @Test void shouldReturnHostWhenFound() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); - var hostId = insertHostRecord(handle, "localhost", envId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); + var hostId = insertHostRecord(handle, "localhost", envId, systemId); var host = dao.findById(hostId).orElseThrow(); @@ -138,8 +144,9 @@ void shouldReturnHostWhenFound() { @Test void shouldReturnEmptyWhenNoHostFound() { - var envId = insertDeploymentEnvironmentRecord(handle, "dev"); - insertHostRecord(handle, "localhost", envId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var envId = insertDeploymentEnvironmentRecord(handle, "dev", systemId); + insertHostRecord(handle, "localhost", envId, systemId); var hosts = dao.findById(0L); assertThat(hosts).isEmpty(); diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseDaoTest.java index b8976719..bc8b90a2 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseDaoTest.java @@ -1,29 +1,26 @@ package org.kiwiproject.champagne.dao; import static org.assertj.core.api.Assertions.assertThat; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.champagne.util.TestObjects.insertReleaseRecord; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.util.DateTimeTestHelper.assertTimeDifferenceWithinTolerance; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -import org.assertj.core.api.SoftAssertions; -import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; import org.jdbi.v3.core.Handle; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import org.kiwiproject.champagne.model.manualdeployment.Release; import org.kiwiproject.champagne.dao.mappers.ReleaseMapper; +import org.kiwiproject.champagne.model.manualdeployment.Release; import org.kiwiproject.test.junit.jupiter.Jdbi3DaoExtension; import org.kiwiproject.test.junit.jupiter.PostgresLiquibaseTestExtension; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + @DisplayName("ReleaseDao") -@ExtendWith(SoftAssertionsExtension.class) class ReleaseDaoTest { @RegisterExtension @@ -48,7 +45,7 @@ void setUp() { class InsertRelease { @Test - void shouldInsertReleaseSuccessfully(SoftAssertions softly) { + void shouldInsertReleaseSuccessfully() { var beforeInsert = ZonedDateTime.now(); var releaseToInsert = Release.builder() @@ -64,12 +61,12 @@ void shouldInsertReleaseSuccessfully(SoftAssertions softly) { assertThat(releases).hasSize(1); var release = first(releases); - softly.assertThat(release.getId()).isEqualTo(id); + assertThat(release.getId()).isEqualTo(id); - assertTimeDifferenceWithinTolerance(softly, "createdAt", beforeInsert, release.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); - assertTimeDifferenceWithinTolerance(softly, "updatedAt", beforeInsert, release.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("createdAt", beforeInsert, release.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("updatedAt", beforeInsert, release.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); - softly.assertThat(release.getReleaseNumber()).isEqualTo("2023.42.0"); + assertThat(release.getReleaseNumber()).isEqualTo("2023.42.0"); } } @@ -78,9 +75,10 @@ class FindPagedReleases { @Test void shouldReturnListOfReleases() { - insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertReleaseRecord(handle, "42", systemId); - var releases = dao.findPagedReleases(0, 10); + var releases = dao.findPagedReleases(0, 10, systemId); assertThat(releases) .extracting("releaseNumber") .contains("42"); @@ -88,9 +86,10 @@ void shouldReturnListOfReleases() { @Test void shouldReturnEmptyListWhenNoReleasesFound() { - insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertReleaseRecord(handle, "42", systemId); - var releases = dao.findPagedReleases(10, 10); + var releases = dao.findPagedReleases(10, 10, systemId); assertThat(releases).isEmpty(); } } @@ -100,15 +99,16 @@ class CountReleases { @Test void shouldReturnCountOfReleases() { - insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + insertReleaseRecord(handle, "42", systemId); - var releases = dao.countReleases(); + var releases = dao.countReleases(systemId); assertThat(releases).isOne(); } @Test void shouldReturnEmptyListWhenNoReleasesFound() { - var releases = dao.countReleases(); + var releases = dao.countReleases(1L); assertThat(releases).isZero(); } } @@ -118,7 +118,8 @@ class DeleteById { @Test void shouldDeleteReleaseSuccessfully() { - var id = insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var id = insertReleaseRecord(handle, "42", systemId); dao.deleteById(id); @@ -136,7 +137,8 @@ class FindAllReleaseIds { @Test void shouldReturnListOfReleaseIds() { - var releaseId = insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); var releaseIds = dao.findAllReleaseIds(); assertThat(releaseIds).contains(releaseId); diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseStatusDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseStatusDaoTest.java index 437d0d16..11a03688 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseStatusDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/ReleaseStatusDaoTest.java @@ -1,32 +1,29 @@ package org.kiwiproject.champagne.dao; import static org.assertj.core.api.Assertions.assertThat; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.champagne.util.TestObjects.insertDeploymentEnvironmentRecord; import static org.kiwiproject.champagne.util.TestObjects.insertReleaseRecord; import static org.kiwiproject.champagne.util.TestObjects.insertReleaseStatusRecord; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.util.DateTimeTestHelper.assertTimeDifferenceWithinTolerance; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -import org.assertj.core.api.SoftAssertions; -import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; import org.jdbi.v3.core.Handle; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.kiwiproject.champagne.dao.mappers.ReleaseStatusMapper; import org.kiwiproject.champagne.model.manualdeployment.DeploymentTaskStatus; import org.kiwiproject.champagne.model.manualdeployment.ReleaseStatus; -import org.kiwiproject.champagne.dao.mappers.ReleaseStatusMapper; import org.kiwiproject.test.junit.jupiter.Jdbi3DaoExtension; import org.kiwiproject.test.junit.jupiter.PostgresLiquibaseTestExtension; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + @DisplayName("ReleaseStatusDao") -@ExtendWith(SoftAssertionsExtension.class) class ReleaseStatusDaoTest { @RegisterExtension @@ -51,11 +48,12 @@ void setUp() { class InsertReleaseStatus { @Test - void shouldInsertReleaseStatusSuccessfully(SoftAssertions softly) { + void shouldInsertReleaseStatusSuccessfully() { var beforeInsert = ZonedDateTime.now(); - var releaseId = insertReleaseRecord(handle, "42"); - var envId = insertDeploymentEnvironmentRecord(handle, "TEST"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); + var envId = insertDeploymentEnvironmentRecord(handle, "TEST", systemId); var releaseStatusToInsert = ReleaseStatus.builder() .environmentId(envId) @@ -72,14 +70,14 @@ void shouldInsertReleaseStatusSuccessfully(SoftAssertions softly) { assertThat(releaseStatuses).hasSize(1); var status = first(releaseStatuses); - softly.assertThat(status.getId()).isEqualTo(id); + assertThat(status.getId()).isEqualTo(id); - assertTimeDifferenceWithinTolerance(softly, "createdAt", beforeInsert, status.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); - assertTimeDifferenceWithinTolerance(softly, "updatedAt", beforeInsert, status.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("createdAt", beforeInsert, status.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("updatedAt", beforeInsert, status.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); - softly.assertThat(status.getEnvironmentId()).isEqualTo(envId); - softly.assertThat(status.getReleaseId()).isEqualTo(releaseId); - softly.assertThat(status.getStatus()).isEqualTo(DeploymentTaskStatus.PENDING); + assertThat(status.getEnvironmentId()).isEqualTo(envId); + assertThat(status.getReleaseId()).isEqualTo(releaseId); + assertThat(status.getStatus()).isEqualTo(DeploymentTaskStatus.PENDING); } } @@ -88,8 +86,9 @@ class FindByReleaseId { @Test void shouldReturnListOfReleaseStatuses() { - var releaseId = insertReleaseRecord(handle, "42"); - insertReleaseStatusRecord(handle, DeploymentTaskStatus.PENDING, releaseId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); + insertReleaseStatusRecord(handle, DeploymentTaskStatus.PENDING, releaseId, systemId); var statuses = dao.findByReleaseId(releaseId); assertThat(statuses) diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/TaskDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/TaskDaoTest.java index 6cb5321a..f6d56bda 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/TaskDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/TaskDaoTest.java @@ -1,33 +1,30 @@ package org.kiwiproject.champagne.dao; import static org.assertj.core.api.Assertions.assertThat; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.champagne.util.TestObjects.insertReleaseRecord; import static org.kiwiproject.champagne.util.TestObjects.insertTaskRecord; import static org.kiwiproject.champagne.util.TestObjects.insertTaskStatusRecord; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.util.DateTimeTestHelper.assertTimeDifferenceWithinTolerance; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -import org.assertj.core.api.SoftAssertions; -import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; import org.jdbi.v3.core.Handle; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.kiwiproject.champagne.dao.mappers.TaskMapper; import org.kiwiproject.champagne.model.manualdeployment.DeploymentTaskStatus; import org.kiwiproject.champagne.model.manualdeployment.ReleaseStage; import org.kiwiproject.champagne.model.manualdeployment.Task; -import org.kiwiproject.champagne.dao.mappers.TaskMapper; import org.kiwiproject.test.junit.jupiter.Jdbi3DaoExtension; import org.kiwiproject.test.junit.jupiter.PostgresLiquibaseTestExtension; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + @DisplayName("TaskDao") -@ExtendWith(SoftAssertionsExtension.class) class TaskDaoTest { @RegisterExtension @@ -52,10 +49,11 @@ void setUp() { class InsertTask { @Test - void shouldInsertTaskSuccessfully(SoftAssertions softly) { + void shouldInsertTaskSuccessfully() { var beforeInsert = ZonedDateTime.now(); - var releaseId = insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); var taskToInsert = Task.builder() .releaseId(releaseId) @@ -74,16 +72,16 @@ void shouldInsertTaskSuccessfully(SoftAssertions softly) { assertThat(tasks).hasSize(1); var task = first(tasks); - softly.assertThat(task.getId()).isEqualTo(id); + assertThat(task.getId()).isEqualTo(id); - assertTimeDifferenceWithinTolerance(softly, "createdAt", beforeInsert, task.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); - assertTimeDifferenceWithinTolerance(softly, "updatedAt", beforeInsert, task.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("createdAt", beforeInsert, task.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("updatedAt", beforeInsert, task.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); - softly.assertThat(task.getReleaseId()).isEqualTo(releaseId); - softly.assertThat(task.getStage()).isEqualTo(ReleaseStage.PRE); - softly.assertThat(task.getSummary()).isEqualTo("Do the things"); - softly.assertThat(task.getDescription()).isEqualTo("No really do all of it"); - softly.assertThat(task.getComponent()).isEqualTo("The best component"); + assertThat(task.getReleaseId()).isEqualTo(releaseId); + assertThat(task.getStage()).isEqualTo(ReleaseStage.PRE); + assertThat(task.getSummary()).isEqualTo("Do the things"); + assertThat(task.getDescription()).isEqualTo("No really do all of it"); + assertThat(task.getComponent()).isEqualTo("The best component"); } } @@ -93,7 +91,8 @@ class FindByReleaseId { @Test void shouldReturnListOfTasks() { - var releaseId = insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); insertTaskRecord(handle, "Sample", releaseId); var tasks = dao.findByReleaseId(releaseId); @@ -178,8 +177,9 @@ class FindByTaskStatusId { @Test void shouldFindTaskSuccessfully() { + var systemId = insertDeployableSystem(handle, "kiwi"); var id = insertTaskRecord(handle, "to be found"); - var statusId = insertTaskStatusRecord(handle, DeploymentTaskStatus.PENDING, id); + var statusId = insertTaskStatusRecord(handle, DeploymentTaskStatus.PENDING, id, systemId); var task = dao.findByTaskStatusId(statusId).orElseThrow(); assertThat(task.getId()).isEqualTo(id); diff --git a/service/src/test/java/org/kiwiproject/champagne/dao/TaskStatusDaoTest.java b/service/src/test/java/org/kiwiproject/champagne/dao/TaskStatusDaoTest.java index d6ed5640..8bfec2ef 100644 --- a/service/src/test/java/org/kiwiproject/champagne/dao/TaskStatusDaoTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/dao/TaskStatusDaoTest.java @@ -1,32 +1,29 @@ package org.kiwiproject.champagne.dao; import static org.assertj.core.api.Assertions.assertThat; +import static org.kiwiproject.champagne.util.TestObjects.insertDeployableSystem; import static org.kiwiproject.champagne.util.TestObjects.insertDeploymentEnvironmentRecord; import static org.kiwiproject.champagne.util.TestObjects.insertTaskRecord; import static org.kiwiproject.champagne.util.TestObjects.insertTaskStatusRecord; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.util.DateTimeTestHelper.assertTimeDifferenceWithinTolerance; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -import org.assertj.core.api.SoftAssertions; -import org.assertj.core.api.junit.jupiter.SoftAssertionsExtension; import org.jdbi.v3.core.Handle; -import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.kiwiproject.champagne.dao.mappers.TaskStatusMapper; import org.kiwiproject.champagne.model.manualdeployment.DeploymentTaskStatus; import org.kiwiproject.champagne.model.manualdeployment.TaskStatus; -import org.kiwiproject.champagne.dao.mappers.TaskStatusMapper; import org.kiwiproject.test.junit.jupiter.Jdbi3DaoExtension; import org.kiwiproject.test.junit.jupiter.PostgresLiquibaseTestExtension; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + @DisplayName("TaskStatusDao") -@ExtendWith(SoftAssertionsExtension.class) class TaskStatusDaoTest { @RegisterExtension @@ -51,11 +48,12 @@ void setUp() { class InsertTaskStatus { @Test - void shouldInsertTaskStatusSuccessfully(SoftAssertions softly) { + void shouldInsertTaskStatusSuccessfully() { var beforeInsert = ZonedDateTime.now(); + var systemId = insertDeployableSystem(handle, "kiwi"); var taskId = insertTaskRecord(handle, "Some task"); - var envId = insertDeploymentEnvironmentRecord(handle, "TEST"); + var envId = insertDeploymentEnvironmentRecord(handle, "TEST", systemId); var taskStatusToInsert = TaskStatus.builder() .environmentId(envId) @@ -72,14 +70,14 @@ void shouldInsertTaskStatusSuccessfully(SoftAssertions softly) { assertThat(taskStatuses).hasSize(1); var status = first(taskStatuses); - softly.assertThat(status.getId()).isEqualTo(id); + assertThat(status.getId()).isEqualTo(id); - assertTimeDifferenceWithinTolerance(softly, "createdAt", beforeInsert, status.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); - assertTimeDifferenceWithinTolerance(softly, "updatedAt", beforeInsert, status.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("createdAt", beforeInsert, status.getCreatedAt().atZone(ZoneOffset.UTC), 1000L); + assertTimeDifferenceWithinTolerance("updatedAt", beforeInsert, status.getUpdatedAt().atZone(ZoneOffset.UTC), 1000L); - softly.assertThat(status.getEnvironmentId()).isEqualTo(envId); - softly.assertThat(status.getTaskId()).isEqualTo(taskId); - softly.assertThat(status.getStatus()).isEqualTo(DeploymentTaskStatus.PENDING); + assertThat(status.getEnvironmentId()).isEqualTo(envId); + assertThat(status.getTaskId()).isEqualTo(taskId); + assertThat(status.getStatus()).isEqualTo(DeploymentTaskStatus.PENDING); } } @@ -88,8 +86,9 @@ class FindByTaskId { @Test void shouldReturnListOfTaskStatuses() { + var systemId = insertDeployableSystem(handle, "kiwi"); var taskId = insertTaskRecord(handle, "do it"); - insertTaskStatusRecord(handle, DeploymentTaskStatus.PENDING, taskId); + insertTaskStatusRecord(handle, DeploymentTaskStatus.PENDING, taskId, systemId); var statuses = dao.findByTaskId(taskId); assertThat(statuses) @@ -110,8 +109,9 @@ class UpdateStatus { @Test void shouldUpdateTheStatusOfAGivenRecord() { + var systemId = insertDeployableSystem(handle, "kiwi"); var taskId = insertTaskRecord(handle, "Some Task"); - var statusId = insertTaskStatusRecord(handle, DeploymentTaskStatus.PENDING, taskId); + var statusId = insertTaskStatusRecord(handle, DeploymentTaskStatus.PENDING, taskId, systemId); dao.updateStatus(statusId, DeploymentTaskStatus.COMPLETE); diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/AuditRecordResourceTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/AuditRecordResourceTest.java index eef86746..2297ef8e 100644 --- a/service/src/test/java/org/kiwiproject/champagne/resource/AuditRecordResourceTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/resource/AuditRecordResourceTest.java @@ -12,6 +12,7 @@ import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -21,6 +22,7 @@ import org.kiwiproject.champagne.junit.jupiter.JwtExtension; import org.kiwiproject.champagne.model.AuditRecord; import org.kiwiproject.champagne.model.AuditRecord.Action; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.model.User; import org.kiwiproject.dropwizard.util.exception.JerseyViolationExceptionMapper; import org.kiwiproject.jaxrs.exception.JaxrsExceptionMapper; @@ -32,23 +34,29 @@ @DisplayName("AuditRecordResource") @ExtendWith(DropwizardExtensionsSupport.class) class AuditRecordResourceTest { - + private static final AuditRecordDao AUDIT_RECORD_DAO = mock(AuditRecordDao.class); private static final AuditRecordResource RESOURCE = new AuditRecordResource(AUDIT_RECORD_DAO); private static final ResourceExtension RESOURCES = ResourceExtension.builder() - .bootstrapLogging(false) - .addResource(RESOURCE) - .addProvider(JerseyViolationExceptionMapper.class) - .addProvider(JaxrsExceptionMapper.class) - .build(); + .bootstrapLogging(false) + .addResource(RESOURCE) + .addProvider(JerseyViolationExceptionMapper.class) + .addProvider(JaxrsExceptionMapper.class) + .build(); @RegisterExtension private final JwtExtension jwtExtension = new JwtExtension("bob"); + @BeforeEach + void setUp() { + DeployableSystemThreadLocal.setCurrentDeployableSystem(1L); + } + @AfterEach void cleanup() { reset(AUDIT_RECORD_DAO); + DeployableSystemThreadLocal.clearDeployableSystem(); } @Nested @@ -57,37 +65,39 @@ class GetPagedAudits { @Test void shouldReturnPagedListOfAuditRecords() { var auditRecord = AuditRecord.builder() - .id(1L) - .recordId(42L) - .recordType(User.class.getSimpleName()) - .action(Action.CREATED) - .build(); + .id(1L) + .recordId(42L) + .recordType(User.class.getSimpleName()) + .action(Action.CREATED) + .deployableSystemId(1L) + .build(); - when(AUDIT_RECORD_DAO.findPagedAuditRecords(0, 10)).thenReturn(List.of(auditRecord)); - when(AUDIT_RECORD_DAO.countAuditRecords()).thenReturn(1L); + when(AUDIT_RECORD_DAO.findPagedAuditRecords(0, 10, 1L)).thenReturn(List.of(auditRecord)); + when(AUDIT_RECORD_DAO.countAuditRecords(1L)).thenReturn(1L); var response = RESOURCES.client() - .target("/audit") - .queryParam("pageNumber", 1) - .queryParam("pageSize", 10) - .request() - .get(); + .target("/audit") + .queryParam("pageNumber", 1) + .queryParam("pageSize", 10) + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result.getNumber()).isOne(); assertThat(result.getTotalElements()).isOne(); var audit = first(result.getContent()); assertThat(audit) - .usingRecursiveComparison() - .ignoringFields("timestamp") - .isEqualTo(auditRecord); + .usingRecursiveComparison() + .ignoringFields("timestamp") + .isEqualTo(auditRecord); - verify(AUDIT_RECORD_DAO).findPagedAuditRecords(0, 10); - verify(AUDIT_RECORD_DAO).countAuditRecords(); + verify(AUDIT_RECORD_DAO).findPagedAuditRecords(0, 10, 1L); + verify(AUDIT_RECORD_DAO).countAuditRecords(1L); verifyNoMoreInteractions(AUDIT_RECORD_DAO); } @@ -95,38 +105,40 @@ void shouldReturnPagedListOfAuditRecords() { @Test void shouldReturnPagedListOfAuditRecordsWithDefaultPaging() { var auditRecord = AuditRecord.builder() - .id(1L) - .recordId(42L) - .recordType(User.class.getSimpleName()) - .action(Action.CREATED) - .build(); + .id(1L) + .recordId(42L) + .recordType(User.class.getSimpleName()) + .action(Action.CREATED) + .deployableSystemId(1L) + .build(); - when(AUDIT_RECORD_DAO.findPagedAuditRecords(0, 50)).thenReturn(List.of(auditRecord)); - when(AUDIT_RECORD_DAO.countAuditRecords()).thenReturn(1L); + when(AUDIT_RECORD_DAO.findPagedAuditRecords(0, 50, 1L)).thenReturn(List.of(auditRecord)); + when(AUDIT_RECORD_DAO.countAuditRecords(1L)).thenReturn(1L); var response = RESOURCES.client() - .target("/audit") - .request() - .get(); + .target("/audit") + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result.getNumber()).isOne(); assertThat(result.getTotalElements()).isOne(); var audit = first(result.getContent()); assertThat(audit) - .usingRecursiveComparison() - .ignoringFields("timestamp") - .isEqualTo(auditRecord); + .usingRecursiveComparison() + .ignoringFields("timestamp") + .isEqualTo(auditRecord); - verify(AUDIT_RECORD_DAO).findPagedAuditRecords(0, 50); - verify(AUDIT_RECORD_DAO).countAuditRecords(); + verify(AUDIT_RECORD_DAO).findPagedAuditRecords(0, 50, 1L); + verify(AUDIT_RECORD_DAO).countAuditRecords(1L); verifyNoMoreInteractions(AUDIT_RECORD_DAO); } } - + } diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/BuildResourceTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/BuildResourceTest.java index 24e285df..a06eb504 100644 --- a/service/src/test/java/org/kiwiproject/champagne/resource/BuildResourceTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/resource/BuildResourceTest.java @@ -19,6 +19,7 @@ import javax.ws.rs.core.GenericType; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -27,6 +28,7 @@ import org.kiwiproject.champagne.dao.BuildDao; import org.kiwiproject.champagne.junit.jupiter.JwtExtension; import org.kiwiproject.champagne.model.Build; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.dropwizard.util.exception.JerseyViolationExceptionMapper; import org.kiwiproject.jaxrs.exception.JaxrsExceptionMapper; import org.kiwiproject.spring.data.KiwiPage; @@ -37,24 +39,30 @@ @DisplayName("BuildResource") @ExtendWith(DropwizardExtensionsSupport.class) class BuildResourceTest { - + private static final BuildDao BUILD_DAO = mock(BuildDao.class); private static final BuildResource RESOURCE = new BuildResource(BUILD_DAO, JSON_HELPER); private static final ResourceExtension RESOURCES = ResourceExtension.builder() - .bootstrapLogging(false) - .addResource(RESOURCE) - .addProvider(JerseyViolationExceptionMapper.class) - .addProvider(JaxrsExceptionMapper.class) - .build(); + .bootstrapLogging(false) + .addResource(RESOURCE) + .addProvider(JerseyViolationExceptionMapper.class) + .addProvider(JaxrsExceptionMapper.class) + .build(); @RegisterExtension private final JwtExtension jwtExtension = new JwtExtension("bob"); + @BeforeEach + void setUp() { + DeployableSystemThreadLocal.setCurrentDeployableSystem(1L); + } + @AfterEach void cleanup() { reset(BUILD_DAO); + DeployableSystemThreadLocal.clearDeployableSystem(); } @Nested @@ -63,36 +71,38 @@ class GetPagedReleases { @Test void shouldReturnPagedListOfReleases() { var build = Build.builder() - .repoNamespace("kiwiproject") - .repoName("champagne-service") - .commitRef("abc1234") - .commitUser("jdoe") - .sourceBranch("main") - .componentIdentifier("champagne_service") - .componentVersion("42.0.0") - .distributionLocation("https://some-nexus-server.net/foo") - .extraDeploymentInfo(Map.of()) - .build(); - - when(BUILD_DAO.findPagedBuilds(0, 10, null, null)).thenReturn(List.of(build)); - when(BUILD_DAO.countBuilds(null, null)).thenReturn(1L); + .repoNamespace("kiwiproject") + .repoName("champagne-service") + .commitRef("abc1234") + .commitUser("jdoe") + .sourceBranch("main") + .componentIdentifier("champagne_service") + .componentVersion("42.0.0") + .distributionLocation("https://some-nexus-server.net/foo") + .extraDeploymentInfo(Map.of()) + .deployableSystemId(1L) + .build(); + + when(BUILD_DAO.findPagedBuilds(0, 10, 1L, null, null)).thenReturn(List.of(build)); + when(BUILD_DAO.countBuilds(1L, null, null)).thenReturn(1L); var response = RESOURCES.client() - .target("/build") - .queryParam("pageNumber", 1) - .queryParam("pageSize", 10) - .request() - .get(); + .target("/build") + .queryParam("pageNumber", 1) + .queryParam("pageSize", 10) + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result.getNumber()).isOne(); assertThat(result.getTotalElements()).isOne(); - verify(BUILD_DAO).findPagedBuilds(0, 10, null, null); - verify(BUILD_DAO).countBuilds(null, null); + verify(BUILD_DAO).findPagedBuilds(0, 10, 1L, null, null); + verify(BUILD_DAO).countBuilds(1L, null, null); verifyNoMoreInteractions(BUILD_DAO); } @@ -100,35 +110,37 @@ void shouldReturnPagedListOfReleases() { @Test void shouldReturnPagedListOfReleasesWithDefaultPaging() { var build = Build.builder() - .repoNamespace("kiwiproject") - .repoName("champagne-service") - .commitRef("abc1234") - .commitUser("jdoe") - .sourceBranch("main") - .componentIdentifier("champagne_service") - .componentVersion("42.0.0") - .distributionLocation("https://some-nexus-server.net/foo") - .extraDeploymentInfo(Map.of()) - .build(); - - when(BUILD_DAO.findPagedBuilds(0, 50, null, null)).thenReturn(List.of(build)); - when(BUILD_DAO.countBuilds(null, null)).thenReturn(1L); + .repoNamespace("kiwiproject") + .repoName("champagne-service") + .commitRef("abc1234") + .commitUser("jdoe") + .sourceBranch("main") + .componentIdentifier("champagne_service") + .componentVersion("42.0.0") + .distributionLocation("https://some-nexus-server.net/foo") + .extraDeploymentInfo(Map.of()) + .deployableSystemId(1L) + .build(); + + when(BUILD_DAO.findPagedBuilds(0, 50, 1L, null, null)).thenReturn(List.of(build)); + when(BUILD_DAO.countBuilds(1L, null, null)).thenReturn(1L); var response = RESOURCES.client() - .target("/build") - .request() - .get(); + .target("/build") + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result.getNumber()).isOne(); assertThat(result.getSize()).isEqualTo(50); assertThat(result.getTotalElements()).isOne(); - verify(BUILD_DAO).findPagedBuilds(0, 50, null, null); - verify(BUILD_DAO).countBuilds(null, null); + verify(BUILD_DAO).findPagedBuilds(0, 50, 1L, null, null); + verify(BUILD_DAO).countBuilds(1L, null, null); verifyNoMoreInteractions(BUILD_DAO); } @@ -140,23 +152,23 @@ class AddNewBuild { @Test void shouldSaveNewBuild() { var build = Build.builder() - .repoNamespace("kiwiproject") - .repoName("champagne-service") - .commitRef("abc1234") - .commitUser("jdoe") - .sourceBranch("main") - .componentIdentifier("champagne_service") - .componentVersion("42.0.0") - .distributionLocation("https://some-nexus-server.net/foo") - .extraDeploymentInfo(Map.of()) - .build(); + .repoNamespace("kiwiproject") + .repoName("champagne-service") + .commitRef("abc1234") + .commitUser("jdoe") + .sourceBranch("main") + .componentIdentifier("champagne_service") + .componentVersion("42.0.0") + .distributionLocation("https://some-nexus-server.net/foo") + .extraDeploymentInfo(Map.of()) + .build(); when(BUILD_DAO.insertBuild(any(Build.class), anyString())).thenReturn(1L); var response = RESOURCES.client() - .target("/build") - .request() - .post(json(build)); + .target("/build") + .request() + .post(json(build)); assertAcceptedResponse(response); diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResourceTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResourceTest.java index 6e4912e8..8b2e1da0 100644 --- a/service/src/test/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResourceTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/resource/DeploymentEnvironmentResourceTest.java @@ -4,6 +4,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertAcceptedResponse; +import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertBadRequest; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertNoContentResponse; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertOkResponse; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertResponseStatusCode; @@ -18,6 +19,7 @@ import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -29,6 +31,7 @@ import org.kiwiproject.champagne.junit.jupiter.JwtExtension; import org.kiwiproject.champagne.model.AuditRecord; import org.kiwiproject.champagne.model.AuditRecord.Action; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.service.ManualTaskService; import org.kiwiproject.champagne.model.DeploymentEnvironment; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; @@ -40,7 +43,7 @@ import javax.ws.rs.core.GenericType; @DisplayName("DeploymentEnvironmentResource") -@ExtendWith( {DropwizardExtensionsSupport.class, ApplicationErrorExtension.class}) +@ExtendWith({DropwizardExtensionsSupport.class, ApplicationErrorExtension.class}) class DeploymentEnvironmentResourceTest { private static final DeploymentEnvironmentDao DEPLOYMENT_ENVIRONMENT_DAO = mock(DeploymentEnvironmentDao.class); private static final AuditRecordDao AUDIT_RECORD_DAO = mock(AuditRecordDao.class); @@ -56,10 +59,16 @@ class DeploymentEnvironmentResourceTest { @RegisterExtension private final JwtExtension jwtExtension = new JwtExtension("bob"); - + @BeforeEach void setUp() { + DeployableSystemThreadLocal.setCurrentDeployableSystem(1L); + } + + @AfterEach + void tearDown() { reset(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO, MANUAL_TASK_SERVICE); + DeployableSystemThreadLocal.clearDeployableSystem(); } @Nested @@ -68,26 +77,28 @@ class ListEnvironments { @Test void shouldReturnListOfEnvironments() { var env = DeploymentEnvironment.builder() - .name("DEV") - .build(); + .name("DEV") + .deployableSystemId(1L) + .build(); - when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments()).thenReturn(List.of(env)); + when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments(1L)).thenReturn(List.of(env)); var response = APP.client().target("/environments") - .request() - .get(); + .request() + .get(); assertOkResponse(response); - var envs = response.readEntity(new GenericType>(){}); + var envs = response.readEntity(new GenericType>() { + }); var foundEnv = first(envs); assertThat(foundEnv) - .usingRecursiveComparison() - .ignoringFields("createdAt", "updatedAt") - .isEqualTo(env); + .usingRecursiveComparison() + .ignoringFields("createdAt", "updatedAt") + .isEqualTo(env); - verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(); + verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(1L); verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO); verifyNoInteractions(AUDIT_RECORD_DAO); } @@ -101,18 +112,19 @@ void shouldAddTheGivenEnvironment() { when(DEPLOYMENT_ENVIRONMENT_DAO.insertEnvironment(any(DeploymentEnvironment.class))).thenReturn(1L); var env = DeploymentEnvironment.builder() - .name("DEV") - .build(); + .name("DEV") + .deployableSystemId(1L) + .build(); var response = APP.client().target("/environments") - .request() - .post(json(env)); + .request() + .post(json(env)); assertNoContentResponse(response); verify(DEPLOYMENT_ENVIRONMENT_DAO).insertEnvironment(isA(DeploymentEnvironment.class)); - verifyAuditRecorded(1L, Action.CREATED); + verifyAuditRecorded(Action.CREATED); verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } @@ -122,13 +134,51 @@ void shouldNotAddTheGivenUserWhenValidationErrors() { var env = DeploymentEnvironment.builder().build(); var response = APP.client().target("/environments") - .request() - .post(json(env)); + .request() + .post(json(env)); assertResponseStatusCode(response, 422); verifyNoInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } + + @Test + void shouldSetTheSystemFromHeaderWhenNotPosted() { + when(DEPLOYMENT_ENVIRONMENT_DAO.insertEnvironment(any(DeploymentEnvironment.class))).thenReturn(1L); + + var env = DeploymentEnvironment.builder() + .name("DEV") + .build(); + + var response = APP.client().target("/environments") + .request() + .post(json(env)); + + assertNoContentResponse(response); + + verify(DEPLOYMENT_ENVIRONMENT_DAO).insertEnvironment(isA(DeploymentEnvironment.class)); + + verifyAuditRecorded(Action.CREATED); + + verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); + } + + @Test + void shouldReturnBadRequestWhenSystemNotProvided() { + DeployableSystemThreadLocal.clearDeployableSystem(); + + var env = DeploymentEnvironment.builder() + .name("DEV") + .build(); + + var response = APP.client().target("/environments") + .request() + .post(json(env)); + + assertBadRequest(response); + + verifyNoInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); + } } @Nested @@ -139,19 +189,19 @@ void shouldUpdateTheGivenEnvironment() { when(DEPLOYMENT_ENVIRONMENT_DAO.updateEnvironment(any(DeploymentEnvironment.class))).thenReturn(1); var env = DeploymentEnvironment.builder() - .id(1L) - .name("DEV") - .build(); + .id(1L) + .name("DEV") + .build(); var response = APP.client().target("/environments") - .request() - .put(json(env)); + .request() + .put(json(env)); assertAcceptedResponse(response); verify(DEPLOYMENT_ENVIRONMENT_DAO).updateEnvironment(isA(DeploymentEnvironment.class)); - verifyAuditRecorded(1L, Action.UPDATED); + verifyAuditRecorded(Action.UPDATED); verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } @@ -161,8 +211,8 @@ void shouldNotUpdateTheGivenEnvironmentWhenIdIsMissing() { var env = DeploymentEnvironment.builder().build(); var response = APP.client().target("/environments") - .request() - .put(json(env)); + .request() + .put(json(env)); assertResponseStatusCode(response, 422); @@ -174,13 +224,13 @@ void shouldNotAuditUpdateIfUpdateDoesNotChangeAnything() { when(DEPLOYMENT_ENVIRONMENT_DAO.updateEnvironment(any(DeploymentEnvironment.class))).thenReturn(0); var env = DeploymentEnvironment.builder() - .id(1L) - .name("DEV") - .build(); + .id(1L) + .name("DEV") + .build(); var response = APP.client().target("/environments") - .request() - .put(json(env)); + .request() + .put(json(env)); assertAcceptedResponse(response); @@ -198,16 +248,16 @@ void shouldDeleteGivenEnvironment() { when(DEPLOYMENT_ENVIRONMENT_DAO.hardDeleteById(1L)).thenReturn(1); var response = APP.client().target("/environments") - .path("{id}/delete") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}/delete") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); verify(DEPLOYMENT_ENVIRONMENT_DAO).hardDeleteById(1L); - - verifyAuditRecorded(1L, Action.DELETED); + + verifyAuditRecorded(Action.DELETED); verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } @@ -217,10 +267,10 @@ void shouldNotAuditDeleteIfDoesNotChangeAnything() { when(DEPLOYMENT_ENVIRONMENT_DAO.hardDeleteById(1L)).thenReturn(0); var response = APP.client().target("/environments") - .path("{id}/delete") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}/delete") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); @@ -238,16 +288,16 @@ void shouldSoftDeleteGivenEnvironment() { when(DEPLOYMENT_ENVIRONMENT_DAO.softDeleteById(1L)).thenReturn(1); var response = APP.client().target("/environments") - .path("{id}/deactivate") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}/deactivate") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); verify(DEPLOYMENT_ENVIRONMENT_DAO).softDeleteById(1L); - - verifyAuditRecorded(1L, Action.UPDATED); + + verifyAuditRecorded(Action.UPDATED); verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } @@ -257,10 +307,10 @@ void shouldNotAuditSoftDeleteIfDoesNotChangeAnything() { when(DEPLOYMENT_ENVIRONMENT_DAO.softDeleteById(1L)).thenReturn(0); var response = APP.client().target("/environments") - .path("{id}/deactivate") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}/deactivate") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); @@ -278,16 +328,16 @@ void shouldUnDeleteGivenEnvironment() { when(DEPLOYMENT_ENVIRONMENT_DAO.unSoftDeleteById(1L)).thenReturn(1); var response = APP.client().target("/environments") - .path("{id}/activate") - .resolveTemplate("id", 1) - .request() - .put(json("")); + .path("{id}/activate") + .resolveTemplate("id", 1) + .request() + .put(json("")); assertAcceptedResponse(response); verify(DEPLOYMENT_ENVIRONMENT_DAO).unSoftDeleteById(1L); - - verifyAuditRecorded(1L, Action.UPDATED); + + verifyAuditRecorded(Action.UPDATED); verifyNoMoreInteractions(DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } @@ -297,10 +347,10 @@ void shouldNotAuditUnDeleteIfDoesNotChangeAnything() { when(DEPLOYMENT_ENVIRONMENT_DAO.softDeleteById(1L)).thenReturn(0); var response = APP.client().target("/environments") - .path("{id}/activate") - .resolveTemplate("id", 1) - .request() - .put(json("")); + .path("{id}/activate") + .resolveTemplate("id", 1) + .request() + .put(json("")); assertAcceptedResponse(response); @@ -310,13 +360,13 @@ void shouldNotAuditUnDeleteIfDoesNotChangeAnything() { } } - private void verifyAuditRecorded(long id, Action action) { + private void verifyAuditRecorded(Action action) { var argCapture = ArgumentCaptor.forClass(AuditRecord.class); verify(AUDIT_RECORD_DAO).insertAuditRecord(argCapture.capture()); var audit = argCapture.getValue(); - assertThat(audit.getRecordId()).isEqualTo(id); + assertThat(audit.getRecordId()).isEqualTo(1); assertThat(audit.getRecordType()).isEqualTo(DeploymentEnvironment.class.getSimpleName()); assertThat(audit.getAction()).isEqualTo(action); } diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/HostConfigurationResourceTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/HostConfigurationResourceTest.java index da992c3f..bfd2f46a 100644 --- a/service/src/test/java/org/kiwiproject/champagne/resource/HostConfigurationResourceTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/resource/HostConfigurationResourceTest.java @@ -17,6 +17,7 @@ import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; @@ -30,6 +31,7 @@ import org.kiwiproject.champagne.model.AuditRecord; import org.kiwiproject.champagne.model.Component; import org.kiwiproject.champagne.model.AuditRecord.Action; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.model.Host; import org.kiwiproject.dropwizard.error.dao.ApplicationErrorDao; import org.kiwiproject.dropwizard.error.test.junit.jupiter.ApplicationErrorExtension; @@ -42,7 +44,7 @@ import javax.ws.rs.core.GenericType; @DisplayName("HostConfigurationResource") -@ExtendWith( {DropwizardExtensionsSupport.class, ApplicationErrorExtension.class}) +@ExtendWith({DropwizardExtensionsSupport.class, ApplicationErrorExtension.class}) class HostConfigurationResourceTest { private static final HostDao HOST_DAO = mock(HostDao.class); private static final ComponentDao COMPONENT_DAO = mock(ComponentDao.class); @@ -58,10 +60,16 @@ class HostConfigurationResourceTest { @RegisterExtension private final JwtExtension jwtExtension = new JwtExtension("bob"); - + @BeforeEach void setUp() { + DeployableSystemThreadLocal.setCurrentDeployableSystem(1L); + } + + @AfterEach + void tearDown() { reset(HOST_DAO, COMPONENT_DAO, AUDIT_RECORD_DAO); + DeployableSystemThreadLocal.clearDeployableSystem(); } @Nested @@ -70,28 +78,30 @@ class ListHostsForEnvironment { @Test void shouldReturnListOfHostsForEnv() { var host = Host.builder() - .id(1L) - .hostname("localhost") - .build(); + .id(1L) + .hostname("localhost") + .deployableSystemId(1L) + .build(); - when(HOST_DAO.findHostsByEnvId(1L)).thenReturn(List.of(host)); + when(HOST_DAO.findHostsByEnvId(1L, 1L)).thenReturn(List.of(host)); var response = APP.client().target("/host/{envId}") - .resolveTemplate("envId", 1L) - .request() - .get(); + .resolveTemplate("envId", 1L) + .request() + .get(); assertOkResponse(response); - var hosts = response.readEntity(new GenericType>(){}); + var hosts = response.readEntity(new GenericType>() { + }); var foundHost = first(hosts); assertThat(foundHost) - .usingRecursiveComparison() - .ignoringFields("createdAt", "updatedAt") - .isEqualTo(host); + .usingRecursiveComparison() + .ignoringFields("createdAt", "updatedAt") + .isEqualTo(host); - verify(HOST_DAO).findHostsByEnvId(1L); + verify(HOST_DAO).findHostsByEnvId(1L, 1L); verifyNoMoreInteractions(HOST_DAO); verifyNoInteractions(AUDIT_RECORD_DAO); } @@ -105,19 +115,19 @@ void shouldAddTheGivenHost() { when(HOST_DAO.insertHost(any(Host.class), anyString())).thenReturn(1L); var host = Host.builder() - .hostname("localhost") - .tags(List.of("foo")) - .build(); + .hostname("localhost") + .tags(List.of("foo")) + .build(); var response = APP.client().target("/host") - .request() - .post(json(host)); + .request() + .post(json(host)); assertAcceptedResponse(response); verify(HOST_DAO).insertHost(any(Host.class), anyString()); - verifyAuditRecorded(1L, Host.class, Action.CREATED); + verifyAuditRecorded(Host.class, Action.CREATED); verifyNoMoreInteractions(HOST_DAO, AUDIT_RECORD_DAO); } @@ -131,16 +141,16 @@ void shouldDeleteGivenHost() { when(HOST_DAO.deleteHost(1L)).thenReturn(1); var response = APP.client().target("/host") - .path("{id}") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); verify(HOST_DAO).deleteHost(1L); - - verifyAuditRecorded(1L, Host.class, Action.DELETED); + + verifyAuditRecorded(Host.class, Action.DELETED); verifyNoMoreInteractions(HOST_DAO, AUDIT_RECORD_DAO); } @@ -150,10 +160,10 @@ void shouldNotAuditDeleteIfDoesNotChangeAnything() { when(HOST_DAO.deleteHost(1L)).thenReturn(0); var response = APP.client().target("/host") - .path("{id}") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); @@ -163,52 +173,53 @@ void shouldNotAuditDeleteIfDoesNotChangeAnything() { } } - private void verifyAuditRecorded(long id, Class auditRecordClass, Action action) { + private void verifyAuditRecorded(Class auditRecordClass, Action action) { var argCapture = ArgumentCaptor.forClass(AuditRecord.class); verify(AUDIT_RECORD_DAO).insertAuditRecord(argCapture.capture()); var audit = argCapture.getValue(); - assertThat(audit.getRecordId()).isEqualTo(id); + assertThat(audit.getRecordId()).isEqualTo(1); assertThat(audit.getRecordType()).isEqualTo(auditRecordClass.getSimpleName()); assertThat(audit.getAction()).isEqualTo(action); } - + @Nested class ListComponentsForHost { @Test void shouldReturnListOfComponentsForHost() { var host = Host.builder() - .id(1L) - .hostname("localhost") - .tags(List.of("core")) - .build(); + .id(1L) + .hostname("localhost") + .tags(List.of("core")) + .build(); when(HOST_DAO.findById(1L)).thenReturn(Optional.of(host)); var component = Component.builder() - .id(2L) - .componentName("foo-service") - .tag("core") - .build(); + .id(2L) + .componentName("foo-service") + .tag("core") + .build(); when(COMPONENT_DAO.findComponentsByHostTags(List.of("core"))).thenReturn(List.of(component)); var response = APP.client().target("/host/{hostId}/components") - .resolveTemplate("hostId", 1L) - .request() - .get(); + .resolveTemplate("hostId", 1L) + .request() + .get(); assertOkResponse(response); - var components = response.readEntity(new GenericType>(){}); + var components = response.readEntity(new GenericType>() { + }); var foundComponent = first(components); assertThat(foundComponent) - .usingRecursiveComparison() - .ignoringFields("createdAt", "updatedAt") - .isEqualTo(component); + .usingRecursiveComparison() + .ignoringFields("createdAt", "updatedAt") + .isEqualTo(component); verify(HOST_DAO).findById(1L); verify(COMPONENT_DAO).findComponentsByHostTags(List.of("core")); @@ -221,9 +232,9 @@ void shouldReturn404WhenHostNotFound() { when(HOST_DAO.findById(1L)).thenReturn(Optional.empty()); var response = APP.client().target("/host/{hostId}/components") - .resolveTemplate("hostId", 1L) - .request() - .get(); + .resolveTemplate("hostId", 1L) + .request() + .get(); assertNotFoundResponse(response); } @@ -237,19 +248,19 @@ void shouldAddTheGivenComponent() { when(COMPONENT_DAO.insertComponent(any(Component.class))).thenReturn(1L); var component = Component.builder() - .componentName("foo-service") - .tag("core") - .build(); + .componentName("foo-service") + .tag("core") + .build(); var response = APP.client().target("/host/component") - .request() - .post(json(component)); + .request() + .post(json(component)); assertAcceptedResponse(response); verify(COMPONENT_DAO).insertComponent(any(Component.class)); - verifyAuditRecorded(1L, Component.class, Action.CREATED); + verifyAuditRecorded(Component.class, Action.CREATED); verifyNoMoreInteractions(COMPONENT_DAO, AUDIT_RECORD_DAO); } @@ -263,16 +274,16 @@ void shouldDeleteGivenComponent() { when(COMPONENT_DAO.deleteComponent(1L)).thenReturn(1); var response = APP.client().target("/host/component") - .path("{id}") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); verify(COMPONENT_DAO).deleteComponent(1L); - - verifyAuditRecorded(1L, Component.class, Action.DELETED); + + verifyAuditRecorded(Component.class, Action.DELETED); verifyNoMoreInteractions(COMPONENT_DAO, AUDIT_RECORD_DAO); } @@ -282,10 +293,10 @@ void shouldNotAuditDeleteIfDoesNotChangeAnything() { when(COMPONENT_DAO.deleteComponent(1L)).thenReturn(0); var response = APP.client().target("/host/component") - .path("{id}") - .resolveTemplate("id", 1) - .request() - .delete(); + .path("{id}") + .resolveTemplate("id", 1) + .request() + .delete(); assertAcceptedResponse(response); diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/TaskResourceTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/TaskResourceTest.java index 87a95d79..eff6521d 100644 --- a/service/src/test/java/org/kiwiproject/champagne/resource/TaskResourceTest.java +++ b/service/src/test/java/org/kiwiproject/champagne/resource/TaskResourceTest.java @@ -6,13 +6,13 @@ import static org.kiwiproject.collect.KiwiLists.first; import static org.kiwiproject.test.constants.KiwiTestConstants.JSON_HELPER; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertAcceptedResponse; +import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertBadRequest; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertNotFoundResponse; import static org.kiwiproject.test.jaxrs.JaxrsTestHelper.assertOkResponse; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -21,6 +21,7 @@ import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; import io.dropwizard.testing.junit5.ResourceExtension; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; @@ -34,6 +35,7 @@ import org.kiwiproject.champagne.dao.TaskStatusDao; import org.kiwiproject.champagne.junit.jupiter.JwtExtension; import org.kiwiproject.champagne.model.AuditRecord.Action; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; import org.kiwiproject.champagne.model.DeploymentEnvironment; import org.kiwiproject.champagne.model.manualdeployment.DeploymentTaskStatus; import org.kiwiproject.champagne.model.manualdeployment.Release; @@ -66,18 +68,24 @@ class TaskResourceTest { private static final TaskResource RESOURCE = new TaskResource(RELEASE_DAO, RELEASE_STATUS_DAO, TASK_DAO, TASK_STATUS_DAO, DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO, APPLICATION_ERROR_DAO); private static final ResourceExtension RESOURCES = ResourceExtension.builder() - .bootstrapLogging(false) - .addResource(RESOURCE) - .addProvider(JerseyViolationExceptionMapper.class) - .addProvider(JaxrsExceptionMapper.class) - .build(); + .bootstrapLogging(false) + .addResource(RESOURCE) + .addProvider(JerseyViolationExceptionMapper.class) + .addProvider(JaxrsExceptionMapper.class) + .build(); @RegisterExtension private final JwtExtension jwtExtension = new JwtExtension("bob"); + @BeforeEach + void setUp() { + DeployableSystemThreadLocal.setCurrentDeployableSystem(1L); + } + @AfterEach void cleanup() { reset(RELEASE_DAO, RELEASE_STATUS_DAO, TASK_DAO, TASK_STATUS_DAO, DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); + DeployableSystemThreadLocal.clearDeployableSystem(); } @Nested @@ -86,31 +94,33 @@ class GetPagedReleases { @Test void shouldReturnPagedListOfReleases() { var release = Release.builder() - .id(1L) - .releaseNumber("2023.42") - .build(); + .id(1L) + .releaseNumber("2023.42") + .deployableSystemId(1L) + .build(); - when(RELEASE_DAO.findPagedReleases(0, 10)).thenReturn(List.of(release)); - when(RELEASE_DAO.countReleases()).thenReturn(1L); + when(RELEASE_DAO.findPagedReleases(0, 10, 1L)).thenReturn(List.of(release)); + when(RELEASE_DAO.countReleases(1L)).thenReturn(1L); var releaseStatus = ReleaseStatus.builder() - .releaseId(1L) - .status(DeploymentTaskStatus.PENDING) - .environmentId(1L) - .build(); + .releaseId(1L) + .status(DeploymentTaskStatus.PENDING) + .environmentId(1L) + .build(); when(RELEASE_STATUS_DAO.findByReleaseId(1L)).thenReturn(List.of(releaseStatus)); var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases") - .queryParam("pageNumber", 1) - .queryParam("pageSize", 10) - .request() - .get(); + .target("/manual/deployment/tasks/releases") + .queryParam("pageNumber", 1) + .queryParam("pageSize", 10) + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result.getNumber()).isOne(); assertThat(result.getTotalElements()).isOne(); @@ -120,8 +130,8 @@ void shouldReturnPagedListOfReleases() { assertThat(releaseWithStatus.getReleaseNumber()).isEqualTo("2023.42"); assertThat(releaseWithStatus.getEnvironmentStatus()).contains(entry(1L, releaseStatus)); - verify(RELEASE_DAO).findPagedReleases(0, 10); - verify(RELEASE_DAO).countReleases(); + verify(RELEASE_DAO).findPagedReleases(0, 10, 1L); + verify(RELEASE_DAO).countReleases(1L); verify(RELEASE_STATUS_DAO).findByReleaseId(1L); verifyNoMoreInteractions(RELEASE_DAO, RELEASE_STATUS_DAO); @@ -131,29 +141,31 @@ void shouldReturnPagedListOfReleases() { @Test void shouldReturnPagedListOfReleasesWithDefaultPaging() { var release = Release.builder() - .id(1L) - .releaseNumber("2023.42") - .build(); + .id(1L) + .releaseNumber("2023.42") + .deployableSystemId(1L) + .build(); - when(RELEASE_DAO.findPagedReleases(0, 50)).thenReturn(List.of(release)); - when(RELEASE_DAO.countReleases()).thenReturn(1L); + when(RELEASE_DAO.findPagedReleases(0, 50, 1L)).thenReturn(List.of(release)); + when(RELEASE_DAO.countReleases(1L)).thenReturn(1L); var releaseStatus = ReleaseStatus.builder() - .releaseId(1L) - .status(DeploymentTaskStatus.PENDING) - .environmentId(1L) - .build(); + .releaseId(1L) + .status(DeploymentTaskStatus.PENDING) + .environmentId(1L) + .build(); when(RELEASE_STATUS_DAO.findByReleaseId(1L)).thenReturn(List.of(releaseStatus)); var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases") - .request() - .get(); + .target("/manual/deployment/tasks/releases") + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result.getNumber()).isOne(); assertThat(result.getSize()).isEqualTo(50); @@ -164,48 +176,49 @@ void shouldReturnPagedListOfReleasesWithDefaultPaging() { assertThat(releaseWithStatus.getReleaseNumber()).isEqualTo("2023.42"); assertThat(releaseWithStatus.getEnvironmentStatus()).contains(entry(1L, releaseStatus)); - verify(RELEASE_DAO).findPagedReleases(0, 50); - verify(RELEASE_DAO).countReleases(); + verify(RELEASE_DAO).findPagedReleases(0, 50, 1L); + verify(RELEASE_DAO).countReleases(1L); verify(RELEASE_STATUS_DAO).findByReleaseId(1L); verifyNoMoreInteractions(RELEASE_DAO, RELEASE_STATUS_DAO); verifyNoInteractions(TASK_DAO, TASK_STATUS_DAO, DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); } } - + @Nested class GetTasksForRelease { @Test void shouldReturnTasks() { var task = Task.builder() - .id(1L) - .releaseId(1L) - .component("ZK") - .summary("Upgrade") - .description("All the steps") - .stage(ReleaseStage.PRE) - .build(); + .id(1L) + .releaseId(1L) + .component("ZK") + .summary("Upgrade") + .description("All the steps") + .stage(ReleaseStage.PRE) + .build(); when(TASK_DAO.findByReleaseId(1L)).thenReturn(List.of(task)); var taskStatus = TaskStatus.builder() - .taskId(1L) - .status(DeploymentTaskStatus.PENDING) - .environmentId(1L) - .build(); + .taskId(1L) + .status(DeploymentTaskStatus.PENDING) + .environmentId(1L) + .build(); when(TASK_STATUS_DAO.findByTaskId(1L)).thenReturn(List.of(taskStatus)); var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases/{releaseId}") - .resolveTemplate("releaseId", 1L) - .request() - .get(); + .target("/manual/deployment/tasks/releases/{releaseId}") + .resolveTemplate("releaseId", 1L) + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>() {}); + var result = response.readEntity(new GenericType>() { + }); var taskWithStatus = first(result); @@ -230,91 +243,145 @@ class AddNewRelease { @Test void shouldSaveNewRelease() { var release = Release.builder() - .releaseNumber("2023.01") - .build(); + .releaseNumber("2023.01") + .deployableSystemId(1L) + .build(); when(RELEASE_DAO.insertRelease(any(Release.class))).thenReturn(1L); var env = DeploymentEnvironment.builder() - .id(1L) - .name("DEVELOPMENT") - .build(); + .id(1L) + .name("DEVELOPMENT") + .build(); - when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments()).thenReturn(List.of(env)); + when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments(1L)).thenReturn(List.of(env)); when(RELEASE_STATUS_DAO.insertReleaseStatus(any(ReleaseStatus.class))).thenReturn(2L); var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases") - .request() - .post(json(release)); + .target("/manual/deployment/tasks/releases") + .request() + .post(json(release)); assertAcceptedResponse(response); verify(RELEASE_DAO).insertRelease(argThat(r -> "2023.01".equalsIgnoreCase(r.getReleaseNumber()))); verify(RELEASE_STATUS_DAO).insertReleaseStatus(any(ReleaseStatus.class)); - verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(); + verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(1L); verifyAuditRecorded(1L, Release.class, Action.CREATED); - verifyMultipleStatusRecordsAuditRecorded(1, ReleaseStatus.class, Action.CREATED); + verifyMultipleStatusRecordsAuditRecorded(ReleaseStatus.class, Action.CREATED); verifyNoMoreInteractions(RELEASE_DAO, RELEASE_STATUS_DAO, DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); verifyNoInteractions(TASK_DAO, TASK_STATUS_DAO); } + + @Test + void shouldSetTheSystemFromHeaderWhenNotPosted() { + var release = Release.builder() + .releaseNumber("2023.01") + .build(); + + when(RELEASE_DAO.insertRelease(any(Release.class))).thenReturn(1L); + + var env = DeploymentEnvironment.builder() + .id(1L) + .name("DEVELOPMENT") + .build(); + + when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments(1L)).thenReturn(List.of(env)); + + when(RELEASE_STATUS_DAO.insertReleaseStatus(any(ReleaseStatus.class))).thenReturn(2L); + + var response = RESOURCES.client() + .target("/manual/deployment/tasks/releases") + .request() + .post(json(release)); + + assertAcceptedResponse(response); + + verify(RELEASE_DAO).insertRelease(argThat(r -> "2023.01".equalsIgnoreCase(r.getReleaseNumber()))); + verify(RELEASE_STATUS_DAO).insertReleaseStatus(any(ReleaseStatus.class)); + verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(1L); + + verifyAuditRecorded(1L, Release.class, Action.CREATED); + verifyMultipleStatusRecordsAuditRecorded(ReleaseStatus.class, Action.CREATED); + + verifyNoMoreInteractions(RELEASE_DAO, RELEASE_STATUS_DAO, DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); + verifyNoInteractions(TASK_DAO, TASK_STATUS_DAO); + } + + @Test + void shouldReturnBadRequestWhenSystemNotProvided() { + DeployableSystemThreadLocal.clearDeployableSystem(); + + var release = Release.builder() + .releaseNumber("2023.01") + .build(); + + var response = RESOURCES.client() + .target("/manual/deployment/tasks/releases") + .request() + .post(json(release)); + + assertBadRequest(response); + + verifyNoInteractions(RELEASE_DAO, RELEASE_STATUS_DAO, TASK_DAO, TASK_STATUS_DAO, AUDIT_RECORD_DAO); + } } - + @Nested class AddNewTask { @Test void shouldSaveNewTask() { var task = Task.builder() - .releaseId(1L) - .stage(ReleaseStage.PRE) - .description("some things") - .summary("Do it") - .component("super-service") - .build(); + .releaseId(1L) + .stage(ReleaseStage.PRE) + .description("some things") + .summary("Do it") + .component("super-service") + .build(); when(TASK_DAO.insertTask(any(Task.class))).thenReturn(2L); var env = DeploymentEnvironment.builder() - .id(1L) - .name("DEVELOPMENT") - .build(); + .id(1L) + .name("DEVELOPMENT") + .build(); - when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments()).thenReturn(List.of(env)); + when(DEPLOYMENT_ENVIRONMENT_DAO.findAllEnvironments(1L)).thenReturn(List.of(env)); var taskStatus = TaskStatus.builder() - .status(DeploymentTaskStatus.COMPLETE) - .environmentId(1L) - .build(); + .status(DeploymentTaskStatus.COMPLETE) + .environmentId(1L) + .build(); when(TASK_STATUS_DAO.findByTaskId(2L)).thenReturn(List.of(taskStatus)); var savedTask = Task.builder() - .id(2L) - .releaseId(1L) - .stage(ReleaseStage.PRE) - .description("some things") - .summary("Do it") - .component("super-service") - .build(); + .id(2L) + .releaseId(1L) + .stage(ReleaseStage.PRE) + .description("some things") + .summary("Do it") + .component("super-service") + .build(); when(TASK_DAO.findByReleaseId(1L)).thenReturn(List.of(savedTask)); var status = ReleaseStatus.builder() - .id(5L) - .environmentId(1L) - .status(DeploymentTaskStatus.PENDING) - .build(); + .id(5L) + .environmentId(1L) + .status(DeploymentTaskStatus.PENDING) + .build(); when(RELEASE_STATUS_DAO.findByReleaseId(1L)).thenReturn(List.of(status)); var response = RESOURCES.client() - .target("/manual/deployment/tasks") - .request() - .post(json(task)); + .target("/manual/deployment/tasks") + .request() + .post(json(task)); assertAcceptedResponse(response); @@ -324,11 +391,11 @@ void shouldSaveNewTask() { verify(TASK_STATUS_DAO).findByTaskId(2L); verify(RELEASE_STATUS_DAO).findByReleaseId(1L); verify(RELEASE_STATUS_DAO).updateStatus(5L, DeploymentTaskStatus.COMPLETE); - verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(); + verify(DEPLOYMENT_ENVIRONMENT_DAO).findAllEnvironments(1L); verifyAuditRecorded(2L, Task.class, Action.CREATED); - verifyMultipleStatusRecordsAuditRecorded(1, TaskStatus.class, Action.CREATED); - verifyMultipleStatusRecordsAuditRecorded(1, ReleaseStatus.class, Action.UPDATED); + verifyMultipleStatusRecordsAuditRecorded(TaskStatus.class, Action.CREATED); + verifyMultipleStatusRecordsAuditRecorded(ReleaseStatus.class, Action.UPDATED); verifyNoMoreInteractions(TASK_DAO, TASK_STATUS_DAO, RELEASE_STATUS_DAO, DEPLOYMENT_ENVIRONMENT_DAO, AUDIT_RECORD_DAO); verifyNoInteractions(RELEASE_DAO); @@ -344,11 +411,11 @@ void shouldUpdateStatusForRelease() { when(RELEASE_STATUS_DAO.updateStatus(1L, DeploymentTaskStatus.COMPLETE)).thenReturn(1); var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases/{statusId}/{status}") - .resolveTemplate("statusId", 1L) - .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) - .request() - .put(json("")); + .target("/manual/deployment/tasks/releases/{statusId}/{status}") + .resolveTemplate("statusId", 1L) + .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) + .request() + .put(json("")); assertAcceptedResponse(response); @@ -362,11 +429,11 @@ void shouldReturn404ResponseWhenStatusNotFound() { when(RELEASE_STATUS_DAO.updateStatus(1L, DeploymentTaskStatus.COMPLETE)).thenReturn(0); var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases/{statusId}/{status}") - .resolveTemplate("statusId", 1L) - .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) - .request() - .put(json("")); + .target("/manual/deployment/tasks/releases/{statusId}/{status}") + .resolveTemplate("statusId", 1L) + .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) + .request() + .put(json("")); assertNotFoundResponse(response); } @@ -380,11 +447,11 @@ void shouldUpdateStatusForTask() { when(TASK_STATUS_DAO.updateStatus(1L, DeploymentTaskStatus.COMPLETE)).thenReturn(1); var response = RESOURCES.client() - .target("/manual/deployment/tasks/{statusId}/{status}") - .resolveTemplate("statusId", 1L) - .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) - .request() - .put(json("")); + .target("/manual/deployment/tasks/{statusId}/{status}") + .resolveTemplate("statusId", 1L) + .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) + .request() + .put(json("")); assertAcceptedResponse(response); @@ -398,11 +465,11 @@ void shouldReturn404ResponseWhenStatusNotFound() { when(TASK_STATUS_DAO.updateStatus(1L, DeploymentTaskStatus.COMPLETE)).thenReturn(0); var response = RESOURCES.client() - .target("/manual/deployment/tasks/{statusId}/{status}") - .resolveTemplate("statusId", 1L) - .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) - .request() - .put(json("")); + .target("/manual/deployment/tasks/{statusId}/{status}") + .resolveTemplate("statusId", 1L) + .resolveTemplate("status", DeploymentTaskStatus.COMPLETE) + .request() + .put(json("")); assertNotFoundResponse(response); } @@ -414,10 +481,10 @@ class DeleteRelease { @Test void shouldDeleteRelease() { var response = RESOURCES.client() - .target("/manual/deployment/tasks/releases/{releaseId}") - .resolveTemplate("releaseId", 1L) - .request() - .delete(); + .target("/manual/deployment/tasks/releases/{releaseId}") + .resolveTemplate("releaseId", 1L) + .request() + .delete(); assertAcceptedResponse(response); verify(RELEASE_DAO).deleteById(1L); @@ -432,17 +499,17 @@ class DeleteTask { @Test void shouldDeleteTask() { var task = Task.builder() - .id(1L) - .releaseId(1L) - .build(); - + .id(1L) + .releaseId(1L) + .build(); + when(TASK_DAO.findById(1L)).thenReturn(Optional.of(task)); var response = RESOURCES.client() - .target("/manual/deployment/tasks/{taskId}") - .resolveTemplate("taskId", 1L) - .request() - .delete(); + .target("/manual/deployment/tasks/{taskId}") + .resolveTemplate("taskId", 1L) + .request() + .delete(); assertAcceptedResponse(response); verify(TASK_DAO).deleteById(1L); @@ -455,10 +522,10 @@ void shouldReturn404WhenTaskNotFound() { when(TASK_DAO.findById(1L)).thenReturn(Optional.empty()); var response = RESOURCES.client() - .target("/manual/deployment/tasks/{taskId}") - .resolveTemplate("taskId", 1L) - .request() - .delete(); + .target("/manual/deployment/tasks/{taskId}") + .resolveTemplate("taskId", 1L) + .request() + .delete(); assertNotFoundResponse(response); } @@ -485,10 +552,10 @@ void shouldKeepOriginalStatusIfNoTasks() { private ReleaseStatus newReleaseStatus(DeploymentTaskStatus status) { return ReleaseStatus.builder() - .id(1L) - .environmentId(1L) - .status(status) - .build(); + .id(1L) + .environmentId(1L) + .status(status) + .build(); } @Test @@ -514,10 +581,10 @@ void shouldIgnoreStatusUpdateWhenStatusDoesNotChange() { private TaskStatus newTaskStatus(DeploymentTaskStatus status) { return TaskStatus.builder() - .id(1L) - .environmentId(1L) - .status(status) - .build(); + .id(1L) + .environmentId(1L) + .status(status) + .build(); } @Test @@ -710,28 +777,29 @@ class GetReleaseStages { @Test void shouldReleaseStages() { var response = RESOURCES.client() - .target("/manual/deployment/tasks/stages") - .request() - .get(); + .target("/manual/deployment/tasks/stages") + .request() + .get(); assertOkResponse(response); - var result = response.readEntity(new GenericType>(){}); + var result = response.readEntity(new GenericType>() { + }); assertThat(result).contains(ReleaseStage.values()); } - + } - + private void verifyAuditRecorded(long id, Class taskClass, Action action) { verify(AUDIT_RECORD_DAO).insertAuditRecord(argThat(audit -> audit.getRecordId() == id - && audit.getRecordType().equalsIgnoreCase(taskClass.getSimpleName()) - && audit.getAction() == action)); + && audit.getRecordType().equalsIgnoreCase(taskClass.getSimpleName()) + && audit.getAction() == action)); } - private void verifyMultipleStatusRecordsAuditRecorded(int times, Class statusClass, Action action) { - verify(AUDIT_RECORD_DAO, times(times)).insertAuditRecord( + private void verifyMultipleStatusRecordsAuditRecorded(Class statusClass, Action action) { + verify(AUDIT_RECORD_DAO).insertAuditRecord( argThat(audit -> audit.getRecordType().equalsIgnoreCase(statusClass.getSimpleName()) && audit.getAction() == action)); } diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilterTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilterTest.java new file mode 100644 index 00000000..6951c57a --- /dev/null +++ b/service/src/test/java/org/kiwiproject/champagne/resource/filter/DeployableSystemRequestFilterTest.java @@ -0,0 +1,79 @@ +package org.kiwiproject.champagne.resource.filter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.dhatim.dropwizard.jwt.cookie.authentication.DefaultJwtCookiePrincipal; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.kiwiproject.champagne.dao.DeployableSystemDao; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.core.SecurityContext; + +@DisplayName("DeployableSystemRequestFilter") +class DeployableSystemRequestFilterTest { + + @BeforeEach + void setUp() { + DeployableSystemThreadLocal.clearDeployableSystem(); + } + + @Test + void shouldNotSetDeployableSystemWhenHeaderNotSet() { + var dao = mock(DeployableSystemDao.class); + var filter = new DeployableSystemRequestFilter(dao); + + var context = mock(ContainerRequestContext.class); + when(context.getHeaderString("DeployableSystem")).thenReturn(null); + + filter.filter(context); + + assertThat(DeployableSystemThreadLocal.getCurrentDeployableSystem()).isEmpty(); + } + + @Test + void shouldNotSetDeployableSystemWhenHeaderSetButUserNotInSystem() { + var dao = mock(DeployableSystemDao.class); + var filter = new DeployableSystemRequestFilter(dao); + + var context = mock(ContainerRequestContext.class); + when(context.getHeaderString("DeployableSystem")).thenReturn("1"); + + var securityContext = mock(SecurityContext.class); + when(context.getSecurityContext()).thenReturn(securityContext); + + var principal = new DefaultJwtCookiePrincipal("bob"); + when(securityContext.getUserPrincipal()).thenReturn(principal); + + when(dao.isUserBySystemIdentifierInSystem("bob", 1)).thenReturn(false); + + filter.filter(context); + + assertThat(DeployableSystemThreadLocal.getCurrentDeployableSystem()).isEmpty(); + } + + @Test + void shouldSetDeployableSystemWhenHeaderSetAndUserInSystem() { + var dao = mock(DeployableSystemDao.class); + var filter = new DeployableSystemRequestFilter(dao); + + var context = mock(ContainerRequestContext.class); + when(context.getHeaderString("DeployableSystem")).thenReturn("1"); + + var securityContext = mock(SecurityContext.class); + when(context.getSecurityContext()).thenReturn(securityContext); + + var principal = new DefaultJwtCookiePrincipal("bob"); + when(securityContext.getUserPrincipal()).thenReturn(principal); + + when(dao.isUserBySystemIdentifierInSystem("bob", 1)).thenReturn(true); + + filter.filter(context); + + assertThat(DeployableSystemThreadLocal.getCurrentDeployableSystem()).contains(1L); + } +} diff --git a/service/src/test/java/org/kiwiproject/champagne/resource/filter/DeployableSystemResponseFilterTest.java b/service/src/test/java/org/kiwiproject/champagne/resource/filter/DeployableSystemResponseFilterTest.java new file mode 100644 index 00000000..d9558011 --- /dev/null +++ b/service/src/test/java/org/kiwiproject/champagne/resource/filter/DeployableSystemResponseFilterTest.java @@ -0,0 +1,25 @@ +package org.kiwiproject.champagne.resource.filter; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.kiwiproject.champagne.model.DeployableSystemThreadLocal; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; + +@DisplayName("DeployableSystemResponseFilter") +class DeployableSystemResponseFilterTest { + + @Test + void shouldClearDeployableSystem() { + DeployableSystemThreadLocal.setCurrentDeployableSystem(1L); + var filter = new DeployableSystemResponseFilter(); + + filter.filter(mock(ContainerRequestContext.class), mock(ContainerResponseContext.class)); + + assertThat(DeployableSystemThreadLocal.getCurrentDeployableSystem()).isEmpty(); + } +} diff --git a/service/src/test/java/org/kiwiproject/champagne/util/TestObjects.java b/service/src/test/java/org/kiwiproject/champagne/util/TestObjects.java index 8c650b74..92fd8910 100644 --- a/service/src/test/java/org/kiwiproject/champagne/util/TestObjects.java +++ b/service/src/test/java/org/kiwiproject/champagne/util/TestObjects.java @@ -26,31 +26,33 @@ @UtilityClass public class TestObjects { - public static long insertAuditRecord(Handle handle) { + public static long insertAuditRecord(Handle handle, long systemId) { var testAuditRecord = AuditRecord.builder() - .userSystemIdentifier("jdoe") - .action(Action.UPDATED) - .recordType("Task") - .recordId(1L) - .build(); - - return handle.createUpdate("insert into audit_records (user_system_identifier, action, record_type, record_id) values (:userSystemIdentifier, :action, :recordType, :recordId)") - .bindBean(testAuditRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .userSystemIdentifier("jdoe") + .action(Action.UPDATED) + .recordType("Task") + .recordId(1L) + .deployableSystemId(systemId) + .build(); + + return handle.createUpdate("insert into audit_records (user_system_identifier, action, record_type, record_id, deployable_system_id) values (:userSystemIdentifier, :action, :recordType, :recordId, :deployableSystemId)") + .bindBean(testAuditRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } - public static long insertDeploymentEnvironmentRecord(Handle handle, String name) { + public static long insertDeploymentEnvironmentRecord(Handle handle, String name, long systemId) { var testDeploymentEnvironmentRecord = DeploymentEnvironment.builder() - .name(name) - .build(); - - return handle.createUpdate("insert into deployment_environments (environment_name) values (:name)") - .bindBean(testDeploymentEnvironmentRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .name(name) + .deployableSystemId(systemId) + .build(); + + return handle.createUpdate("insert into deployment_environments (environment_name, deployable_system_id) values (:name, :deployableSystemId)") + .bindBean(testDeploymentEnvironmentRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } public static long insertUserRecord(Handle handle, String systemIdentifier) { @@ -59,89 +61,92 @@ public static long insertUserRecord(Handle handle, String systemIdentifier) { public static long insertUserRecord(Handle handle, String systemIdentifier, String firstName, String lastName) { var testUserRecord = User.builder() - .systemIdentifier(systemIdentifier) - .firstName(firstName) - .lastName(lastName) - .displayName(firstName + " " + lastName) - .build(); + .systemIdentifier(systemIdentifier) + .firstName(firstName) + .lastName(lastName) + .displayName(firstName + " " + lastName) + .build(); return handle.createUpdate("insert into users (system_identifier, first_name, last_name, display_name) values (:systemIdentifier, :firstName, :lastName, :displayName)") - .bindBean(testUserRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .bindBean(testUserRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } - public static long insertReleaseRecord(Handle handle, String releaseNumber) { + public static long insertReleaseRecord(Handle handle, String releaseNumber, long systemId) { var testReleaseRecord = Release.builder() - .releaseNumber(releaseNumber) - .build(); - - return handle.createUpdate("insert into manual_deployment_task_releases (release_number) values (:releaseNumber)") - .bindBean(testReleaseRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .releaseNumber(releaseNumber) + .deployableSystemId(systemId) + .build(); + + return handle.createUpdate("insert into manual_deployment_task_releases (release_number, deployable_system_id) values (:releaseNumber, :deployableSystemId)") + .bindBean(testReleaseRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } public static long insertReleaseStatusRecord(Handle handle, DeploymentTaskStatus status) { - var releaseId = insertReleaseRecord(handle, "42"); - return insertReleaseStatusRecord(handle, status, releaseId); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); + return insertReleaseStatusRecord(handle, status, releaseId, systemId); } - public static long insertReleaseStatusRecord(Handle handle, DeploymentTaskStatus status, long releaseId) { - var envId = insertDeploymentEnvironmentRecord(handle, "DEV"); + public static long insertReleaseStatusRecord(Handle handle, DeploymentTaskStatus status, long releaseId, long systemId) { + var envId = insertDeploymentEnvironmentRecord(handle, "DEV", systemId); var testReleaseStatusRecord = ReleaseStatus.builder() - .releaseId(releaseId) - .environmentId(envId) - .status(status) - .build(); + .releaseId(releaseId) + .environmentId(envId) + .status(status) + .build(); return handle.createUpdate("insert into manual_deployment_task_release_statuses (manual_deployment_task_release_id, deployment_environment_id, status) values (:releaseId, :environmentId, :status)") - .bindBean(testReleaseStatusRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .bindBean(testReleaseStatusRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } public static long insertTaskRecord(Handle handle, String summary) { - var releaseId = insertReleaseRecord(handle, "42"); + var systemId = insertDeployableSystem(handle, "kiwi"); + var releaseId = insertReleaseRecord(handle, "42", systemId); return insertTaskRecord(handle, summary, releaseId); } public static long insertTaskRecord(Handle handle, String summary, long releaseId) { var testTaskRecord = Task.builder() - .releaseId(releaseId) - .stage(ReleaseStage.POST) - .summary(summary) - .component("component") - .build(); + .releaseId(releaseId) + .stage(ReleaseStage.POST) + .summary(summary) + .component("component") + .build(); return handle.createUpdate("insert into manual_deployment_tasks (manual_deployment_task_release_id, stage, summary, component) values (:releaseId, :stage, :summary, :component)") - .bindBean(testTaskRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .bindBean(testTaskRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } - public static long insertTaskStatusRecord(Handle handle, DeploymentTaskStatus status, long taskId) { - var envId = insertDeploymentEnvironmentRecord(handle, "DEV"); + public static long insertTaskStatusRecord(Handle handle, DeploymentTaskStatus status, long taskId, long systemId) { + var envId = insertDeploymentEnvironmentRecord(handle, "DEV", systemId); var testTaskStatusRecord = TaskStatus.builder() - .taskId(taskId) - .environmentId(envId) - .status(status) - .build(); + .taskId(taskId) + .environmentId(envId) + .status(status) + .build(); return handle.createUpdate("insert into manual_deployment_task_statuses (manual_deployment_task_id, deployment_environment_id, status) values (:taskId, :environmentId, :status)") - .bindBean(testTaskStatusRecord) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + .bindBean(testTaskStatusRecord) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } - public static long insertBuildRecord(Handle handle, String identifier, String version) { + public static long insertBuildRecord(Handle handle, String identifier, String version, long systemId) { var buildToInsert = Build.builder() .repoNamespace("kiwiproject") .repoName(identifier) @@ -153,36 +158,38 @@ public static long insertBuildRecord(Handle handle, String identifier, String ve .distributionLocation("https://some-nexus-server.net/foo") .extraDeploymentInfo(Map.of()) .gitProvider(GitProvider.GITHUB) + .deployableSystemId(systemId) .build(); - return handle.createUpdate("insert into builds " - + "(repo_namespace, repo_name, commit_ref, commit_user, source_branch, component_identifier, component_version, distribution_location, extra_deployment_info, git_provider) " - + "values " - + "(:repoNamespace, :repoName, :commitRef, :commitUser, :sourceBranch, :componentIdentifier, :componentVersion, :distributionLocation, :extraData, :gitProvider)") - .bindBean(buildToInsert) - .bind("extraData", "{}") - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + return handle.createUpdate("insert into builds " + + "(repo_namespace, repo_name, commit_ref, commit_user, source_branch, component_identifier, component_version, distribution_location, extra_deployment_info, git_provider, deployable_system_id) " + + "values " + + "(:repoNamespace, :repoName, :commitRef, :commitUser, :sourceBranch, :componentIdentifier, :componentVersion, :distributionLocation, :extraData, :gitProvider, :deployableSystemId)") + .bindBean(buildToInsert) + .bind("extraData", "{}") + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } - public static long insertHostRecord(Handle handle, String hostname, long envId) { + public static long insertHostRecord(Handle handle, String hostname, long envId, long systemId) { var hostToInsert = Host.builder() .environmentId(envId) .hostname(hostname) .source(Host.Source.CHAMPAGNE) .tags(List.of("foo")) + .deployableSystemId(systemId) .build(); - return handle.createUpdate("insert into hosts " - + "(environment_id, hostname, source, tags) " - + "values " - + "(:environmentId, :hostname, :source, :tagCsv)") - .bindBean(hostToInsert) - .bind("tagCsv", StringUtils.join(hostToInsert.getTags(), ",")) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + return handle.createUpdate("insert into hosts " + + "(environment_id, hostname, source, tags, deployable_system_id) " + + "values " + + "(:environmentId, :hostname, :source, :tagCsv, :deployableSystemId)") + .bindBean(hostToInsert) + .bind("tagCsv", StringUtils.join(hostToInsert.getTags(), ",")) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } public static long insertComponentRecord(Handle handle, String componentName, String tag) { @@ -191,14 +198,14 @@ public static long insertComponentRecord(Handle handle, String componentName, St .tag(tag) .build(); - return handle.createUpdate("insert into components " - + "(component_name, tag) " - + "values " - + "(:componentName, :tag)") - .bindBean(componentToInsert) - .executeAndReturnGeneratedKeys("id") - .mapTo(Long.class) - .first(); + return handle.createUpdate("insert into components " + + "(component_name, tag) " + + "values " + + "(:componentName, :tag)") + .bindBean(componentToInsert) + .executeAndReturnGeneratedKeys("id") + .mapTo(Long.class) + .first(); } public static long insertDeployableSystem(Handle handle, String name) { @@ -223,5 +230,5 @@ public static void insertUserToDeployableSystemLink(Handle handle, long userId, .bind("admin", admin) .execute(); } - + }