Skip to content

Commit

Permalink
29527 add sequencing facility (#205)
Browse files Browse the repository at this point in the history
* 29527 Add Sequencing Facility
Added db migration + entity + crud test

* 29527 Add Sequencing Facility
Added dto and repository

* 29527 Add Sequencing Facility
Added Open API specs testing
  • Loading branch information
cgendreau authored Dec 20, 2022
1 parent 74796b9 commit 2393f58
Show file tree
Hide file tree
Showing 12 changed files with 446 additions and 0 deletions.
37 changes: 37 additions & 0 deletions src/main/java/ca/gc/aafc/seqdb/api/dto/SequencingFacilityDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ca.gc.aafc.seqdb.api.dto;

import ca.gc.aafc.dina.dto.RelatedEntity;
import ca.gc.aafc.seqdb.api.entities.SequencingFacility;
import io.crnk.core.resource.annotations.JsonApiId;
import io.crnk.core.resource.annotations.JsonApiResource;
import lombok.Data;
import org.javers.core.metamodel.annotation.Id;
import org.javers.core.metamodel.annotation.PropertyName;
import org.javers.core.metamodel.annotation.TypeName;

import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;

@Data
@JsonApiResource(type = SequencingFacilityDto.TYPENAME)
@RelatedEntity(SequencingFacility.class)
@TypeName(SequencingFacilityDto.TYPENAME)
public class SequencingFacilityDto {

public static final String TYPENAME = "sequencing-facility";

@JsonApiId
@Id
@PropertyName("id")
private UUID uuid;

private String createdBy;
private OffsetDateTime createdOn;
private String group;
private String name;

private List<SequencingFacility.ContactRole> contacts = List.of();
private SequencingFacility.Address shippingAddress;

}
113 changes: 113 additions & 0 deletions src/main/java/ca/gc/aafc/seqdb/api/entities/SequencingFacility.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package ca.gc.aafc.seqdb.api.entities;

import ca.gc.aafc.dina.entity.DinaEntity;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.RequiredArgsConstructor;
import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.NaturalIdCache;
import org.hibernate.annotations.Type;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.OffsetDateTime;
import java.util.List;
import java.util.UUID;

@Entity
@Data
@AllArgsConstructor
@RequiredArgsConstructor
@Builder
@NaturalIdCache
@Table(name = "sequencing_facility")
public class SequencingFacility implements DinaEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

@NaturalId
@NotNull
@Column(unique = true)
private UUID uuid;

@NotBlank
@Column(name = "created_by", updatable = false)
private String createdBy;

@Column(name = "created_on", insertable = false, updatable = false)
@Generated(value = GenerationTime.INSERT)
private OffsetDateTime createdOn;

@NotBlank
@Size(max = 50)
@Column(name = "_group")
private String group;

@NotBlank
@Size(max = 50)
private String name;

@Type(type = "jsonb")
@Column(name = "contacts", columnDefinition = "jsonb")
@Valid
private List<ContactRole> contacts = List.of();

@Type(type = "jsonb")
@Column(name = "shipping_address", columnDefinition = "jsonb")
@Valid
private Address shippingAddress;

@Data
@Builder
public static class ContactRole {

@NotEmpty
private String name;

@NotEmpty
private List<@NotBlank String> roles;

@Size(max = 100)
private String info;

}

// TODO to be replaced by dina-base-api version in 0.99
@Data
@Builder
public static class Address {

@Size (max = 150)
private String addressLine1;

@Size (max = 150)
private String addressLine2;

@Size (max = 150)
private String city;

@Size (max = 150)
private String provinceState;

@Size (max = 50)
private String zipCode;

@Size (max = 50)
private String country;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package ca.gc.aafc.seqdb.api.repository;

import ca.gc.aafc.dina.mapper.DinaMapper;
import ca.gc.aafc.dina.repository.DinaRepository;
import ca.gc.aafc.dina.repository.external.ExternalResourceProvider;
import ca.gc.aafc.dina.security.DinaAuthorizationService;
import ca.gc.aafc.dina.service.DinaService;
import ca.gc.aafc.seqdb.api.dto.SequencingFacilityDto;
import ca.gc.aafc.seqdb.api.entities.SequencingFacility;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.NonNull;
import org.springframework.boot.info.BuildProperties;
import org.springframework.stereotype.Repository;

import java.util.Optional;

@Repository
public class SequencingFacilityRepository extends DinaRepository<SequencingFacilityDto, SequencingFacility> {

public SequencingFacilityRepository(
@NonNull DinaService<SequencingFacility> dinaService,
DinaAuthorizationService groupAuthorizationService,
@NonNull BuildProperties props,
ExternalResourceProvider externalResourceProvider,
ObjectMapper objMapper) {
super(
dinaService,
groupAuthorizationService,
Optional.empty(),
new DinaMapper<>(SequencingFacilityDto.class),
SequencingFacilityDto.class, SequencingFacility.class,
null,
externalResourceProvider,
props, objMapper);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package ca.gc.aafc.seqdb.api.service;

import ca.gc.aafc.dina.jpa.BaseDAO;
import ca.gc.aafc.dina.service.DefaultDinaService;

import ca.gc.aafc.seqdb.api.entities.SequencingFacility;
import lombok.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.validation.SmartValidator;

import java.util.UUID;

@Service
public class SequencingFacilityService extends DefaultDinaService<SequencingFacility> {

public SequencingFacilityService(
@NonNull BaseDAO baseDAO,
@NonNull SmartValidator sv) {
super(baseDAO, sv);
}

@Override
protected void preCreate(SequencingFacility entity) {
entity.setUuid(UUID.randomUUID());
}
}

1 change: 1 addition & 0 deletions src/main/resources/db/changelog/db.changelog-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,5 @@
<include file="db/changelog/migrations/29-Replace_thermocycler_profile_steps_by_an_array.xml"/>
<include file="db/changelog/migrations/30-Allow_storage_unit_type_on_pcrbatch.xml"/>
<include file="db/changelog/migrations/31-Add_reaction_date_to_seqbatch.xml"/>
<include file="db/changelog/migrations/32-Add_sequencing_facility.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog https://local.xsd/dbchangelog-4.4.xsd"
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS">
<changeSet id="32-Create_Sequencing_Facility" context="schema-change" author="cgendreau">
<createTable tableName="sequencing_facility">
<column autoIncrement="true" name="id" type="SERIAL">
<constraints primaryKey="true" primaryKeyName="pk_sequencing_facility_id" />
</column>
<column name="uuid" type="uuid">
<constraints nullable="false" unique="true" />
</column>
<column name="created_by" type="VARCHAR(250)">
<constraints nullable="false"/>
</column>
<column name="_group" type="VARCHAR(50)">
<constraints nullable="false"/>
</column>
<column name="created_on" type="timestamptz" defaultValueComputed="current_timestamp"/>
<column name="name" type="VARCHAR(50)">
<constraints nullable="false"/>
</column>
<column name="shipping_address" type="jsonb"/>
<column name="contacts" type="jsonb"/>
</createTable>
</changeSet>
</databaseChangeLog>
4 changes: 4 additions & 0 deletions src/test/java/ca/gc/aafc/seqdb/api/SequenceModuleBaseIT.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import ca.gc.aafc.seqdb.api.service.PcrBatchItemService;
import ca.gc.aafc.seqdb.api.service.SeqSubmissionService;
import ca.gc.aafc.seqdb.api.service.SequencingFacilityService;

public class SequenceModuleBaseIT extends BaseIntegrationTest {

Expand All @@ -12,5 +13,8 @@ public class SequenceModuleBaseIT extends BaseIntegrationTest {

@Inject
protected SeqSubmissionService seqSubmissionService;

@Inject
protected SequencingFacilityService sequencingFacilityService;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package ca.gc.aafc.seqdb.api.entities;

import ca.gc.aafc.seqdb.api.SequenceModuleBaseIT;
import ca.gc.aafc.seqdb.api.testsupport.factories.SequencingFacilityFactory;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class SequenceFacilityCRUDIT extends SequenceModuleBaseIT {

private static final String EXPECTED_NAME = "name";
private static final String EXPECTED_GROUP = "DINA GROUP";
private static final String EXPECTED_CREATED_BY = "createdBy";

@Test
void create() {
SequencingFacility seqFacility = buildExpectedSequenceFacility();

sequencingFacilityService.create(seqFacility);

Assertions.assertNotNull(seqFacility.getId());
Assertions.assertNotNull(seqFacility.getCreatedOn());
Assertions.assertNotNull(seqFacility.getUuid());
}

@Test
void find() {
SequencingFacility seqFacility = buildExpectedSequenceFacility();

sequencingFacilityService.create(seqFacility);

SequencingFacility result = sequencingFacilityService.findOne(seqFacility.getUuid(), SequencingFacility.class);

Assertions.assertEquals(EXPECTED_NAME, result.getName());
Assertions.assertEquals(EXPECTED_GROUP, result.getGroup());
Assertions.assertEquals(EXPECTED_CREATED_BY, result.getCreatedBy());
}

private SequencingFacility buildExpectedSequenceFacility() {
return SequencingFacilityFactory.newSequencingFacility()
.name(EXPECTED_NAME)
.group(EXPECTED_GROUP)
.createdBy(EXPECTED_CREATED_BY)
.build();

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package ca.gc.aafc.seqdb.api.openapi;

import ca.gc.aafc.dina.testsupport.BaseRestAssuredTest;
import ca.gc.aafc.dina.testsupport.PostgresTestContainerInitializer;
import ca.gc.aafc.dina.testsupport.jsonapi.JsonAPITestHelper;
import ca.gc.aafc.dina.testsupport.specs.OpenAPI3Assertions;
import ca.gc.aafc.seqdb.api.SeqdbApiLauncher;
import ca.gc.aafc.seqdb.api.dto.SequencingFacilityDto;
import ca.gc.aafc.seqdb.api.testsupport.fixtures.SequencingFacilityTestFixture;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;

@SpringBootTest(
classes = SeqdbApiLauncher.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@TestPropertySource(properties = "spring.config.additional-location=classpath:application-test.yml")
@ContextConfiguration(initializers = {PostgresTestContainerInitializer.class})
public class SequencingFacilityOpenApiIT extends BaseRestAssuredTest {

protected SequencingFacilityOpenApiIT() {
super("/api");
}

@SneakyThrows
@Test
void sequencingFacility_SpecValid() {
SequencingFacilityDto sequencingFacility = SequencingFacilityTestFixture.newSequencingFacility();

OpenAPI3Assertions.assertRemoteSchema(OpenAPIConstants.SEQDB_API_SPECS_URL, "SequencingFacility",
sendPost(SequencingFacilityDto.TYPENAME, JsonAPITestHelper.toJsonAPIMap(SequencingFacilityDto.TYPENAME, JsonAPITestHelper.toAttributeMap(sequencingFacility),
null,
null)
).extract().asString());
}
}
Loading

0 comments on commit 2393f58

Please sign in to comment.