Skip to content

Commit

Permalink
Merge pull request #10039 from BasLee/custom_data_binning_endpoint
Browse files Browse the repository at this point in the history
Binning of custom data
  • Loading branch information
dippindots authored Mar 17, 2023
2 parents f375e62 + bae8b2b commit ca13827
Show file tree
Hide file tree
Showing 46 changed files with 1,979 additions and 687 deletions.
13 changes: 13 additions & 0 deletions model/src/main/java/org/cbioportal/model/Binnable.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.cbioportal.model;

/**
* Data that can be binned, clinical or custom
*/
public interface Binnable {
String getAttrId();
String getAttrValue();
String getSampleId();
String getPatientId();
String getStudyId();
Boolean isPatientAttribute();
}
9 changes: 8 additions & 1 deletion model/src/main/java/org/cbioportal/model/ClinicalData.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import javax.validation.constraints.NotNull;

public class ClinicalData extends UniqueKeyBase {
public class ClinicalData extends UniqueKeyBase implements Binnable {

private Integer internalId;
private String sampleId;
Expand Down Expand Up @@ -51,6 +51,13 @@ public String getAttrId() {
return attrId;
}

public Boolean isPatientAttribute() {
if(clinicalAttribute == null) {
return null;
}
return this.clinicalAttribute.getPatientAttribute();
}

public void setAttrId(String attrId) {
this.attrId = attrId;
}
Expand Down
27 changes: 27 additions & 0 deletions service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,29 @@
<groupId>org.mskcc.cbio</groupId>
<artifactId>permission-evaluator</artifactId>
</dependency>
<dependency>
<groupId>com.github.cbioportal</groupId>
<artifactId>session-service</artifactId>
<classifier>model</classifier>
<exclusions>
<exclusion>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
<exclusion>
<artifactId>spring-boot-starter-web</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
<exclusion>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
Expand Down Expand Up @@ -57,6 +80,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.cbioportal.service;

import org.cbioportal.model.ClinicalAttribute;

import java.util.List;

public interface AttributeByStudyService {
List<ClinicalAttribute> getClinicalAttributesByStudyIdsAndAttributeIds(List<String> studyIds, List<String> attributeIds);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

import java.util.List;

public interface ClinicalAttributeService {
public interface ClinicalAttributeService extends AttributeByStudyService {

List<ClinicalAttribute> getAllClinicalAttributes(String projection, Integer pageSize, Integer pageNumber,
String sortBy, String direction);
Expand All @@ -31,5 +31,4 @@ List<ClinicalAttribute> getAllClinicalAttributesInStudy(String studyId, String p

List<ClinicalAttributeCount> getClinicalAttributeCountsBySampleListId(String sampleListId);

List<ClinicalAttribute> getClinicalAttributesByStudyIdsAndAttributeIds(List<String> studyIds, List<String> attributeIds);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.cbioportal.service;

import org.cbioportal.service.util.CustomDataSession;

import java.util.List;
import java.util.Map;

public interface CustomDataService {
Map<String, CustomDataSession> getCustomDataSessions(List<String> attributes);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package org.cbioportal.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.cbioportal.service.CustomDataService;
import org.cbioportal.service.util.CustomDataSession;
import org.cbioportal.service.util.SessionServiceRequestHandler;
import org.cbioportal.session_service.domain.SessionType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

@Service
public class CustomDataServiceImpl implements CustomDataService {
@Autowired
private SessionServiceRequestHandler sessionServiceRequestHandler;

@Autowired
private ObjectMapper sessionServiceObjectMapper;

/**
* Retrieve CustomDataSession from session service for custom data attributes.
* @param customAttributeIds - attribute id/hash of custom data used as session service key.
* @return Map of custom data attribute id to the CustomDataSession
*/
@Override
public Map<String, CustomDataSession> getCustomDataSessions(List<String> customAttributeIds) {
Map<String, CompletableFuture<CustomDataSession>> postFuturesMap = customAttributeIds.stream()
.collect(Collectors.toMap(
attributeId -> attributeId,
attributeId -> CompletableFuture.supplyAsync(() -> {
try {
String customDataSessionJson = sessionServiceRequestHandler.getSessionDataJson(
SessionType.custom_data,
attributeId
);
return sessionServiceObjectMapper.readValue(customDataSessionJson, CustomDataSession.class);
} catch (Exception e) {
return null;
}
})
));

CompletableFuture.allOf(postFuturesMap.values().toArray(new CompletableFuture[postFuturesMap.size()])).join();

Map<String, CustomDataSession> customDataSessions = postFuturesMap.entrySet().stream()
.filter(entry -> entry.getValue().join() != null)
.collect(Collectors.toMap(
entry -> entry.getKey(),
entry -> entry.getValue().join()
));

return customDataSessions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.cbioportal.service.util;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.cbioportal.model.Binnable;

import java.io.Serializable;

@JsonIgnoreProperties(ignoreUnknown = true)
public class BinnableCustomDataValue implements Binnable, Serializable {

private final CustomDataValue customDataValue;
private final String attrId;
private final Boolean patientAttribute;

public BinnableCustomDataValue(
CustomDataValue customDataValue,
String attributeId,
Boolean patientAttribute
) {
this.customDataValue = customDataValue;
this.attrId = attributeId;
this.patientAttribute = patientAttribute;
}

public String getSampleId() {
return customDataValue.getSampleId();
}

public String getPatientId() {
return customDataValue.getPatientId();
}

public String getStudyId() {
return customDataValue.getStudyId();
}

public String getAttrId() {
return attrId;
}

public Boolean isPatientAttribute() {
return patientAttribute;
}

public String getAttrValue() {
return customDataValue.getValue();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,24 @@

@Component
public class ClinicalAttributeUtil {
public void extractCategorizedClinicalAttributes(List<ClinicalAttribute> clinicalAttributes,
List<String> sampleAttributeIds, List<String> patientAttributeIds,
List<String> conflictingPatientAttributeIds) {


public void extractCategorizedClinicalAttributes(
List<ClinicalAttribute> clinicalAttributes,
List<String> sampleAttributeIds,
List<String> patientAttributeIds,
List<String> conflictingPatientAttributeIds
) {

Set<String> sampleAttributeIdsSet = new HashSet<String>();
Set<String> patientAttributeIdsSet = new HashSet<String>();
Set<String> conflictingPatientAttributeIdsSet = new HashSet<String>();

Map<String, Map<Boolean, List<ClinicalAttribute>>> groupedAttributesByIdAndType = clinicalAttributes.stream()
.collect(Collectors.groupingBy(ClinicalAttribute::getAttrId,
Collectors.groupingBy(ClinicalAttribute::getPatientAttribute)));
Map<String, Map<Boolean, List<ClinicalAttribute>>> groupedAttributesByIdAndType = clinicalAttributes
.stream()
.collect(Collectors.groupingBy(
ClinicalAttribute::getAttrId,
Collectors.groupingBy(ClinicalAttribute::getPatientAttribute)
));

groupedAttributesByIdAndType.entrySet().forEach(entry -> {
if (entry.getValue().keySet().size() == 1) {
Expand All @@ -42,7 +49,7 @@ public void extractCategorizedClinicalAttributes(List<ClinicalAttribute> clinica
});
}
});

sampleAttributeIds.addAll(sampleAttributeIdsSet);
patientAttributeIds.addAll(patientAttributeIdsSet);
conflictingPatientAttributeIds.addAll(conflictingPatientAttributeIdsSet);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package org.cbioportal.web;
package org.cbioportal.service.util;

import java.io.Serializable;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import javax.validation.constraints.NotNull;

import org.cbioportal.web.parameter.CustomDataValue;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class CustomAttributeWithData implements Serializable{
public class CustomAttributeWithData implements Serializable {

private String owner = "anonymous";
private Set<String> origin = new HashSet<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
package org.cbioportal.web.parameter;
package org.cbioportal.service.util;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.cbioportal.session_service.domain.Session;
import org.cbioportal.session_service.domain.SessionType;
import org.cbioportal.web.CustomAttributeWithData;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.cbioportal.web.parameter;
package org.cbioportal.service.util;

import java.io.Serializable;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package org.cbioportal.service.util;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SessionServiceConfig {

@Bean
public ObjectMapper sessionServiceObjectMapper() {
return new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}

}
Original file line number Diff line number Diff line change
@@ -1,15 +1,10 @@
package org.cbioportal.web.util;
package org.cbioportal.service.util;

import java.nio.charset.Charset;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.cbioportal.session_service.domain.Session;
import org.cbioportal.session_service.domain.SessionType;
import org.cbioportal.web.parameter.CustomDataSession;
import org.cbioportal.web.parameter.CustomGeneList;
import org.cbioportal.web.parameter.PageSettings;
import org.cbioportal.web.parameter.VirtualStudy;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
Expand All @@ -18,9 +13,6 @@
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

@Component
public class SessionServiceRequestHandler {

Expand Down Expand Up @@ -56,32 +48,16 @@ public HttpHeaders getHttpHeaders() {
};
}

public Session getSession(SessionType type, String id) throws Exception {
public String getSessionDataJson(SessionType type, String id) throws Exception {

RestTemplate restTemplate = new RestTemplate();

// add basic authentication in header
HttpEntity<String> headers = new HttpEntity<String>(getHttpHeaders());
HttpEntity<String> headers = new HttpEntity<>(getHttpHeaders());
ResponseEntity<String> responseEntity = restTemplate.exchange(sessionServiceURL + type + "/" + id,
HttpMethod.GET, headers, String.class);

ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Session session;

if (type.equals(SessionType.virtual_study) || type.equals(SessionType.group)) {
session = mapper.readValue(responseEntity.getBody(), VirtualStudy.class);
} else if (type.equals(SessionType.settings)) {
session = mapper.readValue(responseEntity.getBody(), PageSettings.class);
} else if (type.equals(SessionType.custom_data)) {
session = mapper.readValue(responseEntity.getBody(), CustomDataSession.class);
} else if (type.equals(SessionType.custom_gene_list)) {
session = mapper.readValue(responseEntity.getBody(), CustomGeneList.class);
} else {
session = mapper.readValue(responseEntity.getBody(), Session.class);
}

return session;
return responseEntity.getBody();
}

}
Loading

0 comments on commit ca13827

Please sign in to comment.