Skip to content

Commit

Permalink
Migration to Java21 and Neo4j 5.19.0 (#1313)
Browse files Browse the repository at this point in the history
Details:

Changes in this pull request introduce support for java21 and neo4j 5.19.0.

Deployment changes:

  Some changes to the circleci configuration, jitpack, and github actions workflow were needed.
  Jitpack by default runs builds with an older version of java but this can be addressed with the
  addition of a `jitpack.yml`. Circleci config also needed an update to allow circlular references
  during the app runtime. This is okay for now but perhaps can be addressed in the future.

App configuration:

  The SMILE app configuration is mostly the same. There is now an added bean in the app
  configuration that explicitly sets the session factory for the neo4j driver.

Model layer:

  The model layer changes include updates to the annotations classes used.

Persistence layer:

  Appart from updating relevant annotations used for the persistence layer, some queries were
  cleaned up, removed, and/or improved to consolidate additional calls that were populating
  child edges and nodes. Example, we were using 2 calls to (1) fetch SampleMetadata nodes and (2)
  fetch the related SampleStatus nodes for the SampleMetadata nodes. This is now accomplished with
  one single query.

Service layer:

  For the most part the service layer has remained the same. Some cleanup and refactoring were done
  to remove unused methods and/or methods that were made redundant due to the improved/consolidated
  queries modified in the persistence layer.

Test layer:

  This layer required the most work as in addition to updating java and the testcontainers
  for supporting a newer neo4j instance, we also migrated the test framework to junit-jupiter.

  One of the major changes in the test classes is the use of @SpringBootTest annotations instead
  of using the @DataNeo4jTest annotation. There's also additional @TestConfiguration settings that
  needed to be introduced to support the updated test framework and components.

Web layer:

  Some relatively minor changes introduced here to migrate away from swagger by springfox to
  swagger by open api. Reference documentation: https://springdoc.org/#migrating-from-springfox

Signed-off-by: Angelica Ochoa <[email protected]>

Update docker file for java21 (#1317)

Signed-off-by: Angelica Ochoa <[email protected]>

Fix for correcting CMO patient IDs (#1319)

Fix for optional matching on sample status

Signed-off-by: Angelica Ochoa <[email protected]>

Fix end date formatter (#1320)

Signed-off-by: Angelica Ochoa <[email protected]>
  • Loading branch information
ao508 committed Nov 13, 2024
1 parent aa9052e commit 4a05c84
Show file tree
Hide file tree
Showing 50 changed files with 855 additions and 677 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
run_checkstyle:
working_directory: /tmp/repos/smile-server
machine:
image: ubuntu-2004:202201-02
image: ubuntu-2004:2024.05.1
steps:
- checkout
- run:
Expand All @@ -19,7 +19,7 @@ jobs:
git checkout ${SMILE_COMMONS_VERSION}
- run:
name: "Build project and run checkstyle plugin..."
command: mvn clean install
command: mvn clean install -Dspring.main.allow-circular-references=true
- run:
name: "Running checkstyle plugin..."
command: mvn checkstyle:checkstyle
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
FROM maven:3.6.1-jdk-11-slim
FROM maven:3.8.8
RUN mkdir /smile-server
ADD . /smile-server
WORKDIR /smile-server
RUN mvn clean install -DskipTests

FROM openjdk:11-slim
FROM openjdk:21
COPY --from=0 /smile-server/server/target/smile_server.jar /smile-server/smile_server.jar
ENTRYPOINT ["java"]
9 changes: 9 additions & 0 deletions jitpack.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
jdk:
- openjdk21

before_install:
- sdk install maven 3.8.8
- sdk use maven 3.8.8
- sdk install java 21.0.2-open
- sdk use java 21.0.2-open
- sdk update
5 changes: 0 additions & 5 deletions model/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@
</parent>
<dependencies>
<!-- neo4j dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-neo4j</artifactId>
<version>${spring.boot.version}</version>
</dependency>
<dependency>
<groupId>org.neo4j</groupId>
<artifactId>neo4j-ogm</artifactId>
Expand Down
14 changes: 0 additions & 14 deletions model/src/main/java/org/mskcc/smile/model/PatientAlias.java
Original file line number Diff line number Diff line change
@@ -1,27 +1,21 @@
package org.mskcc.smile.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;

/**
*
* @author ochoaa
*/

@NodeEntity
public class PatientAlias implements Serializable {
@Id @GeneratedValue
private Long id;
private String value;
private String namespace;
@JsonIgnore
@Relationship(type = "IS_ALIAS", direction = Relationship.OUTGOING)
private SmilePatient smilePatient;

public PatientAlias() {}

Expand All @@ -46,14 +40,6 @@ public void setNamespace(String namespace) {
this.namespace = namespace;
}

public SmilePatient getSmilePatient() {
return smilePatient;
}

public void setSmilePatient(SmilePatient smilePatient) {
this.smilePatient = smilePatient;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class RequestMetadata implements Serializable, Comparable<RequestMetadata
private String igoRequestId;
private String requestMetadataJson;
private String importDate;
@Relationship(type = "HAS_STATUS", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_STATUS", direction = Relationship.Direction.OUTGOING)
private Status status;

/**
Expand Down
15 changes: 1 addition & 14 deletions model/src/main/java/org/mskcc/smile/model/SampleAlias.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
package org.mskcc.smile.model;

import com.fasterxml.jackson.annotation.JsonIgnore;
import java.io.Serializable;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.neo4j.ogm.annotation.GeneratedValue;
import org.neo4j.ogm.annotation.Id;
import org.neo4j.ogm.annotation.NodeEntity;
import org.neo4j.ogm.annotation.Relationship;

/**
* Node entity representing the linked sample entity from an external system.
* @author ochoaa
*/

@NodeEntity
public class SampleAlias implements Serializable {
@Id @GeneratedValue
private Long id;
private String value;
private String namespace;
@JsonIgnore
@Relationship(type = "IS_ALIAS", direction = Relationship.OUTGOING)
private SmileSample sampleMetadata;

public SampleAlias() {}

Expand Down Expand Up @@ -50,14 +45,6 @@ public void setNamespace(String namespace) {
this.namespace = namespace;
}

public SmileSample getSampleMetadata() {
return sampleMetadata;
}

public void setSampleMetadata(SmileSample sampleMetadata) {
this.sampleMetadata = sampleMetadata;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public class SampleMetadata implements Serializable, Comparable<SampleMetadata>,
private Map<String, String> cmoSampleIdFields;
@Convert(MapStringConverter.class)
private Map<String, String> additionalProperties = new HashMap<>();
@Relationship(type = "HAS_STATUS", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_STATUS", direction = Relationship.Direction.OUTGOING)
private Status status;

public SampleMetadata() {}
Expand Down
4 changes: 2 additions & 2 deletions model/src/main/java/org/mskcc/smile/model/SmilePatient.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ public class SmilePatient implements Serializable {
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID smilePatientId;
@Relationship(type = "HAS_SAMPLE", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_SAMPLE", direction = Relationship.Direction.OUTGOING)
private List<SmileSample> smileSampleList;
@Relationship(type = "IS_ALIAS", direction = Relationship.INCOMING)
@Relationship(type = "IS_ALIAS", direction = Relationship.Direction.INCOMING)
private List<PatientAlias> patientAliases;

public SmilePatient() {}
Expand Down
3 changes: 1 addition & 2 deletions model/src/main/java/org/mskcc/smile/model/SmileProject.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class SmileProject implements Serializable {
@Id
private String igoProjectId;
private String namespace;
@Relationship(type = "HAS_REQUEST", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_REQUEST", direction = Relationship.Direction.OUTGOING)
private List<SmileRequest> requestList;

public SmileProject() {}
Expand Down Expand Up @@ -73,5 +73,4 @@ public void addRequest(SmileRequest smileRequest) {
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

}
6 changes: 3 additions & 3 deletions model/src/main/java/org/mskcc/smile/model/SmileRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ public class SmileRequest implements Serializable {
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID smileRequestId;
@Relationship(type = "HAS_SAMPLE", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_SAMPLE", direction = Relationship.Direction.OUTGOING)
private List<SmileSample> smileSampleList;
@Relationship(type = "HAS_REQUEST", direction = Relationship.INCOMING)
@Relationship(type = "HAS_REQUEST", direction = Relationship.Direction.INCOMING)
private SmileProject smileProject;
@JsonIgnore
@Relationship(type = "HAS_METADATA", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_METADATA", direction = Relationship.Direction.OUTGOING)
private List<RequestMetadata> requestMetadataList;
@JsonIgnore
private String namespace;
Expand Down
54 changes: 27 additions & 27 deletions model/src/main/java/org/mskcc/smile/model/SmileSample.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ public class SmileSample implements Serializable {
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
private UUID smileSampleId;
@Relationship(type = "IS_ALIAS", direction = Relationship.INCOMING)
@Relationship(type = "IS_ALIAS", direction = Relationship.Direction.INCOMING)
private List<SampleAlias> sampleAliases;
@Relationship(type = "HAS_SAMPLE", direction = Relationship.INCOMING)
@Relationship(type = "HAS_SAMPLE", direction = Relationship.Direction.INCOMING)
private SmilePatient patient;
@Relationship(type = "HAS_METADATA", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_METADATA", direction = Relationship.Direction.OUTGOING)
private List<SampleMetadata> sampleMetadataList;
@Relationship(type = "HAS_TEMPO", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_TEMPO", direction = Relationship.Direction.OUTGOING)
private Tempo tempo;
private String sampleClass;
private String sampleCategory;
Expand Down Expand Up @@ -161,32 +161,33 @@ public SampleMetadata getLatestSampleMetadata() throws ParseException {
/**
* Applies IGO LIMS updates for the following fields
* @param sampleMetadata
* @return
* @throws java.text.ParseException
*/
public void applyIgoLimsUpdates(SampleMetadata sampleMetadata) throws ParseException {
SampleMetadata latestSampleMetadata = getLatestSampleMetadata();

sampleMetadata.setId(null);
sampleMetadata.setCmoPatientId(latestSampleMetadata.getCmoPatientId());
sampleMetadata.setInvestigatorSampleId(latestSampleMetadata.getInvestigatorSampleId());
sampleMetadata.setInvestigatorSampleId(latestSampleMetadata.getInvestigatorSampleId());
sampleMetadata.setSampleName(latestSampleMetadata.getSampleName());
sampleMetadata.setCmoInfoIgoId(latestSampleMetadata.getCmoInfoIgoId());
sampleMetadata.setOncotreeCode(latestSampleMetadata.getOncotreeCode());
sampleMetadata.setCollectionYear(latestSampleMetadata.getCollectionYear());
sampleMetadata.setTubeId(latestSampleMetadata.getTubeId());
sampleMetadata.setSpecies(latestSampleMetadata.getSpecies());
sampleMetadata.setSex(latestSampleMetadata.getSex());
sampleMetadata.setTumorOrNormal(latestSampleMetadata.getTumorOrNormal());
sampleMetadata.setSampleType(latestSampleMetadata.getSampleType());
sampleMetadata.setPreservation(latestSampleMetadata.getPreservation());
sampleMetadata.setSampleClass(latestSampleMetadata.getSampleClass());
sampleMetadata.setSampleOrigin(latestSampleMetadata.getSampleOrigin());
sampleMetadata.setTissueLocation(latestSampleMetadata.getTissueLocation());
sampleMetadata.setGenePanel(latestSampleMetadata.getGenePanel());
sampleMetadata.setIgoComplete(latestSampleMetadata.getIgoComplete());

addSampleMetadata(sampleMetadata);
latestSampleMetadata.setId(null);
// prevent having multiple sample metdata nodes pointing to the same status node
latestSampleMetadata.setStatus(sampleMetadata.getStatus());
// apply updates from igo data received
latestSampleMetadata.setCmoPatientId(sampleMetadata.getCmoPatientId());
latestSampleMetadata.setInvestigatorSampleId(sampleMetadata.getInvestigatorSampleId());
latestSampleMetadata.setSampleName(sampleMetadata.getSampleName());
latestSampleMetadata.setCmoInfoIgoId(sampleMetadata.getCmoInfoIgoId());
latestSampleMetadata.setOncotreeCode(sampleMetadata.getOncotreeCode());
latestSampleMetadata.setTubeId(sampleMetadata.getTubeId());
latestSampleMetadata.setSpecies(sampleMetadata.getSpecies());
latestSampleMetadata.setSex(sampleMetadata.getSex());
latestSampleMetadata.setTumorOrNormal(sampleMetadata.getTumorOrNormal());
latestSampleMetadata.setSampleType(sampleMetadata.getSampleType());
latestSampleMetadata.setPreservation(sampleMetadata.getPreservation());
latestSampleMetadata.setSampleClass(sampleMetadata.getSampleClass());
latestSampleMetadata.setSampleOrigin(sampleMetadata.getSampleOrigin());
latestSampleMetadata.setTissueLocation(sampleMetadata.getTissueLocation());
latestSampleMetadata.setGenePanel(sampleMetadata.getGenePanel());
latestSampleMetadata.setIgoComplete(sampleMetadata.getIgoComplete());
latestSampleMetadata.setBaitSet(sampleMetadata.getBaitSet());
addSampleMetadata(latestSampleMetadata);
}

public void updateSampleMetadata(SampleMetadata sampleMetadata) throws ParseException {
Expand Down Expand Up @@ -230,5 +231,4 @@ public void setTempo(Tempo tempo) {
public String toString() {
return ToStringBuilder.reflectionToString(this);
}

}
2 changes: 1 addition & 1 deletion model/src/main/java/org/mskcc/smile/model/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class Status implements Serializable {

public Status() {
this.validationStatus = Boolean.TRUE;
this.validationReport = "";
this.validationReport = "{}";
}

public Status(Boolean validationStatus,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.Entity;
import javax.persistence.Id;
import org.apache.commons.lang.builder.ToStringBuilder;

@Entity
Expand Down
4 changes: 2 additions & 2 deletions model/src/main/java/org/mskcc/smile/model/tempo/Cohort.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ public class Cohort implements Serializable {
@Id @GeneratedValue
private Long id;
private String cohortId;
@Relationship(type = "HAS_COHORT_COMPLETE", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_COHORT_COMPLETE", direction = Relationship.Direction.OUTGOING)
private List<CohortComplete> cohortCompleteList;
@Relationship(type = "HAS_COHORT_SAMPLE", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_COHORT_SAMPLE", direction = Relationship.Direction.OUTGOING)
private List<SmileSample> cohortSamples;

public Cohort() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
* Represents a MAF Complete entity.
* @author qu8n
*/
@NodeEntity
@NodeEntity(label = "MafComplete")
public class MafComplete implements Serializable {
@Id @GeneratedValue
private Long id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*
* @author ochoaa
*/
@NodeEntity
@NodeEntity(label = "QcComplete")
public class QcComplete implements Serializable {
@Id @GeneratedValue
private Long id;
Expand Down
10 changes: 5 additions & 5 deletions model/src/main/java/org/mskcc/smile/model/tempo/Tempo.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*
* @author ochoaa
*/
@NodeEntity
@NodeEntity(label = "Tempo")
public class Tempo implements Serializable {
@Id @GeneratedValue(strategy = UuidStrategy.class)
@Convert(UuidStringConverter.class)
Expand All @@ -28,13 +28,13 @@ public class Tempo implements Serializable {
private Boolean billed;
private String billedBy;
private String costCenter;
@Relationship(type = "HAS_EVENT", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_EVENT", direction = Relationship.Direction.OUTGOING)
private List<BamComplete> bamCompleteEvents;
@Relationship(type = "HAS_EVENT", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_EVENT", direction = Relationship.Direction.OUTGOING)
private List<QcComplete> qcCompleteEvents;
@Relationship(type = "HAS_EVENT", direction = Relationship.OUTGOING)
@Relationship(type = "HAS_EVENT", direction = Relationship.Direction.OUTGOING)
private List<MafComplete> mafCompleteEvents;
@Relationship(type = "HAS_TEMPO", direction = Relationship.INCOMING)
@Relationship(type = "HAS_TEMPO", direction = Relationship.Direction.INCOMING)
private SmileSample sample;

public Tempo() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@
*/
@Repository
public interface CohortCompleteRepository extends Neo4jRepository<Cohort, Long> {
@Query("MATCH (c: Cohort {cohortId: $cohortId}) RETURN c")
@Query("MATCH (c: Cohort {cohortId: $cohortId})-[hcc:HAS_COHORT_COMPLETE]->(cc: CohortComplete) "
+ "RETURN c, hcc, cc")
Cohort findCohortByCohortId(@Param("cohortId") String cohortId);

@Query("MATCH (c: Cohort {cohortId: $cohortId})-[:HAS_COHORT_COMPLETE]->(cc: CohortComplete) "
+ "RETURN cc")
List<CohortComplete> findCohortCompleteEventsByCohortId(@Param("cohortId") String cohortId);

@Query("MATCH (c: Cohort {cohortId: $cohortId})-[:HAS_COHORT_COMPLETE]->(cc: CohortComplete) "
+ "RETURN cc ORDER BY cc.date DESC LIMIT 1")
CohortComplete findLatestCohortCompleteEventByCohortId(@Param("cohortId") String cohortId);
Expand All @@ -30,7 +27,7 @@ public interface CohortCompleteRepository extends Neo4jRepository<Cohort, Long>
List<Cohort> findCohortsBySamplePrimaryId(@Param("primaryId") String primaryId);

@Query("MATCH (s: Sample)-[:HAS_METADATA]->(sm: SampleMetadata {primaryId: $primaryId}) "
+ "MATCH (c: Cohort {cohortId: $cohortId}) MERGE (c)-[:HAS_COHORT_SAMPLE]->(s)")
+ "MATCH (c: Cohort {cohortId: $cohortId}) MERGE (c)-[hcs:HAS_COHORT_SAMPLE]->(s)")
void addCohortSampleRelationship(@Param("cohortId") String cohortId,
@Param("primaryId") String primaryId);
}
Loading

0 comments on commit 4a05c84

Please sign in to comment.