diff --git a/mica-core/src/main/java/org/obiba/mica/core/domain/BaseStudyTable.java b/mica-core/src/main/java/org/obiba/mica/core/domain/BaseStudyTable.java index b85fb007f5..15ebe196d1 100644 --- a/mica-core/src/main/java/org/obiba/mica/core/domain/BaseStudyTable.java +++ b/mica-core/src/main/java/org/obiba/mica/core/domain/BaseStudyTable.java @@ -13,9 +13,7 @@ import com.google.common.base.MoreObjects; import com.google.common.base.Strings; -import java.io.Serializable; - -public class BaseStudyTable extends OpalTable { +public class BaseStudyTable { protected String studyId; @@ -23,6 +21,22 @@ public class BaseStudyTable extends OpalTable { protected int populationWeight; + private LocalizedString name; + + private LocalizedString description; + + private LocalizedString additionalInformation; + + private int weight; + + private String sourceURN; + + // legacy + private String project; + + // legacy + private String table; + public String getStudyId() { return studyId; } @@ -72,13 +86,66 @@ public void setPopulationWeight(int populationWeight) { @Override public String toString() { - return MoreObjects.toStringHelper(this).add("project", getProject()).add("table", getTable()) + return MoreObjects.toStringHelper(this).add("source", getSourceURN()) .add("studyId", getStudyId()).add("populationId", getPopulationId()) .toString(); } - @Override - protected String getEntityId() { - return studyId; + public void setName(LocalizedString name) { + this.name = name; + } + + public LocalizedString getName() { + return name; + } + + public void setDescription(LocalizedString description) { + this.description = description; + } + + public LocalizedString getDescription() { + return description; + } + + public LocalizedString getAdditionalInformation() { + return additionalInformation; + } + + public void setAdditionalInformation(LocalizedString additionalInformation) { + this.additionalInformation = additionalInformation; + } + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public boolean isFor(String studyId, String sourceURN) { + return this.studyId.equals(studyId) && getSourceURN().equals(sourceURN); + } + + public void setSourceURN(String sourceURN) { + this.sourceURN = sourceURN; + } + + public String getSourceURN() { + // legacy + if (Strings.isNullOrEmpty(sourceURN)) { + this.sourceURN = OpalTableSource.newSource(project, table).getURN(); + } + return sourceURN; + } + + @Deprecated + public void setProject(String project) { + this.project = project; + } + + @Deprecated + public void setTable(String table) { + this.table = table; } } diff --git a/mica-core/src/main/java/org/obiba/mica/core/domain/OpalTable.java b/mica-core/src/main/java/org/obiba/mica/core/domain/OpalTable.java deleted file mode 100644 index 9b17df54ce..0000000000 --- a/mica-core/src/main/java/org/obiba/mica/core/domain/OpalTable.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2018 OBiBa. All rights reserved. - * - * This program and the accompanying materials - * are made available under the terms of the GNU Public License v3.0. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.obiba.mica.core.domain; - -import javax.validation.constraints.NotNull; - -/** - * Represents a table in opal. - */ -public abstract class OpalTable { - - @NotNull - private String project; - - @NotNull - private String table; - - private LocalizedString name; - - private LocalizedString description; - - private LocalizedString additionalInformation; - - private int weight; - - public String getProject() { - return project; - } - - public void setProject(String project) { - this.project = project; - } - - public String getTable() { - return table; - } - - public void setTable(String table) { - this.table = table; - } - - public void setName(LocalizedString name) { - this.name = name; - } - - public LocalizedString getName() { - return name; - } - - public void setDescription(LocalizedString description) { - this.description = description; - } - - public LocalizedString getDescription() { - return description; - } - - public LocalizedString getAdditionalInformation() { - return additionalInformation; - } - - public void setAdditionalInformation(LocalizedString additionalInformation) { - this.additionalInformation = additionalInformation; - } - - public int getWeight() { - return weight; - } - - public void setWeight(int weight) { - this.weight = weight; - } - - public boolean isFor(String entityId, String project, String table) { - return getEntityId().equals(entityId) && getProject().equals(project) && getTable().equals(table); - } - - protected abstract String getEntityId(); - -} diff --git a/mica-core/src/main/java/org/obiba/mica/core/domain/OpalTableSource.java b/mica-core/src/main/java/org/obiba/mica/core/domain/OpalTableSource.java new file mode 100644 index 0000000000..fe19508893 --- /dev/null +++ b/mica-core/src/main/java/org/obiba/mica/core/domain/OpalTableSource.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2022 OBiBa. All rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.obiba.mica.core.domain; + +import com.google.common.base.Strings; +import org.obiba.magma.ValueTable; +import org.obiba.mica.micaConfig.service.OpalService; +import org.obiba.mica.spi.dataset.StudyTableSource; +import org.obiba.opal.rest.client.magma.RestDatasource; +import org.obiba.opal.rest.client.magma.RestValueTable; +import org.obiba.opal.web.model.Math; +import org.obiba.opal.web.model.Search; + +import javax.validation.constraints.NotNull; + +/** + * Connector to an Opal server, to retrieve value table and summary statistics. + */ +public class OpalTableSource implements StudyTableSource { + + private OpalService opalService; + + private String opalUrl; + + @NotNull + private String project; + + @NotNull + private String table; + + public String getProject() { + return project; + } + + public void setProject(String project) { + this.project = project; + } + + public String getTable() { + return table; + } + + public void setTable(String table) { + this.table = table; + } + + @Override + public ValueTable getValueTable() { + return getDatasource().getValueTable(table); + } + + @Override + public Search.QueryResultDto getFacets(Search.QueryTermsDto query) { + return getRestValueTable().getFacets(query); + } + + @Override + public Math.SummaryStatisticsDto getVariableSummary(String variableName) { + return ((RestValueTable.RestVariableValueSource)getRestValueTable().getVariableValueSource(variableName)).getSummary(); + } + + @Override + public String getURN() { + return String.format("urn:opal:%s.%s", project, table); + } + + public static boolean isFor(String sourceURN) { + return !Strings.isNullOrEmpty(sourceURN) && sourceURN.startsWith("urn:opal:"); + } + + public static OpalTableSource newSource(String project, String table) { + OpalTableSource source = new OpalTableSource(); + source.setProject(project); + source.setTable(table); + return source; + } + + public static OpalTableSource fromURN(String sourceURN) { + if (Strings.isNullOrEmpty(sourceURN) || !sourceURN.startsWith("urn:opal:")) + throw new IllegalArgumentException("Not a valid Opal table source URN: " + sourceURN); + + String fullName = toTableName(sourceURN); + int sep = fullName.indexOf("."); + String project = fullName.substring(0, sep); + String table = fullName.substring(sep + 1); + return OpalTableSource.newSource(project, table); + } + + public static String toTableName(String sourceURN) { + return sourceURN.replace("urn:opal:", ""); + } + + public void init(OpalService opalService, String opalUrl) { + this.opalService = opalService; + this.opalUrl = opalUrl; + } + + private RestDatasource getDatasource() { + return opalService.getDatasource(opalUrl, project); + } + + private RestValueTable getRestValueTable() { + return (RestValueTable) getDatasource().getValueTable(table); + } +} diff --git a/mica-core/src/main/java/org/obiba/mica/core/domain/StudyTable.java b/mica-core/src/main/java/org/obiba/mica/core/domain/StudyTable.java index 14ec461824..e3036a78dc 100644 --- a/mica-core/src/main/java/org/obiba/mica/core/domain/StudyTable.java +++ b/mica-core/src/main/java/org/obiba/mica/core/domain/StudyTable.java @@ -10,10 +10,10 @@ package org.obiba.mica.core.domain; -import java.io.Serializable; - import com.google.common.base.MoreObjects; +import java.io.Serializable; + /** * Represents a opal table that is associated to a {@link org.obiba.mica.study.domain.Study} * {@link org.obiba.mica.study.domain.Population} {@link org.obiba.mica.study.domain.DataCollectionEvent}. @@ -63,7 +63,7 @@ public boolean appliesTo(String studyId, String populationId, String dataCollect @Override public String toString() { - return MoreObjects.toStringHelper(this).add("project", getProject()).add("table", getTable()) + return MoreObjects.toStringHelper(this).add("source", getSourceURN()) .add("dceId", getDataCollectionEventUId()).toString(); } diff --git a/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java b/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java new file mode 100644 index 0000000000..7ad425a408 --- /dev/null +++ b/mica-core/src/main/java/org/obiba/mica/core/service/StudyTableSourceServiceRegistry.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 OBiBa. All rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.obiba.mica.core.service; + +import org.obiba.mica.core.domain.BaseStudyTable; +import org.obiba.mica.core.domain.OpalTableSource; +import org.obiba.mica.micaConfig.service.OpalService; +import org.obiba.mica.micaConfig.service.PluginsService; +import org.obiba.mica.spi.dataset.StudyTableSource; +import org.obiba.mica.spi.dataset.StudyTableSourceService; +import org.obiba.mica.study.domain.BaseStudy; +import org.springframework.stereotype.Service; + +import javax.inject.Inject; +import java.util.NoSuchElementException; +import java.util.Optional; + +@Service +public class StudyTableSourceServiceRegistry { + + @Inject + private PluginsService pluginsService; + + @Inject + private OpalService opalService; + + public StudyTableSource makeSource(BaseStudy study, String sourceURN) { + if (OpalTableSource.isFor(sourceURN)) { + OpalTableSource source = OpalTableSource.fromURN(sourceURN); + source.init(opalService, study.getOpal()); + return source; + } + Optional serviceOptional = pluginsService.getStudyTableSourceServices().stream() + .filter(service -> service.isFor(sourceURN)).findFirst(); + if (serviceOptional.isPresent()) { + // TODO add a context to the study table source + return serviceOptional.get().makeSource(sourceURN); + } + throw new NoSuchElementException("Missing study-table-source plugin to handle source: " + sourceURN); + } + +} diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/domain/Dataset.java b/mica-core/src/main/java/org/obiba/mica/dataset/domain/Dataset.java index b1aabd45fe..6e32ab5fb1 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/domain/Dataset.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/domain/Dataset.java @@ -28,7 +28,7 @@ import java.util.Map; /** - * Proxy to Opal tables. + * Proxy to value tables. */ public abstract class Dataset extends AbstractModelAware implements AttributeAware, Indexable { diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/domain/DatasetVariable.java b/mica-core/src/main/java/org/obiba/mica/dataset/domain/DatasetVariable.java index c4884ebd59..6618a77d98 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/domain/DatasetVariable.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/domain/DatasetVariable.java @@ -89,9 +89,7 @@ public enum OpalTableType { private int index; - private String project; - - private String table; + private String sourceURN; private OpalTableType opalTableType; @@ -132,25 +130,17 @@ public DatasetVariable(HarmonizationDataset dataset, Variable variable) { setContainerId(table.getStudyId()); } - public DatasetVariable(HarmonizationDataset dataset, Variable variable, OpalTable opalTable) { + public DatasetVariable(HarmonizationDataset dataset, Variable variable, BaseStudyTable studyTable) { this(dataset, Type.Harmonized, variable); - if (opalTable instanceof BaseStudyTable) { - studyId = ((BaseStudyTable)opalTable).getStudyId(); - setContainerId(studyId); - opalTableType = opalTable instanceof StudyTable ? OpalTableType.Study : OpalTableType.Harmonization; + studyId = studyTable.getStudyId(); + setContainerId(studyId); + opalTableType = studyTable instanceof StudyTable ? OpalTableType.Study : OpalTableType.Harmonization; - if (opalTable instanceof HarmonizationStudyTable) { - populationId = ((HarmonizationStudyTable) opalTable).getPopulationUId(); - dceId = ((HarmonizationStudyTable) opalTable).getDataCollectionEventUId(); - } else { - populationId = ((BaseStudyTable) opalTable).getPopulationUId(); - dceId = ((BaseStudyTable) opalTable).getDataCollectionEventUId(); - } - } + populationId = studyTable.getPopulationUId(); + dceId = studyTable.getDataCollectionEventUId(); - project = opalTable.getProject(); - table = opalTable.getTable(); + sourceURN = studyTable.getSourceURN(); } private DatasetVariable(Dataset dataset, Type type, Variable variable) { @@ -187,7 +177,7 @@ public String getId() { if (Type.Harmonized == variableType) { String entityId = studyId; String tableType = opalTableType == OpalTableType.Study ? OPAL_STUDY_TABLE_PREFIX : OPAL_HARMONIZATION_TABLE_PREFIX; - id = id + ID_SEPARATOR + tableType + ID_SEPARATOR + entityId + ID_SEPARATOR + project + ID_SEPARATOR + table; + id = id + ID_SEPARATOR + tableType + ID_SEPARATOR + entityId + ID_SEPARATOR + sourceURN; } return id; @@ -202,8 +192,7 @@ public void setId(String id) { opalTableType = Strings.isNullOrEmpty(tableType) ? null : OpalTableType.valueOf(tableType); if (resolver.hasStudyId()) studyId = resolver.getStudyId(); - if (resolver.hasProject()) project = resolver.getProject(); - if (resolver.hasTable()) table = resolver.getTable(); + if (resolver.hasSourceURN()) sourceURN = resolver.getSourceURN(); } public String getDatasetId() { @@ -327,12 +316,8 @@ public int getIndex() { return index; } - public String getProject() { - return project; - } - - public String getTable() { - return table; + public String getSourceURN() { + return sourceURN; } public OpalTableType getOpalTableType() { @@ -483,7 +468,7 @@ private static String encodeDecode(Map map, Pattern pattern, Str public static class IdResolver { - private final String id; + private String id; private final Type type; @@ -493,12 +478,10 @@ public static class IdResolver { private final String studyId; - private final String project; - - private final String table; - private final String tableType; + private final String sourceURN; + public static IdResolver from(String id) { return new IdResolver(id); } @@ -507,31 +490,33 @@ public static IdResolver from(String datasetId, String variableName, Type variab return from(encode(datasetId, variableName, variableType, null)); } + public static String encode(String datasetId, String variableName, Type variableType) { + return encode(datasetId, variableName, variableType, null, null, null); + } + public static String encode(String datasetId, String variableName, Type variableType, String studyId, - String project, String table, String tableType) { + String sourceURN, String tableType) { String id = datasetId + ID_SEPARATOR + IdEncoderDecoder.encode(variableName) + ID_SEPARATOR + variableType; String entityId; if (Type.Harmonized == variableType) { entityId = studyId; - id = id + ID_SEPARATOR + tableType + ID_SEPARATOR + entityId + ID_SEPARATOR + project + ID_SEPARATOR + table; + id = id + ID_SEPARATOR + tableType + ID_SEPARATOR + entityId + ID_SEPARATOR + sourceURN; } return id; } - public static String encode(String datasetId, String variableName, Type variableType, OpalTable opalTable) { - String tableType = opalTable instanceof StudyTable ? OPAL_STUDY_TABLE_PREFIX : OPAL_HARMONIZATION_TABLE_PREFIX; - BaseStudyTable studyTable = (BaseStudyTable)opalTable; + public static String encode(String datasetId, String variableName, Type variableType, BaseStudyTable studyTable) { + String tableType = studyTable instanceof StudyTable ? OPAL_STUDY_TABLE_PREFIX : OPAL_HARMONIZATION_TABLE_PREFIX; return studyTable == null - ? encode(datasetId, variableName, variableType, null, null, null, null) + ? encode(datasetId, variableName, variableType) : encode(datasetId, variableName, variableType, studyTable.getStudyId(), - opalTable.getProject(), - opalTable.getTable(), + studyTable.getSourceURN(), tableType); } @@ -540,7 +525,9 @@ private IdResolver(String id) { this.id = IdEncoderDecoder.encode(id); boolean encoded = !this.id.equals(id); - String[] tokens = id.split(ID_SEPARATOR); + String[] parts = id.split(":urn:"); + + String[] tokens = parts[0].split(ID_SEPARATOR); if (tokens.length < 3) throw new IllegalArgumentException("Not a valid dataset variable ID: " + id); datasetId = tokens[0]; @@ -550,8 +537,16 @@ private IdResolver(String id) { tableType = tokens.length > 3 ? tokens[3] : null; studyId = tokens.length > 4 ? tokens[4] : null; - project = tokens.length > 5 ? tokens[5] : null; - table = tokens.length > 6 ? tokens[6] : null; + if (parts.length>1) { + sourceURN = "urn:" + parts[1]; + } else if (tokens.length > 6) { + // legacy + sourceURN = String.format("urn:opal:%s.%s", tokens[5], tokens[6]); + // need to rewrite id + this.id = IdEncoderDecoder.encode(encode(datasetId, name, type,studyId, sourceURN, tableType)); + } else { + sourceURN = null; + } } public String getId() { @@ -578,26 +573,18 @@ public boolean hasStudyId() { return !Strings.isNullOrEmpty(studyId); } - public String getProject() { - return project; - } - - public boolean hasProject() { - return !Strings.isNullOrEmpty(project); - } - - public String getTable() { - return table; + public boolean hasSourceURN() { + return !Strings.isNullOrEmpty(sourceURN); } - public boolean hasTable() { - return !Strings.isNullOrEmpty(table); + public String getSourceURN() { + return sourceURN; } @Override public String toString() { String tableType = type == Type.Dataschema ? OPAL_HARMONIZATION_TABLE_PREFIX : OPAL_STUDY_TABLE_PREFIX; - return "[" + datasetId + "," + name + "," + type + ", " + tableType + ", " + studyId + ", " + project + ", " + table + "]"; + return "[" + datasetId + "," + name + "," + type + ", " + tableType + ", " + studyId + ", " + sourceURN + "]"; } public String getTableType() { diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/domain/HarmonizationDataset.java b/mica-core/src/main/java/org/obiba/mica/dataset/domain/HarmonizationDataset.java index 124cc5b0c2..6ee28b065f 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/domain/HarmonizationDataset.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/domain/HarmonizationDataset.java @@ -10,21 +10,18 @@ package org.obiba.mica.dataset.domain; -import java.io.Serializable; -import java.util.*; -import java.util.stream.Collectors; - -import javax.validation.constraints.NotNull; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; - import org.obiba.mica.core.domain.BaseStudyTable; import org.obiba.mica.core.domain.HarmonizationStudyTable; -import org.obiba.mica.core.domain.OpalTable; import org.obiba.mica.core.domain.StudyTable; +import javax.validation.constraints.NotNull; +import java.io.Serializable; +import java.util.*; +import java.util.stream.Collectors; + /** * Dataset that relies on Study Opal servers summaries. */ @@ -106,6 +103,6 @@ public Map parts() { @JsonIgnore public List getBaseStudyTables() { return Lists.newArrayList(Iterables.concat(getStudyTables(), getHarmonizationTables())).stream()// - .sorted(Comparator.comparingInt(OpalTable::getWeight)).collect(Collectors.toList()); + .sorted(Comparator.comparingInt(BaseStudyTable::getWeight)).collect(Collectors.toList()); } } diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/service/CollectedDatasetService.java b/mica-core/src/main/java/org/obiba/mica/dataset/service/CollectedDatasetService.java index 29511f5a61..28b01f76b2 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/service/CollectedDatasetService.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/service/CollectedDatasetService.java @@ -15,9 +15,9 @@ import com.google.common.collect.Sets; import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; -import org.joda.time.DateTime; import org.obiba.magma.NoSuchValueTableException; import org.obiba.magma.NoSuchVariableException; +import org.obiba.magma.ValueTable; import org.obiba.mica.NoSuchEntityException; import org.obiba.mica.core.domain.AbstractGitPersistable; import org.obiba.mica.core.domain.PublishCascadingScope; @@ -50,7 +50,6 @@ import org.obiba.mica.study.service.IndividualStudyService; import org.obiba.mica.study.service.PublishedStudyService; import org.obiba.mica.study.service.StudyService; -import org.obiba.opal.rest.client.magma.RestValueTable; import org.obiba.opal.web.model.Search; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,6 +66,7 @@ import javax.inject.Inject; import javax.validation.Valid; import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; import java.util.*; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -74,8 +74,6 @@ import static java.util.stream.Collectors.toList; -import java.time.LocalDateTime; - @Service @Validated public class CollectedDatasetService extends DatasetService { @@ -410,10 +408,8 @@ public List processVariablesForStudyDataset(StudyDataset datase } @Override - @NotNull - protected RestValueTable getTable(@NotNull StudyDataset dataset) throws NoSuchValueTableException { - StudyTable studyTable = dataset.getSafeStudyTable(); - return execute(studyTable, datasource -> (RestValueTable) datasource.getValueTable(studyTable.getTable())); + protected ValueTable getValueTable(@NotNull StudyDataset dataset) throws NoSuchValueTableException { + return getStudyTableSource(dataset.getSafeStudyTable()).getValueTable(); } @Override @@ -428,25 +424,19 @@ public Iterable getDatasetVariables(StudyDataset dataset) { @Override public DatasetVariable getDatasetVariable(StudyDataset dataset, String variableName) throws NoSuchValueTableException, NoSuchVariableException { - return new DatasetVariable(dataset, getVariableValueSource(dataset, variableName).getVariable()); + return new DatasetVariable(dataset, getValueTable(dataset).getVariable(variableName)); } @Cacheable(value = "dataset-variables", cacheResolver = "datasetVariablesCacheResolver", key = "#variableName") public SummaryStatisticsWrapper getVariableSummary(@NotNull StudyDataset dataset, String variableName) throws NoSuchValueTableException, NoSuchVariableException { log.info("Caching variable summary {} {}", dataset.getId(), variableName); - return new SummaryStatisticsWrapper(getVariableValueSource(dataset, variableName).getSummary()); - } - - public Search.QueryResultDto getVariableFacet(@NotNull StudyDataset dataset, String variableName) - throws NoSuchValueTableException, NoSuchVariableException { - log.debug("Getting variable facet {} {}", dataset.getId(), variableName); - return getVariableValueSource(dataset, variableName).getFacet(); + return new SummaryStatisticsWrapper(getStudyTableSource(dataset.getSafeStudyTable()).getVariableSummary(variableName)); } public Search.QueryResultDto getFacets(@NotNull StudyDataset dataset, Search.QueryTermsDto query) throws NoSuchValueTableException, NoSuchVariableException { - return getTable(dataset).getFacets(query); + return getStudyTableSource(dataset.getSafeStudyTable()).getFacets(query); } public Search.QueryResultDto getContingencyTable(@NotNull StudyDataset dataset, DatasetVariable variable, @@ -515,18 +505,6 @@ protected EventBus getEventBus() { // Private methods // - /** - * Build or reuse the {@link org.obiba.opal.rest.client.magma.RestDatasource} and execute the callback with it. - * - * @param studyTable - * @param callback - * @param - * @return - */ - private T execute(StudyTable studyTable, DatasourceCallback callback) { - return execute(getDatasource(studyTable), callback); - } - private void saveInternal(StudyDataset dataset, String comment) { if (!Strings.isNullOrEmpty(dataset.getId()) && micaConfigService.getConfig().isCommentsRequiredOnDocumentSave() && Strings.isNullOrEmpty(comment)) { throw new MissingCommentException("Due to the server configuration, comments are required when saving this document."); diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/service/DatasetService.java b/mica-core/src/main/java/org/obiba/mica/dataset/service/DatasetService.java index 52543c8e40..f061a9dcfc 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/service/DatasetService.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/service/DatasetService.java @@ -10,42 +10,34 @@ package org.obiba.mica.dataset.service; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.Serializable; -import java.util.List; - -import javax.annotation.Nullable; -import javax.validation.constraints.NotNull; - +import com.google.common.base.Strings; +import com.google.common.eventbus.EventBus; +import com.google.protobuf.GeneratedMessage; import net.sf.ehcache.pool.sizeof.annotations.IgnoreSizeOf; - -import org.obiba.magma.MagmaRuntimeException; -import org.obiba.magma.NoSuchValueTableException; -import org.obiba.magma.NoSuchVariableException; -import org.obiba.magma.Variable; +import org.obiba.magma.*; +import org.obiba.mica.core.domain.BaseStudyTable; import org.obiba.mica.core.domain.EntityState; -import org.obiba.mica.core.domain.HarmonizationStudyTable; import org.obiba.mica.core.domain.LocalizedString; -import org.obiba.mica.core.domain.OpalTable; -import org.obiba.mica.core.domain.StudyTable; import org.obiba.mica.core.service.AbstractGitPersistableService; +import org.obiba.mica.core.service.StudyTableSourceServiceRegistry; import org.obiba.mica.dataset.NoSuchDatasetException; import org.obiba.mica.dataset.domain.Dataset; import org.obiba.mica.dataset.domain.DatasetVariable; import org.obiba.mica.micaConfig.service.OpalService; import org.obiba.mica.network.service.NetworkService; +import org.obiba.mica.spi.dataset.StudyTableSource; import org.obiba.mica.study.service.StudyService; -import org.obiba.opal.rest.client.magma.RestDatasource; -import org.obiba.opal.rest.client.magma.RestValueTable; -import org.obiba.opal.web.model.Magma; import org.obiba.opal.web.model.Math; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.google.common.base.Strings; -import com.google.common.eventbus.EventBus; -import com.google.protobuf.GeneratedMessage; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.validation.constraints.NotNull; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.Serializable; +import java.util.List; /** * {@link org.obiba.mica.dataset.domain.Dataset} management service. @@ -55,6 +47,9 @@ public abstract class DatasetService private static final Logger log = LoggerFactory.getLogger(DatasetService.class); + @Inject + private StudyTableSourceServiceRegistry studyTableSourceServiceRegistry; + /** * Get all {@link org.obiba.mica.dataset.domain.DatasetVariable}s from a {@link org.obiba.mica.dataset.domain.Dataset}. * @@ -73,18 +68,7 @@ public abstract class DatasetService public abstract DatasetVariable getDatasetVariable(T dataset, String name) throws NoSuchValueTableException, NoSuchVariableException; - /** - * Get the {@link org.obiba.opal.web.model.Magma.TableDto} of the {@link org.obiba.mica.dataset.domain.Dataset} identified by its id. - * - * @param dataset - * @return - */ - @NotNull - protected abstract RestValueTable getTable(@NotNull T dataset) throws NoSuchValueTableException; - - protected RestValueTable getTable(@NotNull String project, @NotNull String table) throws NoSuchValueTableException { - return execute(getDatasource(project), datasource -> (RestValueTable) datasource.getValueTable(table)); - } + protected abstract ValueTable getValueTable(@NotNull T dataset) throws NoSuchValueTableException; protected abstract StudyService getStudyService(); @@ -150,71 +134,11 @@ private void ensureAcronym(@NotNull T dataset) { */ protected Iterable getVariables(@NotNull T dataset) throws NoSuchDatasetException, NoSuchValueTableException { - return getTable(dataset).getVariables(); - } - - /** - * Get the {@link org.obiba.magma.VariableValueSource} (proxy to the {@link org.obiba.magma.Variable} of - * the {@link org.obiba.mica.dataset.domain.Dataset} identified by its id. - * - * @param dataset - * @param variableName - * @return - * @throws NoSuchDatasetException - */ - protected RestValueTable.RestVariableValueSource getVariableValueSource(@NotNull T dataset, String variableName) - throws NoSuchValueTableException, NoSuchVariableException { - return (RestValueTable.RestVariableValueSource) getTable(dataset).getVariableValueSource(variableName); - } - - protected RestValueTable.RestVariableValueSource getVariableValueSource(String project, String table, String variableName) - throws NoSuchValueTableException, NoSuchVariableException { - return (RestValueTable.RestVariableValueSource) getTable(project, table).getVariableValueSource(variableName); - } - - public Magma.TableDto getTableDto(@NotNull T dataset) { - return getTable(dataset).getTableDto(); - } - - public Magma.VariableDto getVariable(@NotNull T dataset, String variableName) { - return getVariableValueSource(dataset, variableName).getVariableDto(); - } - - /** - * Callback that can be used to make any operations on a {@link org.obiba.opal.rest.client.magma.RestDatasource} - * - * @param - */ - public interface DatasourceCallback { - R doWithDatasource(RestDatasource datasource); - } - - /** - * Execute the callback on the given datasource. - * - * @param datasource - * @param callback - * @param - * @return - */ - protected R execute(RestDatasource datasource, DatasourceCallback callback) { - return callback.doWithDatasource(datasource); - } - - protected RestDatasource getDatasource(@NotNull OpalTable opalTable) { - String opalUrl = null; - - if (opalTable instanceof StudyTable) { - opalUrl = getStudyService().findDraft(((StudyTable) opalTable).getStudyId()).getOpal(); - } else if (opalTable instanceof HarmonizationStudyTable) { - opalUrl = getStudyService().findDraft(((HarmonizationStudyTable) opalTable).getStudyId()).getOpal(); - } - - return getOpalService().getDatasource(opalUrl, opalTable.getProject()); + return getValueTable(dataset).getVariables(); } - protected RestDatasource getDatasource(@NotNull String project) { - return getOpalService().getDatasource(project); + protected StudyTableSource getStudyTableSource(@NotNull BaseStudyTable studyTable) { + return studyTableSourceServiceRegistry.makeSource(getStudyService().findDraft(studyTable.getStudyId()), studyTable.getSourceURN()); } protected Iterable wrappedGetDatasetVariables(T dataset) { diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/service/HarmonizedDatasetService.java b/mica-core/src/main/java/org/obiba/mica/dataset/service/HarmonizedDatasetService.java index 7eeeee0226..d104912ff7 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/service/HarmonizedDatasetService.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/service/HarmonizedDatasetService.java @@ -10,33 +10,14 @@ package org.obiba.mica.dataset.service; -import static java.util.stream.Collectors.toList; - -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.StreamSupport; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.validation.Valid; -import javax.validation.constraints.NotNull; - -import org.obiba.magma.MagmaRuntimeException; -import org.obiba.magma.NoSuchValueTableException; -import org.obiba.magma.NoSuchVariableException; -import org.obiba.magma.ValueTable; -import org.obiba.magma.Variable; +import com.google.common.base.Strings; +import com.google.common.base.Throwables; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.google.common.eventbus.EventBus; +import org.obiba.magma.*; import org.obiba.mica.NoSuchEntityException; import org.obiba.mica.core.domain.BaseStudyTable; -import org.obiba.mica.core.domain.OpalTable; import org.obiba.mica.core.domain.PublishCascadingScope; import org.obiba.mica.core.repository.EntityStateRepository; import org.obiba.mica.core.service.MissingCommentException; @@ -62,7 +43,6 @@ import org.obiba.mica.study.service.HarmonizationStudyService; import org.obiba.mica.study.service.PublishedStudyService; import org.obiba.mica.study.service.StudyService; -import org.obiba.opal.rest.client.magma.RestValueTable; import org.obiba.opal.web.model.Search; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -76,11 +56,19 @@ import org.springframework.util.Assert; import org.springframework.validation.annotation.Validated; -import com.google.common.base.Strings; -import com.google.common.base.Throwables; -import com.google.common.collect.Lists; -import com.google.common.collect.Sets; -import com.google.common.eventbus.EventBus; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.validation.Valid; +import javax.validation.constraints.NotNull; +import java.time.LocalDateTime; +import java.util.*; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + +import static java.util.stream.Collectors.toList; @Service @Validated @@ -313,8 +301,7 @@ public void publish(@NotNull String id, boolean published, PublishCascadingScope private void checkIsPublishable(HarmonizationDataset dataset) { if (dataset == null || dataset.getHarmonizationTable() == null - || dataset.getHarmonizationTable().getProject() == null - || dataset.getHarmonizationTable().getTable() == null + || dataset.getHarmonizationTable().getSourceURN() == null || dataset.getHarmonizationTable().getStudyId() == null) { throw new IllegalArgumentException("dataset.harmonization.missing-attributes"); } @@ -357,10 +344,8 @@ public void delete(String id) { } @Override - @NotNull - protected RestValueTable getTable(@NotNull HarmonizationDataset dataset) throws NoSuchValueTableException { - return execute(dataset.getSafeHarmonizationTable().getProject(), - datasource -> (RestValueTable) datasource.getValueTable(dataset.getSafeHarmonizationTable().getTable())); + protected ValueTable getValueTable(@NotNull HarmonizationDataset dataset) throws NoSuchValueTableException { + return getStudyTableSource(dataset.getSafeHarmonizationTable()).getValueTable(); } @Override @@ -372,52 +357,48 @@ public Iterable getDatasetVariables(HarmonizationDataset datase @Override public DatasetVariable getDatasetVariable(HarmonizationDataset dataset, String variableName) throws NoSuchValueTableException, NoSuchVariableException { - return new DatasetVariable(dataset, getVariableValueSource(dataset, variableName).getVariable()); + return new DatasetVariable(dataset, getStudyTableSource(dataset.getSafeHarmonizationTable()).getValueTable().getVariable(variableName)); } - public Iterable getDatasetVariables(HarmonizationDataset dataset, OpalTable opalTable) + public Iterable getDatasetVariables(HarmonizationDataset dataset, BaseStudyTable studyTable) throws NoSuchStudyException, NoSuchValueTableException { - return StreamSupport.stream(getVariables(opalTable).spliterator(), false) - .map(input -> new DatasetVariable(dataset, input, opalTable)).collect(toList()); + return StreamSupport.stream(getVariables(studyTable).spliterator(), false) + .map(input -> new DatasetVariable(dataset, input, studyTable)).collect(toList()); } - public DatasetVariable getDatasetVariable(HarmonizationDataset dataset, String variableName, OpalTable opalTable) + public DatasetVariable getDatasetVariable(HarmonizationDataset dataset, String variableName, BaseStudyTable studyTable) throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { - return new DatasetVariable(dataset, getTable(opalTable).getVariableValueSource(variableName).getVariable()); + return new DatasetVariable(dataset, getStudyTableSource(studyTable).getValueTable().getVariable(variableName)); } public DatasetVariable getDatasetVariable(HarmonizationDataset dataset, String variableName, String studyId, - String project, String table) throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { + String sourceURN) throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { return new DatasetVariable(dataset, - getTable(dataset, studyId, project, table).getVariableValueSource(variableName).getVariable()); + getTable(dataset, studyId, sourceURN).getVariableValueSource(variableName).getVariable()); } @Cacheable(value = "dataset-variables", cacheResolver = "datasetVariablesCacheResolver", - key = "#variableName + ':' + #studyId + ':' + #project + ':' + #table") - public SummaryStatisticsWrapper getVariableSummary(@NotNull HarmonizationDataset dataset, String variableName, - String studyId, String project, String table) + key = "#variableName + ':' + #studyId + ':' + #sourceURN") + public SummaryStatisticsWrapper getVariableSummary(@NotNull HarmonizationDataset dataset, String variableName, String studyId, String sourceURN) throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { - log.info("Caching variable summary {} {} {} {} {}", dataset.getId(), variableName, studyId, project, table); - - return new SummaryStatisticsWrapper( - getVariableValueSource(dataset, variableName, studyId, project, table).getSummary()); - } + log.info("Caching variable summary {} {} {} {} {}", dataset.getId(), variableName, studyId, sourceURN); + for(BaseStudyTable baseTable : dataset.getBaseStudyTables()) { + if(baseTable.isFor(studyId, sourceURN)) { + return new SummaryStatisticsWrapper(getStudyTableSource(baseTable).getVariableSummary(variableName)); + } + } - public Search.QueryResultDto getVariableFacet(@NotNull HarmonizationDataset dataset, String variableName, - String studyId, String project, String table) - throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { - log.debug("Getting variable facet {} {}", dataset.getId(), variableName); - return getVariableValueSource(dataset, variableName, studyId, project, table).getFacet(); + throw NoSuchStudyException.withId(studyId); } - public Search.QueryResultDto getFacets(Search.QueryTermsDto query, OpalTable opalTable) + public Search.QueryResultDto getFacets(Search.QueryTermsDto query, BaseStudyTable studyTable) throws NoSuchStudyException, NoSuchValueTableException { - return getTable(opalTable).getFacets(query); + return getStudyTableSource(studyTable).getFacets(query); } - public Search.QueryResultDto getContingencyTable(@NotNull OpalTable opalTable, DatasetVariable variable, + public Search.QueryResultDto getContingencyTable(@NotNull BaseStudyTable studyTable, DatasetVariable variable, DatasetVariable crossVariable) throws NoSuchStudyException, NoSuchValueTableException { - return getFacets(QueryTermsUtil.getContingencyQuery(variable, crossVariable), opalTable); + return getFacets(QueryTermsUtil.getContingencyQuery(variable, crossVariable), studyTable); } @Override @@ -487,71 +468,23 @@ protected HarmonizationDataset prepareSave(HarmonizationDataset dataset) { } } - private Iterable getVariables(OpalTable opalTable) + private Iterable getVariables(BaseStudyTable studyTable) throws NoSuchDatasetException, NoSuchStudyException, NoSuchValueTableException { - return getTable(opalTable).getVariables(); + return getStudyTableSource(studyTable).getValueTable().getVariables(); } - private RestValueTable getTable(@NotNull OpalTable opalTable) + private ValueTable getTable(@NotNull HarmonizationDataset dataset, String studyId, String sourceURN) throws NoSuchStudyException, NoSuchValueTableException { - return execute(opalTable, ds -> (RestValueTable) ds.getValueTable(opalTable.getTable())); - } - - private ValueTable getTable(@NotNull HarmonizationDataset dataset, String studyId, String project, String table) - throws NoSuchStudyException, NoSuchValueTableException { - - for(BaseStudyTable opalTable : dataset.getBaseStudyTables()) { - String opalTableId = studyId; - if(opalTable.isFor(opalTableId, project, table)) { - return getTable(opalTable); - } - } - - throw NoSuchStudyException.withId(studyId); - } - private RestValueTable.RestVariableValueSource getVariableValueSource(@NotNull HarmonizationDataset dataset, - String variableName, String studyId, String project, String table) - throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { - for(BaseStudyTable opalTable : dataset.getBaseStudyTables()) { - String opalTableId = studyId; - if(opalTable.isFor(opalTableId, project, table)) { - return getVariableValueSource(variableName, opalTable); + for(BaseStudyTable baseTable : dataset.getBaseStudyTables()) { + if(baseTable.isFor(studyId, sourceURN)) { + return getStudyTableSource(baseTable).getValueTable(); } } throw NoSuchStudyException.withId(studyId); } - private RestValueTable.RestVariableValueSource getVariableValueSource(String variableName, OpalTable opalTable) - throws NoSuchStudyException, NoSuchValueTableException, NoSuchVariableException { - return (RestValueTable.RestVariableValueSource) getTable(opalTable).getVariableValueSource(variableName); - } - - /** - * Build or reuse the {@link org.obiba.opal.rest.client.magma.RestDatasource} and execute the callback with it. - * - * @param project - * @param callback - * @param - * @return - */ - private T execute(String project, DatasourceCallback callback) { - return execute(getDatasource(project), callback); - } - - /** - * Build or reuse the {@link org.obiba.opal.rest.client.magma.RestDatasource} and execute the callback with it. - * - * @param opalTable - * @param callback - * @param - * @return - */ - private T execute(OpalTable opalTable, DatasourceCallback callback) { - return execute(getDatasource(opalTable), callback); - } - @Override protected EntityStateRepository getEntityStateRepository() { return harmonizationDatasetStateRepository; @@ -609,7 +542,7 @@ public void asyncBuildDatasetVariablesCache(HarmonizationDataset dataset, dataset.getBaseStudyTables().forEach(st -> harmonizationVariables.forEach((k, v) -> v.forEach(var -> { try { String studyId = st.getStudyId(); - service.getVariableSummary(dataset, var.getName(), studyId, st.getProject(), st.getTable()); + service.getVariableSummary(dataset, var.getName(), studyId, st.getSourceURN()); } catch(Exception e) { //ignoring } diff --git a/mica-core/src/main/java/org/obiba/mica/dataset/service/VariableSetService.java b/mica-core/src/main/java/org/obiba/mica/dataset/service/VariableSetService.java index f10ae60e22..a46d0c0fbc 100644 --- a/mica-core/src/main/java/org/obiba/mica/dataset/service/VariableSetService.java +++ b/mica-core/src/main/java/org/obiba/mica/dataset/service/VariableSetService.java @@ -13,23 +13,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.googlecode.protobuf.format.JsonFormat; -import java.io.IOException; -import java.io.OutputStream; -import java.util.*; -import java.util.Map.Entry; -import java.util.stream.Collectors; -import java.util.zip.ZipEntry; -import java.util.zip.ZipOutputStream; -import org.obiba.mica.core.domain.Attributes; -import org.obiba.mica.core.domain.DocumentSet; -import org.obiba.mica.core.domain.LocalizedString; -import org.obiba.mica.core.domain.OpalTable; +import org.obiba.mica.core.domain.*; import org.obiba.mica.core.service.DocumentSetService; -import org.obiba.mica.dataset.domain.Dataset; -import org.obiba.mica.dataset.domain.DatasetCategory; -import org.obiba.mica.dataset.domain.DatasetVariable; -import org.obiba.mica.dataset.domain.HarmonizationDataset; -import org.obiba.mica.dataset.domain.StudyDataset; +import org.obiba.mica.dataset.domain.*; import org.obiba.mica.micaConfig.domain.MicaConfig; import org.obiba.mica.study.service.PublishedDatasetVariableService; import org.obiba.opal.web.model.Magma; @@ -37,6 +23,13 @@ import org.springframework.validation.annotation.Validated; import javax.inject.Inject; +import java.io.IOException; +import java.io.OutputStream; +import java.util.*; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; @Service @Validated @@ -320,16 +313,16 @@ private List toCategoryDtoList(List categori private List toOpalTableFullName(Dataset dataset) { if (dataset instanceof StudyDataset) { - OpalTable opalTable = ((StudyDataset) dataset).getSafeStudyTable(); - return Lists.newArrayList(opalTable.getProject() + "." + opalTable.getTable()); + StudyTable studyTable = ((StudyDataset) dataset).getSafeStudyTable(); + return Lists.newArrayList(OpalTableSource.toTableName(studyTable.getSourceURN())); } else { HarmonizationDataset harmoDataset = (HarmonizationDataset) dataset; // one for each study and harmo tables List tableNames = Lists.newArrayList(); tableNames.addAll(harmoDataset.getStudyTables().stream() - .map(st -> st.getProject() + "." + st.getTable()).collect(Collectors.toList())); + .map(st -> OpalTableSource.toTableName(st.getSourceURN())).collect(Collectors.toList())); tableNames.addAll(harmoDataset.getHarmonizationTables().stream() - .map(ht -> ht.getProject() + "." + ht.getTable()).collect(Collectors.toList())); + .map(ht -> OpalTableSource.toTableName(ht.getSourceURN())).collect(Collectors.toList())); return tableNames; } } diff --git a/mica-core/src/main/java/org/obiba/mica/micaConfig/service/CacheService.java b/mica-core/src/main/java/org/obiba/mica/micaConfig/service/CacheService.java index 22bbacab51..b40ca985c7 100644 --- a/mica-core/src/main/java/org/obiba/mica/micaConfig/service/CacheService.java +++ b/mica-core/src/main/java/org/obiba/mica/micaConfig/service/CacheService.java @@ -108,7 +108,7 @@ public void buildDatasetVariablesCache() { String studyId = st.getStudyId(); try { harmonizedDatasetService - .getVariableSummary(dataset, v.getName(), studyId, st.getProject(), st.getTable()); + .getVariableSummary(dataset, v.getName(), studyId, st.getSourceURN()); } catch(NoSuchVariableException ex) { //ignore } catch(Exception e) { diff --git a/mica-core/src/main/java/org/obiba/mica/micaConfig/service/PluginsService.java b/mica-core/src/main/java/org/obiba/mica/micaConfig/service/PluginsService.java index f06ba2d76a..a42198fe64 100644 --- a/mica-core/src/main/java/org/obiba/mica/micaConfig/service/PluginsService.java +++ b/mica-core/src/main/java/org/obiba/mica/micaConfig/service/PluginsService.java @@ -16,6 +16,8 @@ import com.google.common.io.Files; import org.obiba.core.util.FileUtil; import org.obiba.mica.core.upgrade.RuntimeVersionProvider; +import org.obiba.mica.spi.dataset.StudyTableSourceService; +import org.obiba.mica.spi.dataset.StudyTableSourceServiceLoader; import org.obiba.mica.spi.search.ConfigurationProvider; import org.obiba.mica.spi.search.SearchEngineService; import org.obiba.mica.spi.search.SearchEngineServiceLoader; @@ -86,12 +88,17 @@ public SearchEngineService getSearchEngineService() { return (SearchEngineService) getServicePlugins(SearchEngineService.class).iterator().next(); } + public Collection getStudyTableSourceServices() { + return getServicePlugins(StudyTableSourceService.class).stream() + .map(service -> (StudyTableSourceService)service) + .collect(Collectors.toList()); + } + // // Private methods // private Collection getServicePlugins(Class clazz) { - //init(); return servicePlugins.stream().filter(s -> clazz.isAssignableFrom(s.getClass())).collect(Collectors.toList()); } @@ -155,6 +162,13 @@ private void initSearchEngineServicePlugin(PluginResources plugin) { servicePlugins.add(service); } + private void initStudyTableSourceServicePlugins(PluginResources plugin) { + StudyTableSourceServiceLoader.get(plugin.getURLClassLoader(false)).forEach(service -> { + service.start(); + servicePlugins.add(service); + }); + } + private synchronized Collection getPlugins(boolean extract) { Map pluginsMap = Maps.newLinkedHashMap(); // make sure plugins directory exists diff --git a/mica-core/src/main/java/org/obiba/mica/web/model/DatasetDtos.java b/mica-core/src/main/java/org/obiba/mica/web/model/DatasetDtos.java index f9c44d1446..ff73485bf8 100644 --- a/mica-core/src/main/java/org/obiba/mica/web/model/DatasetDtos.java +++ b/mica-core/src/main/java/org/obiba/mica/web/model/DatasetDtos.java @@ -10,29 +10,15 @@ package org.obiba.mica.web.model; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.validation.constraints.NotNull; - +import com.google.common.base.Strings; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import org.obiba.magma.type.BooleanType; import org.obiba.mica.JSONUtils; import org.obiba.mica.core.domain.*; import org.obiba.mica.dataset.HarmonizationDatasetStateRepository; import org.obiba.mica.dataset.StudyDatasetStateRepository; -import org.obiba.mica.dataset.domain.Dataset; -import org.obiba.mica.dataset.domain.DatasetCategory; -import org.obiba.mica.dataset.domain.DatasetVariable; -import org.obiba.mica.dataset.domain.HarmonizationDataset; -import org.obiba.mica.dataset.domain.HarmonizationDatasetState; -import org.obiba.mica.dataset.domain.StudyDataset; -import org.obiba.mica.dataset.domain.StudyDatasetState; +import org.obiba.mica.dataset.domain.*; import org.obiba.mica.micaConfig.domain.MicaConfig; import org.obiba.mica.micaConfig.service.MicaConfigService; import org.obiba.mica.security.service.SubjectAclService; @@ -45,9 +31,11 @@ import org.springframework.stereotype.Component; import org.springframework.util.Assert; -import com.google.common.base.Strings; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.validation.constraints.NotNull; +import java.util.*; +import java.util.stream.Collectors; @Component class DatasetDtos { @@ -194,11 +182,13 @@ Mica.DatasetVariableResolverDto.Builder asDto(@NotNull DatasetVariable.IdResolve if(resolver.hasStudyId()) { builder.setStudyId(resolver.getStudyId()); } - if(resolver.hasProject()) { - builder.setProject(resolver.getProject()); - } - if(resolver.hasTable()) { - builder.setTable(resolver.getTable()); + if(resolver.hasSourceURN()) { + builder.setSourceURN(resolver.getSourceURN()); + if (OpalTableSource.isFor(resolver.getSourceURN())) { + OpalTableSource source = OpalTableSource.fromURN(resolver.getSourceURN()); + builder.setProject(source.getProject()); + builder.setTable(source.getTable()); + } } return builder; @@ -314,8 +304,8 @@ Mica.DatasetVariableDto asDto(@NotNull DatasetVariable variable, @NotNull List builder.addAttributes(attributeDtos.asDto(attribute))); } - if(opalTable instanceof StudyTable) builder.setStudyTable(asDto((StudyTable) opalTable, includeSummaries)); - else if(opalTable instanceof HarmonizationStudyTable) { - builder.setHarmonizationStudyTable(asDto((HarmonizationStudyTable) opalTable, includeSummaries)); + if(studyTable instanceof StudyTable) builder.setStudyTable(asDto((StudyTable) studyTable, includeSummaries)); + else if(studyTable instanceof HarmonizationStudyTable) { + builder.setHarmonizationStudyTable(asDto((HarmonizationStudyTable) studyTable, includeSummaries)); } return builder.build(); @@ -408,13 +398,18 @@ public Mica.DatasetDto.StudyTableDto.Builder asDto(StudyTable studyTable) { } public Mica.DatasetDto.StudyTableDto.Builder asDto(StudyTable studyTable, boolean includeSummary) { - Mica.DatasetDto.StudyTableDto.Builder sbuilder = Mica.DatasetDto.StudyTableDto.newBuilder() // - .setProject(studyTable.getProject())// - .setTable(studyTable.getTable()) // - .setWeight(studyTable.getWeight()) // - .setStudyId(studyTable.getStudyId()) // + Mica.DatasetDto.StudyTableDto.Builder sbuilder = Mica.DatasetDto.StudyTableDto.newBuilder() + .setSourceURN(studyTable.getSourceURN()) + .setWeight(studyTable.getWeight()) + .setStudyId(studyTable.getStudyId()) .setDceId(studyTable.getDataCollectionEventUId()); + if (OpalTableSource.isFor(studyTable.getSourceURN())) { + OpalTableSource source = OpalTableSource.fromURN(studyTable.getSourceURN()); + sbuilder.setProject(source.getProject()); + sbuilder.setTable(source.getTable()); + } + String populationId = studyTable.getPopulationId(); if (!Strings.isNullOrEmpty(populationId)) { sbuilder.setPopulationId(populationId); @@ -441,11 +436,16 @@ public Mica.DatasetDto.HarmonizationTableDto.Builder asDto(HarmonizationStudyTab public Mica.DatasetDto.HarmonizationTableDto.Builder asDto(HarmonizationStudyTable harmonizationTable, boolean includeSummary) { Mica.DatasetDto.HarmonizationTableDto.Builder hBuilder = Mica.DatasetDto.HarmonizationTableDto.newBuilder() - .setProject(harmonizationTable.getProject()) - .setTable(harmonizationTable.getTable()) + .setSourceURN(harmonizationTable.getSourceURN()) .setWeight(harmonizationTable.getWeight()) .setStudyId(harmonizationTable.getStudyId()); + if (OpalTableSource.isFor(harmonizationTable.getSourceURN())) { + OpalTableSource source = OpalTableSource.fromURN(harmonizationTable.getSourceURN()); + hBuilder.setProject(source.getProject()); + hBuilder.setTable(source.getTable()); + } + if(includeSummary) hBuilder.setStudySummary(studySummaryDtos.asDto(harmonizationTable.getStudyId())); hBuilder.addAllName(localizedStringDtos.asDto(harmonizationTable.getName())); @@ -455,16 +455,16 @@ public Mica.DatasetDto.HarmonizationTableDto.Builder asDto(HarmonizationStudyTab return hBuilder; } - public Mica.DatasetVariableAggregationDto.Builder asDto(@NotNull OpalTable opalTable, + public Mica.DatasetVariableAggregationDto.Builder asDto(@NotNull BaseStudyTable studyTable, @Nullable Math.SummaryStatisticsDto summary, boolean withStudySummary) { Mica.DatasetVariableAggregationDto.Builder aggDto = Mica.DatasetVariableAggregationDto.newBuilder(); aggDto = simpleAggregationDto(aggDto, summary); - if(opalTable instanceof StudyTable) - aggDto.setStudyTable(asDto((StudyTable) opalTable, withStudySummary)); - else if (opalTable instanceof HarmonizationStudyTable) - aggDto.setHarmonizationStudyTable(asDto((HarmonizationStudyTable) opalTable, withStudySummary)); + if(studyTable instanceof StudyTable) + aggDto.setStudyTable(asDto((StudyTable) studyTable, withStudySummary)); + else if (studyTable instanceof HarmonizationStudyTable) + aggDto.setHarmonizationStudyTable(asDto((HarmonizationStudyTable) studyTable, withStudySummary)); return aggDto; } @@ -490,14 +490,14 @@ public Mica.DatasetVariableAggregationDto.Builder simpleAggregationDto(@NotNull return aggDto; } - public Mica.DatasetVariableContingencyDto.Builder asContingencyDto(@NotNull OpalTable opalTable, + public Mica.DatasetVariableContingencyDto.Builder asContingencyDto(@NotNull BaseStudyTable studyTable, DatasetVariable variable, DatasetVariable crossVariable, @Nullable Search.QueryResultDto results) { Mica.DatasetVariableContingencyDto.Builder crossDto = Mica.DatasetVariableContingencyDto.newBuilder(); - if(opalTable instanceof StudyTable) - crossDto.setStudyTable(asDto((StudyTable) opalTable, true)); - else if (opalTable instanceof HarmonizationStudyTable) - crossDto.setHarmonizationStudyTable(asDto((HarmonizationStudyTable) opalTable)); + if(studyTable instanceof StudyTable) + crossDto.setStudyTable(asDto((StudyTable) studyTable, true)); + else if (studyTable instanceof HarmonizationStudyTable) + crossDto.setHarmonizationStudyTable(asDto((HarmonizationStudyTable) studyTable)); Mica.DatasetVariableAggregationDto.Builder allAggBuilder = Mica.DatasetVariableAggregationDto.newBuilder(); @@ -780,8 +780,12 @@ private Dataset fromDto(@NotNull Mica.HarmonizedDatasetDto dto) { if(dto.hasHarmonizationTable()) { HarmonizationStudyTable harmonizationLink = new HarmonizationStudyTable(); - harmonizationLink.setProject(dto.getHarmonizationTable().getProject()); - harmonizationLink.setTable(dto.getHarmonizationTable().getTable()); + // legacy + if (dto.getHarmonizationTable().hasProject() && dto.getHarmonizationTable().hasTable()) { + harmonizationLink.setSourceURN(makeSourceURN(dto.getHarmonizationTable().getProject(), dto.getHarmonizationTable().getTable())); + } else { + harmonizationLink.setSourceURN(dto.getHarmonizationTable().getSourceURN()); + } harmonizationLink.setStudyId(dto.getHarmonizationTable().getStudyId()); harmonizationDataset.setHarmonizationTable(harmonizationLink); } @@ -804,41 +808,56 @@ private StudyTable fromDto(Mica.DatasetDto.StudyTableDto dto) { if (dto.hasDataCollectionEventId()) { table.setDataCollectionEventId(dto.getDataCollectionEventId()); } - table.setProject(dto.getProject()); - table.setTable(dto.getTable()); table.setWeight(dto.getWeight()); - table.setName(localizedStringDtos.fromDto(dto.getNameList())); table.setDescription(localizedStringDtos.fromDto(dto.getDescriptionList())); table.setAdditionalInformation(localizedStringDtos.fromDto(dto.getAdditionalInformationList())); + if (dto.hasProject() && dto.hasTable()) { + table.setSourceURN(makeSourceURN(dto.getProject(), dto.getTable())); + } else { + table.setSourceURN(dto.getSourceURN()); + } + return table; } private HarmonizationStudyTable fromDto(Mica.DatasetDto.HarmonizationTableDto dto) { HarmonizationStudyTable table = new HarmonizationStudyTable(); table.setStudyId(dto.getStudyId()); - table.setProject(dto.getProject()); - table.setTable(dto.getTable()); table.setWeight(dto.getWeight()); - table.setName(localizedStringDtos.fromDto(dto.getNameList())); table.setDescription(localizedStringDtos.fromDto(dto.getDescriptionList())); table.setAdditionalInformation(localizedStringDtos.fromDto(dto.getAdditionalInformationList())); + // legacy + if (dto.hasProject() && dto.hasTable()) { + table.setSourceURN(makeSourceURN(dto.getProject(), dto.getTable())); + } else { + table.setSourceURN(dto.getSourceURN()); + } + return table; } + // legacy + private String makeSourceURN(String project, String table) { + return OpalTableSource.newSource(project, table).getURN(); + } + private Mica.DatasetDto.HarmonizationTableDto.Builder createHarmonizationLinkDtoFromHarmonizationTable( HarmonizationStudyTable harmonizationLink, boolean asDraft) { Mica.DatasetDto.HarmonizationTableDto.Builder harmonizationLinkBuilder = Mica.DatasetDto.HarmonizationTableDto .newBuilder(); - if(!Strings.isNullOrEmpty(harmonizationLink.getProject())) - harmonizationLinkBuilder.setProject(harmonizationLink.getProject()); - - if(!Strings.isNullOrEmpty(harmonizationLink.getTable())) - harmonizationLinkBuilder.setTable(harmonizationLink.getTable()); + if(!Strings.isNullOrEmpty(harmonizationLink.getSourceURN())) { + harmonizationLinkBuilder.setSourceURN(harmonizationLink.getSourceURN()); + if (OpalTableSource.isFor(harmonizationLink.getSourceURN())) { + OpalTableSource source = OpalTableSource.fromURN(harmonizationLink.getSourceURN()); + harmonizationLinkBuilder.setProject(source.getProject()); + harmonizationLinkBuilder.setTable(source.getTable()); + } + } String studyId = harmonizationLink.getStudyId(); diff --git a/mica-core/src/main/java/org/obiba/mica/web/model/Dtos.java b/mica-core/src/main/java/org/obiba/mica/web/model/Dtos.java index efecd0583b..cb7a8d03f4 100644 --- a/mica-core/src/main/java/org/obiba/mica/web/model/Dtos.java +++ b/mica-core/src/main/java/org/obiba/mica/web/model/Dtos.java @@ -397,8 +397,8 @@ public Mica.DatasetHarmonizedVariableSummaryDto asHarmonizedSummaryDto(@NotNull } @NotNull - public Mica.DatasetVariableSummaryDto asSummaryDto(@NotNull DatasetVariable variable, OpalTable opalTable, boolean includeSummaries) { - return datasetDtos.asSummaryDto(variable, opalTable, includeSummaries); + public Mica.DatasetVariableSummaryDto asSummaryDto(@NotNull DatasetVariable variable, BaseStudyTable studyTable, boolean includeSummaries) { + return datasetDtos.asSummaryDto(variable, studyTable, includeSummaries); } @NotNull @@ -427,9 +427,9 @@ public Mica.DatasetDto.StudyTableDto.Builder asDto(@NotNull StudyTable studyTabl } @NotNull - public Mica.DatasetVariableAggregationDto.Builder asDto(@NotNull OpalTable opalTable, + public Mica.DatasetVariableAggregationDto.Builder asDto(@NotNull BaseStudyTable studyTable, @Nullable Math.SummaryStatisticsDto summary, boolean withStudySummary) { - return datasetDtos.asDto(opalTable, summary, withStudySummary); + return datasetDtos.asDto(studyTable, summary, withStudySummary); } @NotNull @@ -438,9 +438,9 @@ public Mica.DatasetVariableAggregationDto.Builder asDto(@NotNull Math.SummarySta } @NotNull - public Mica.DatasetVariableContingencyDto.Builder asContingencyDto(OpalTable opalTable, DatasetVariable variable, + public Mica.DatasetVariableContingencyDto.Builder asContingencyDto(BaseStudyTable studyTable, DatasetVariable variable, DatasetVariable crossVariable, @Nullable Search.QueryResultDto results) { - return datasetDtos.asContingencyDto(opalTable, variable, crossVariable, results); + return datasetDtos.asContingencyDto(studyTable, variable, crossVariable, results); } @NotNull diff --git a/mica-core/src/test/java/org/obiba/mica/dataset/service/CollectedDatasetServiceTest.java b/mica-core/src/test/java/org/obiba/mica/dataset/service/CollectedDatasetServiceTest.java index f3247ef05a..7290609736 100644 --- a/mica-core/src/test/java/org/obiba/mica/dataset/service/CollectedDatasetServiceTest.java +++ b/mica-core/src/test/java/org/obiba/mica/dataset/service/CollectedDatasetServiceTest.java @@ -19,6 +19,7 @@ import org.mockito.MockitoAnnotations; import org.obiba.magma.MagmaRuntimeException; import org.obiba.mica.core.domain.LocalizedString; +import org.obiba.mica.core.domain.OpalTableSource; import org.obiba.mica.core.domain.StudyTable; import org.obiba.mica.core.service.GitService; import org.obiba.mica.dataset.StudyDatasetRepository; @@ -98,8 +99,7 @@ public void testDatasourceConnectionErrorIsIgnoredForDraft() { private StudyDataset buildStudyDataset() { StudyDataset ds = new StudyDataset(); StudyTable st = new StudyTable(); - st.setProject("proj"); - st.setTable("tab"); + st.setSourceURN(OpalTableSource.newSource("proj", "tab").getURN()); st.setPopulationId("1"); st.setDataCollectionEventId("1"); ds.setStudyTable(st); diff --git a/mica-core/src/test/java/org/obiba/mica/dataset/service/HarmonizedDatasetServiceTest.java b/mica-core/src/test/java/org/obiba/mica/dataset/service/HarmonizedDatasetServiceTest.java index a7ef5e54cf..9ff32e5db6 100644 --- a/mica-core/src/test/java/org/obiba/mica/dataset/service/HarmonizedDatasetServiceTest.java +++ b/mica-core/src/test/java/org/obiba/mica/dataset/service/HarmonizedDatasetServiceTest.java @@ -24,6 +24,7 @@ import org.mockito.Spy; import org.mockito.Mock; import org.mockito.MockitoAnnotations; +import org.obiba.mica.core.domain.OpalTableSource; import org.obiba.mica.dataset.domain.DatasetVariable; import org.obiba.magma.Variable; import org.obiba.magma.type.BooleanType; @@ -98,8 +99,7 @@ private HarmonizationDataset buildHarmonizationDataset(String id, StudyTable... private StudyTable buildStudyTable(String project, String table, String studyId) { StudyTable st = new StudyTable(); - st.setProject(project); - st.setTable(table); + st.setSourceURN(OpalTableSource.newSource(project, table).getURN()); st.setStudyId(studyId); st.setPopulationId("pop"); st.setDataCollectionEventId("ev"); diff --git a/mica-core/src/test/java/org/obiba/mica/dataset/support/HarmonizedDatasetHelperTest.java b/mica-core/src/test/java/org/obiba/mica/dataset/support/HarmonizedDatasetHelperTest.java index 619a01fbe9..2736b5acdb 100644 --- a/mica-core/src/test/java/org/obiba/mica/dataset/support/HarmonizedDatasetHelperTest.java +++ b/mica-core/src/test/java/org/obiba/mica/dataset/support/HarmonizedDatasetHelperTest.java @@ -19,6 +19,7 @@ import org.mockito.junit.MockitoJUnitRunner; import org.obiba.mica.core.domain.BaseStudyTable; import org.obiba.mica.core.domain.HarmonizationStudyTable; +import org.obiba.mica.core.domain.OpalTableSource; import org.obiba.mica.core.domain.StudyTable; import org.obiba.mica.dataset.domain.HarmonizationDataset; import static org.obiba.mica.assertj.Assertions.assertThat; @@ -107,8 +108,9 @@ private StudyTable createStudyTable(String studyId) { private void initTable(String studyId, BaseStudyTable table) { table.setStudyId(studyId); - table.setProject(RandomStringUtils.random(10, true, false)); - table.setTable(RandomStringUtils.random(10, true, false)); + String project = RandomStringUtils.random(10, true, false); + String tbl = RandomStringUtils.random(10, true, false); + table.setSourceURN(OpalTableSource.newSource(project, tbl).getURN()); table.setPopulationId(RandomStringUtils.random(10, true, true)); } } diff --git a/mica-core/src/test/java/org/obiba/mica/web/model/DatasetDtosTest.java b/mica-core/src/test/java/org/obiba/mica/web/model/DatasetDtosTest.java index 3e43c7e942..3a31dd978f 100644 --- a/mica-core/src/test/java/org/obiba/mica/web/model/DatasetDtosTest.java +++ b/mica-core/src/test/java/org/obiba/mica/web/model/DatasetDtosTest.java @@ -18,6 +18,7 @@ import org.mockito.Spy; import org.mockito.junit.MockitoJUnitRunner; import org.obiba.mica.core.domain.HarmonizationStudyTable; +import org.obiba.mica.core.domain.OpalTableSource; import org.obiba.mica.dataset.HarmonizationDatasetStateRepository; import org.obiba.mica.dataset.domain.HarmonizationDataset; import org.obiba.mica.dataset.domain.HarmonizationDatasetState; @@ -108,8 +109,7 @@ private HarmonizationDataset createHarmonizedDataset() { HarmonizationDataset harmonizationDataset = new HarmonizationDataset(); harmonizationDataset.setId("123"); HarmonizationStudyTable harmonizationLink = new HarmonizationStudyTable(); - harmonizationLink.setProject("project123"); - harmonizationLink.setTable("table123"); + harmonizationLink.setSourceURN(OpalTableSource.newSource("project123", "table123").getURN()); harmonizationLink.setStudyId("study123"); harmonizationLink.setPopulationId("population123"); harmonizationDataset.setHarmonizationTable(harmonizationLink); diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/PublishedDatasetResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/PublishedDatasetResource.java index 0b99919e8a..1c4e033b4d 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/PublishedDatasetResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/PublishedDatasetResource.java @@ -17,6 +17,7 @@ import javax.ws.rs.PathParam; import org.apache.shiro.SecurityUtils; +import org.obiba.mica.core.domain.OpalTableSource; import org.obiba.mica.dataset.NoSuchDatasetException; import org.obiba.mica.dataset.domain.Dataset; import org.obiba.mica.dataset.domain.DatasetVariable; @@ -88,8 +89,7 @@ private StudyDataset alternativeStudyDataset(String id, String project, String t if (!(dataset instanceof StudyDataset)) throw NoSuchDatasetException.withId(id); StudyDataset asStudyDataset = (StudyDataset) dataset; - asStudyDataset.getStudyTable().setProject(project); - asStudyDataset.getStudyTable().setTable(table); + asStudyDataset.getStudyTable().setSourceURN(OpalTableSource.newSource(project, table).getURN()); return asStudyDataset; } diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetResource.java index f35a36937d..1e3f65d751 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetResource.java @@ -132,13 +132,6 @@ public Response unPublish() { return Response.noContent().build(); } - @GET - @Path("/table") - public Magma.TableDto getTable() { - checkPermission("/draft/collected-dataset", "VIEW"); - return datasetService.getTableDto(getDataset()); - } - @GET @Path("/variables") public List getVariables() { diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetVariableResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetVariableResource.java index 48085456d0..7d8b74aa1f 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetVariableResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/collection/DraftCollectedDatasetVariableResource.java @@ -49,12 +49,6 @@ public Math.SummaryStatisticsDto getVariableSummary() { return datasetService.getVariableSummary(getDataset(), variableName).getWrappedDto(); } - @GET - @Path("/facet") - public Search.QueryResultDto getVariableFacet() { - return datasetService.getVariableFacet(getDataset(), variableName); - } - private StudyDataset getDataset() { return datasetService.findById(datasetId); } diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLCriteriaOpalConverter.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLCriteriaOpalConverter.java index 13520f0078..01ae1090c0 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLCriteriaOpalConverter.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLCriteriaOpalConverter.java @@ -182,8 +182,7 @@ private RQLFieldReferences parseField(String path) { } else if (DatasetVariable.Type.Harmonized.equals(resolver.getType())) { HarmonizationDataset ds = harmonizedDatasetService.findById(resolver.getDatasetId()); Optional studyTable = ds.getBaseStudyTables().stream().filter(st -> st.getStudyId().equals(resolver.getStudyId()) - && st.getProject().equals(resolver.getProject()) - && st.getTable().equals(resolver.getTable())).findFirst(); + && st.getSourceURN().equals(resolver.getSourceURN())).findFirst(); if (!studyTable.isPresent()) throw new IllegalArgumentException("Not a valid variable: " + path); BaseStudy study = studyService.findStudy(studyTable.get().getStudyId()); return new RQLFieldReferences(path, ds, studyTable.get(), study, getDatasetVariableInternal(Indexer.PUBLISHED_HVARIABLE_INDEX, Indexer.HARMONIZED_VARIABLE_TYPE, path)); diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLFieldReferences.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLFieldReferences.java index b3a7cc7a11..6c59af7c68 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLFieldReferences.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/entity/rql/RQLFieldReferences.java @@ -89,6 +89,6 @@ public LocalizedString getStudyTableName() { * @return */ private String getOpalTablePath(BaseStudyTable studyTable) { - return studyTable.getProject() + "." + studyTable.getTable(); + return studyTable.getSourceURN().replace("urn:opal:", ""); } } diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftDataschemaDatasetVariableResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftDataschemaDatasetVariableResource.java index 59f08ddd36..e704dadfd7 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftDataschemaDatasetVariableResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftDataschemaDatasetVariableResource.java @@ -58,7 +58,7 @@ public List getVariableSummaries() { try { String studyId = table.getStudyId(); builder.add(datasetService - .getVariableSummary(dataset, variableName, studyId, table.getProject(), table.getTable()) + .getVariableSummary(dataset, variableName, studyId, table.getSourceURN()) .getWrappedDto()); } catch(NoSuchVariableException | NoSuchValueTableException e) { // ignore (case the study has not implemented this dataschema variable) @@ -67,22 +67,6 @@ public List getVariableSummaries() { return builder.build(); } - @GET - @Path("/facet") - public List getVariableFacets() { - ImmutableList.Builder builder = ImmutableList.builder(); - HarmonizationDataset dataset = getDataset(); - dataset.getBaseStudyTables().forEach(table -> { - try { - String studyId = table.getStudyId(); - builder.add(datasetService.getVariableFacet(dataset, variableName, studyId, table.getProject(), table.getTable())); - } catch(NoSuchVariableException | NoSuchValueTableException e) { - // ignore (case the study has not implemented this dataschema variable) - } - }); - return builder.build(); - } - @GET @Path("/harmonizations") public List getHarmonizedVariables() { diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetResource.java index 9cf772160c..72bb06857c 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetResource.java @@ -137,13 +137,6 @@ public Response unPublish() { return Response.noContent().build(); } - @GET - @Path("/table") - public Magma.TableDto getTable() { - checkPermission("/draft/harmonized-dataset", "VIEW"); - return datasetService.getTableDto(getDataset()); - } - @GET @Path("/variables") public List getVariables() { diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetVariableResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetVariableResource.java index 6e50046272..eb13792215 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetVariableResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/harmonization/DraftHarmonizedDatasetVariableResource.java @@ -39,37 +39,25 @@ public class DraftHarmonizedDatasetVariableResource implements DatasetVariableRe private String studyId; - private String project; - - private String table; + private String sourceURN; @GET public Mica.DatasetVariableDto getVariable() { - return dtos.asDto(datasetService.getDatasetVariable(getDataset(), variableName, studyId, project, table)); + return dtos.asDto(datasetService.getDatasetVariable(getDataset(), variableName, studyId, sourceURN)); } @GET @Path("/summary") public org.obiba.opal.web.model.Math.SummaryStatisticsDto getVariableSummary() { - return datasetService.getVariableSummary(getDataset(), variableName, studyId, project, table).getWrappedDto(); - } - - @GET - @Path("/facet") - public Search.QueryResultDto getVariableFacet() { - return datasetService.getVariableFacet(getDataset(), variableName, studyId, project, table); + return datasetService.getVariableSummary(getDataset(), variableName, studyId, sourceURN).getWrappedDto(); } public void setStudyId(String studyId) { this.studyId = studyId; } - public void setProject(String project) { - this.project = project; - } - - public void setTable(String table) { - this.table = table; + public void setSourceURN(String sourceURN) { + this.sourceURN = sourceURN; } private HarmonizationDataset getDataset() { diff --git a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/variable/DraftDatasetVariableResource.java b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/variable/DraftDatasetVariableResource.java index fdd222a13b..589a2b88f3 100644 --- a/mica-rest/src/main/java/org/obiba/mica/dataset/rest/variable/DraftDatasetVariableResource.java +++ b/mica-rest/src/main/java/org/obiba/mica/dataset/rest/variable/DraftDatasetVariableResource.java @@ -52,8 +52,7 @@ public DatasetVariableResource getVariable(@PathParam("id") String id) { subjectAclService.isPermitted("/draft/harmonized-dataset", "VIEW", resolver.getDatasetId()); resource = applicationContext.getBean(DraftHarmonizedDatasetVariableResource.class); ((DraftHarmonizedDatasetVariableResource) resource).setStudyId(resolver.getStudyId()); - ((DraftHarmonizedDatasetVariableResource) resource).setProject(resolver.getProject()); - ((DraftHarmonizedDatasetVariableResource) resource).setTable(resolver.getTable()); + ((DraftHarmonizedDatasetVariableResource) resource).setSourceURN(resolver.getSourceURN()); break; } diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/AbstractPublishedDatasetResource.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/AbstractPublishedDatasetResource.java index 933ff76eac..e4e1ca09a7 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/AbstractPublishedDatasetResource.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/AbstractPublishedDatasetResource.java @@ -10,23 +10,11 @@ package org.obiba.mica.dataset.search.rest; -import java.io.IOException; -import java.io.InputStream; -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.stream.Collectors; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.validation.constraints.NotNull; -import javax.ws.rs.ForbiddenException; - +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.base.Strings; import org.apache.shiro.SecurityUtils; import org.obiba.magma.NoSuchVariableException; import org.obiba.mica.core.domain.BaseStudyTable; -import org.obiba.mica.core.domain.OpalTable; import org.obiba.mica.core.domain.StudyTable; import org.obiba.mica.dataset.NoSuchDatasetException; import org.obiba.mica.dataset.domain.Dataset; @@ -44,8 +32,17 @@ import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.base.Strings; +import javax.annotation.Nullable; +import javax.inject.Inject; +import javax.validation.constraints.NotNull; +import javax.ws.rs.ForbiddenException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.stream.Collectors; /** * Retrieve the {@link org.obiba.mica.dataset.domain.Dataset} from the published dataset index. @@ -211,22 +208,21 @@ protected Mica.DatasetVariableHarmonizationSummaryDto getVariableHarmonizationSu } protected DatasetVariable getDatasetVariable(@NotNull String datasetId, @NotNull String variableName, - DatasetVariable.Type variableType, OpalTable opalTable) { + DatasetVariable.Type variableType, BaseStudyTable studyTable) { - if (opalTable != null) { + if (studyTable != null) { return getDatasetVariable(datasetId, variableName, variableType, - opalTable instanceof BaseStudyTable ? ((BaseStudyTable) opalTable).getStudyId() : null, - opalTable.getProject(), - opalTable.getTable(), - opalTable instanceof StudyTable + studyTable.getStudyId(), + studyTable.getSourceURN(), + studyTable instanceof StudyTable ? DatasetVariable.OPAL_STUDY_TABLE_PREFIX : DatasetVariable.OPAL_HARMONIZATION_TABLE_PREFIX); } - return getDatasetVariable(datasetId, variableName, variableType, null, null, null, null); + return getDatasetVariable(datasetId, variableName, variableType, null, null, null); } /** @@ -236,18 +232,18 @@ protected DatasetVariable getDatasetVariable(@NotNull String datasetId, @NotNull * @param datasetId * @param variableName * @param studyId - * @param project - * @param table + * @param sourceURN + * @param tableType * @return * @throws NoSuchVariableException */ protected DatasetVariable getDatasetVariable(@NotNull String datasetId, @NotNull String variableName, - DatasetVariable.Type variableType, @Nullable String studyId, @Nullable String project, @Nullable String table, + DatasetVariable.Type variableType, @Nullable String studyId, @Nullable String sourceURN, @Nullable String tableType) throws NoSuchVariableException { String variableId = DatasetVariable.IdResolver - .encode(datasetId, variableName, variableType, studyId, project, table, tableType); + .encode(datasetId, variableName, variableType, studyId, sourceURN, tableType); if (variableType.equals(DatasetVariable.Type.Harmonized)) { return getHarmonizedDatasetVariable(datasetId, variableId, variableName); @@ -262,23 +258,23 @@ protected Mica.DatasetVariableDto getDatasetVariableDto(@NotNull String datasetI } protected Mica.DatasetVariableDto getDatasetVariableDto(@NotNull String datasetId, @NotNull String variableName, - DatasetVariable.Type variableType, @Nullable OpalTable opalTable) { + DatasetVariable.Type variableType, @Nullable BaseStudyTable studyTable) { return dtos - .asDto(getDatasetVariable(datasetId, variableName, variableType, opalTable), getTaxonomies(), + .asDto(getDatasetVariable(datasetId, variableName, variableType, studyTable), getTaxonomies(), getLocale()); } protected Mica.DatasetVariableDto getDatasetVariableDto(@NotNull String datasetId, @NotNull String variableName, - DatasetVariable.Type variableType, @Nullable String studyId, @Nullable String project, @Nullable String table, + DatasetVariable.Type variableType, @Nullable String studyId, @Nullable String sourceURN, @Nullable String tableType) { - return dtos.asDto(getDatasetVariable(datasetId, variableName, variableType, studyId, project, table, tableType), + return dtos.asDto(getDatasetVariable(datasetId, variableName, variableType, studyId, sourceURN, tableType), getTaxonomies(), getLocale()); } protected Mica.DatasetHarmonizedVariableSummaryDto getDatasetHarmonizedVariableSummaryDto(@NotNull String datasetId, - @NotNull String variableName, DatasetVariable.Type variableType, @Nullable OpalTable opalTable) { + @NotNull String variableName, DatasetVariable.Type variableType, @Nullable BaseStudyTable studyTable) { try { - DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, opalTable); + DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, studyTable); return dtos.asHarmonizedSummaryDto(variable); } catch (NoSuchVariableException e) { return Mica.DatasetHarmonizedVariableSummaryDto.newBuilder().setStatus("").build(); @@ -287,18 +283,18 @@ protected Mica.DatasetHarmonizedVariableSummaryDto getDatasetHarmonizedVariableS protected Mica.DatasetVariableSummaryDto getDatasetVariableSummaryDto(@NotNull String datasetId, - @NotNull String variableName, DatasetVariable.Type variableType, @Nullable OpalTable opalTable) { - DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, opalTable); - return dtos.asSummaryDto(variable, opalTable, true); + @NotNull String variableName, DatasetVariable.Type variableType, @Nullable BaseStudyTable studyTable) { + DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, studyTable); + return dtos.asSummaryDto(variable, studyTable, true); } protected Mica.DatasetVariableSummaryDto getDatasetVariableSummaryDto(@NotNull String datasetId, @NotNull String variableName, DatasetVariable.Type variableType, - @Nullable OpalTable opalTable, + @Nullable BaseStudyTable studyTable, boolean includeSummaries) { - DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, opalTable); - return dtos.asSummaryDto(variable, opalTable, includeSummaries); + DatasetVariable variable = getDatasetVariable(datasetId, variableName, variableType, studyTable); + return dtos.asSummaryDto(variable, studyTable, includeSummaries); } @NotNull @@ -324,7 +320,7 @@ protected void checkVariableSummaryAccess() { private DatasetVariable getHarmonizedDatasetVariable(String datasetId, String variableId, String variableName) { String dataSchemaVariableId = DatasetVariable.IdResolver - .encode(datasetId, variableName, DatasetVariable.Type.Dataschema, null, null, null, null); + .encode(datasetId, variableName, DatasetVariable.Type.Dataschema); DatasetVariable harmonizedDatasetVariable = getDatasetVariableInternal(Indexer.PUBLISHED_HVARIABLE_INDEX, Indexer.HARMONIZED_VARIABLE_TYPE, variableId, variableName); DatasetVariable dataSchemaVariable = getDatasetVariableInternal(Indexer.PUBLISHED_VARIABLE_INDEX, Indexer.VARIABLE_TYPE, diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/collection/PublishedCollectedDatasetVariableResource.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/collection/PublishedCollectedDatasetVariableResource.java index f6af8217b8..6cdbf514cf 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/collection/PublishedCollectedDatasetVariableResource.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/collection/PublishedCollectedDatasetVariableResource.java @@ -63,15 +63,6 @@ public org.obiba.opal.web.model.Math.SummaryStatisticsDto getVariableSummary() { return datasetService.getVariableSummary(getDataset(StudyDataset.class, datasetId), variableName).getWrappedDto(); } - @GET - @Path("/facet") - @Timed - public Search.QueryResultDto getVariableFacet() { - checkDatasetAccess(); - checkVariableSummaryAccess(); - return datasetService.getVariableFacet(getDataset(StudyDataset.class, datasetId), variableName); - } - @GET @Path("/aggregation") @Timed diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvContingencyWriter.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvContingencyWriter.java index 5b922ada9b..8d4aa9e559 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvContingencyWriter.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvContingencyWriter.java @@ -84,10 +84,9 @@ private void writeBody(CSVWriter writer, Mica.DatasetVariableContingencyDto dto) private void writeHeaders(CSVWriter writer, Mica.DatasetVariableContingencyDto c, List terms) { if(c.hasStudyTable()) writer.writeNext(new String[] { String - .format("%s - %s - %s", c.getStudyTable().getProject(), c.getStudyTable().getTable(), - c.getStudyTable().getDceId()) }); + .format("%s - %s", c.getStudyTable().getSourceURN(), c.getStudyTable().getDceId()) }); else if(c.hasHarmonizationStudyTable()) writer.writeNext(new String[] { String - .format("%s - %s", c.getHarmonizationStudyTable().getProject(), c.getHarmonizationStudyTable().getTable())}); + .format("%s", c.getHarmonizationStudyTable().getSourceURN())}); writer.writeNext(concat(concat(Stream.of(""), terms.stream()), Stream.of("Total")).toArray(String[]::new)); } diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvHarmonizationVariablesWriter.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvHarmonizationVariablesWriter.java index b4197e64bb..02c1df3913 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvHarmonizationVariablesWriter.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/CsvHarmonizationVariablesWriter.java @@ -83,11 +83,10 @@ private void writeBody(CSVWriter writer, HarmonizationDataset dataset, final boolean[] found = { false }; variableHarmonization.getDatasetVariableSummariesList().forEach( summary -> { - String id = table instanceof StudyTable ? ((StudyTable) table).getStudyId() : ((HarmonizationStudyTable) table).getStudyId(); + String id = table.getStudyId(); Mica.DatasetVariableResolverDto resolver = summary.getResolver(); if ((resolver.getStudyId().equals(id) - && resolver.getProject().equals(table.getProject()) - && resolver.getTable().equals(table.getTable()))) { + && resolver.getSourceURN().equals(table.getSourceURN()))) { String statusDetail = getAttributeByName(summary, "status_detail", locale); diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedDataschemaDatasetVariableResource.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedDataschemaDatasetVariableResource.java index 45bbf17570..ab922b0e45 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedDataschemaDatasetVariableResource.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedDataschemaDatasetVariableResource.java @@ -20,9 +20,6 @@ import org.obiba.magma.NoSuchValueTableException; import org.obiba.magma.NoSuchVariableException; import org.obiba.mica.core.domain.BaseStudyTable; -import org.obiba.mica.core.domain.HarmonizationStudyTable; -import org.obiba.mica.core.domain.OpalTable; -import org.obiba.mica.core.domain.StudyTable; import org.obiba.mica.dataset.DatasetVariableResource; import org.obiba.mica.dataset.domain.DatasetVariable; import org.obiba.mica.dataset.domain.HarmonizationDataset; @@ -85,7 +82,7 @@ public List getVariableSummaries() { try { String studyId = table.getStudyId(); builder.add(datasetService - .getVariableSummary(dataset, variableName, studyId, table.getProject(), table.getTable()) + .getVariableSummary(dataset, variableName, studyId, table.getSourceURN()) .getWrappedDto()); } catch (NoSuchVariableException | NoSuchValueTableException e) { // case the study has not implemented this dataschema variable @@ -95,27 +92,6 @@ public List getVariableSummaries() { return builder.build(); } - @GET - @Path("/facet") - @Timed - public List getVariableFacets() { - checkDatasetAccess(); - checkVariableSummaryAccess(); - ImmutableList.Builder builder = ImmutableList.builder(); - HarmonizationDataset dataset = getDataset(HarmonizationDataset.class, datasetId); - dataset.getBaseStudyTables().forEach(table -> { - try { - String studyId = table.getStudyId(); - builder.add(datasetService - .getVariableFacet(dataset, variableName, studyId, table.getProject(), table.getTable())); - } catch (NoSuchVariableException | NoSuchValueTableException e) { - // case the study has not implemented this dataschema variable - builder.add(Search.QueryResultDto.newBuilder().setTotalHits(0).build()); - } - }); - return builder.build(); - } - @GET @Path("/aggregation") @Timed @@ -288,18 +264,11 @@ public static class Helper { @Async protected Future getVariableFacet(HarmonizationDataset dataset, String variableName, - OpalTable table) { + BaseStudyTable table) { try { - String studyId = null; - - if (table instanceof StudyTable) { - studyId = ((StudyTable) table).getStudyId(); - } else if (table instanceof HarmonizationStudyTable) { - studyId = ((HarmonizationStudyTable) table).getStudyId(); - } - + String studyId = table.getStudyId(); return new AsyncResult<>(datasetService - .getVariableSummary(dataset, variableName, studyId, table.getProject(), table.getTable()) + .getVariableSummary(dataset, variableName, studyId, table.getSourceURN()) .getWrappedDto()); } catch (Exception e) { log.warn("Unable to retrieve statistics: " + e.getMessage(), e); @@ -309,9 +278,9 @@ protected Future getVariableFacet(HarmonizationDatase @Async protected Future getContingencyTable(HarmonizationDataset dataset, DatasetVariable var, - DatasetVariable crossVar, OpalTable table) { + DatasetVariable crossVar, BaseStudyTable studyTable) { try { - return new AsyncResult<>(datasetService.getContingencyTable(table, var, crossVar)); + return new AsyncResult<>(datasetService.getContingencyTable(studyTable, var, crossVar)); } catch (Exception e) { log.warn("Unable to retrieve contingency statistics: " + e.getMessage(), e); return new AsyncResult<>(null); diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetResource.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetResource.java index d315837740..a9cfa14e22 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetResource.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetResource.java @@ -215,16 +215,17 @@ private Mica.DatasetVariablesHarmonizationSummaryDto getVariableHarmonizationsSu // harmonized variables, extract one column per study table List> harmonizedVariables = Lists.newArrayList(); builder.setTotal(variablesDto.getTotal()).setLimit(variablesDto.getLimit()).setFrom(variablesDto.getFrom()); - String query = "and(%s,eq(datasetId,%s),eq(studyId,%s),eq(populationId,%s),eq(dceId,%s),eq(opalTableType,%s),eq(project,%s),eq(table,%s))"; + + String query = "and(%s,eq(datasetId,%s),eq(studyId,%s),eq(populationId,%s),eq(dceId,%s),eq(opalTableType,%s),eq(sourceURN,%s))"; dataset.getStudyTables().forEach(st -> { builder.addStudyTable(dtos.asDto(st, includeSummaries)); - String rql = String.format(query, namesQuery, id, st.getStudyId(), st.getPopulationUId(), st.getDataCollectionEventUId(), DatasetVariable.OpalTableType.Study, st.getProject(), st.getTable()); + String rql = String.format(query, namesQuery, id, st.getStudyId(), st.getPopulationUId(), st.getDataCollectionEventUId(), DatasetVariable.OpalTableType.Study, st.getSourceURN()); List datasetVariablesInternal = getDatasetVariablesInternal(rql, 0, hvariablesLimit, sort, order, true); harmonizedVariables.add(datasetVariablesInternal.stream().collect(Collectors.toMap(DatasetVariable::getName, v -> v))); }); dataset.getHarmonizationTables().forEach(st -> { builder.addHarmonizationStudyTable(dtos.asDto(st, includeSummaries)); - String rql = String.format(query, namesQuery, id, st.getStudyId(), st.getPopulationUId(), st.getDataCollectionEventUId(), DatasetVariable.OpalTableType.Harmonization, st.getProject(), st.getTable()); + String rql = String.format(query, namesQuery, id, st.getStudyId(), st.getPopulationUId(), st.getDataCollectionEventUId(), DatasetVariable.OpalTableType.Harmonization, st.getSourceURN()); harmonizedVariables.add(getDatasetVariablesInternal(rql, 0, hvariablesLimit, sort, order, true).stream().collect(Collectors.toMap(DatasetVariable::getName, v -> v))); }); diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetVariableResource.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetVariableResource.java index 3e246b9539..b07f5961f9 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetVariableResource.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/harmonization/PublishedHarmonizedDatasetVariableResource.java @@ -21,7 +21,6 @@ import org.obiba.mica.dataset.search.rest.AbstractPublishedDatasetResource; import org.obiba.mica.dataset.service.HarmonizedDatasetService; import org.obiba.mica.web.model.Mica; -import org.obiba.opal.web.model.Search; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Scope; @@ -49,9 +48,7 @@ public class PublishedHarmonizedDatasetVariableResource extends AbstractPublishe private String studyId; - private String project; - - private String table; + private String sourceURN; private String tableType; @@ -62,8 +59,7 @@ public class PublishedHarmonizedDatasetVariableResource extends AbstractPublishe @Timed public Mica.DatasetVariableDto getVariable() { checkDatasetAccess(); - return getDatasetVariableDto(datasetId, variableName, DatasetVariable.Type.Harmonized, studyId, project, table, - tableType); + return getDatasetVariableDto(datasetId, variableName, DatasetVariable.Type.Harmonized, studyId, sourceURN, tableType); } @GET @@ -73,20 +69,10 @@ public org.obiba.opal.web.model.Math.SummaryStatisticsDto getVariableSummary() { checkDatasetAccess(); checkVariableSummaryAccess(); return datasetService - .getVariableSummary(getDataset(HarmonizationDataset.class, datasetId), variableName, studyId, project, table) + .getVariableSummary(getDataset(HarmonizationDataset.class, datasetId), variableName, studyId, sourceURN) .getWrappedDto(); } - @GET - @Path("/facet") - @Timed - public Search.QueryResultDto getVariableFacet() { - checkDatasetAccess(); - checkVariableSummaryAccess(); - return datasetService - .getVariableFacet(getDataset(HarmonizationDataset.class, datasetId), variableName, studyId, project, table); - } - @GET @Path("/aggregation") @Timed @@ -94,20 +80,19 @@ public Mica.DatasetVariableAggregationDto getVariableAggregations(@QueryParam("s checkDatasetAccess(); checkVariableSummaryAccess(); HarmonizationDataset dataset = getDataset(HarmonizationDataset.class, datasetId); - for (BaseStudyTable opalTable : dataset.getBaseStudyTables()) { - String opalTableId = studyId; - if (opalTable.isFor(opalTableId, project, table)) { + for (BaseStudyTable baseTable : dataset.getBaseStudyTables()) { + if (baseTable.isFor(studyId, sourceURN)) { try { - return dtos.asDto(opalTable, - datasetService.getVariableSummary(dataset, variableName, studyId, project, table).getWrappedDto(), withStudySummary).build(); + return dtos.asDto(baseTable, + datasetService.getVariableSummary(dataset, variableName, studyId, sourceURN).getWrappedDto(), withStudySummary).build(); } catch (Exception e) { log.warn("Unable to retrieve statistics: " + e.getMessage(), e); - return dtos.asDto(opalTable, null, withStudySummary).build(); + return dtos.asDto(baseTable, null, withStudySummary).build(); } } } - throw new NoSuchValueTableException(project, table); + throw new NoSuchValueTableException(sourceURN); } @GET @@ -123,20 +108,19 @@ public Mica.DatasetVariableContingencyDto getContingency(@QueryParam("by") Strin private Mica.DatasetVariableContingencyDto getContingencyDto(DatasetVariable var, DatasetVariable crossVar) { HarmonizationDataset dataset = getDataset(HarmonizationDataset.class, datasetId); - for (BaseStudyTable opalTable : dataset.getBaseStudyTables()) { - String opalTableId = studyId; - if (opalTable.isFor(opalTableId, project, table)) { + for (BaseStudyTable baseTable : dataset.getBaseStudyTables()) { + if (baseTable.isFor(studyId, sourceURN)) { try { - return dtos.asContingencyDto(opalTable, var, crossVar, - datasetService.getContingencyTable(opalTable, var, crossVar)).build(); + return dtos.asContingencyDto(baseTable, var, crossVar, + datasetService.getContingencyTable(baseTable, var, crossVar)).build(); } catch (Exception e) { log.warn("Unable to retrieve contingency table: " + e.getMessage(), e); - return dtos.asContingencyDto(opalTable, var, crossVar, null).build(); + return dtos.asContingencyDto(baseTable, var, crossVar, null).build(); } } } - throw new NoSuchValueTableException(project, table); + throw new NoSuchValueTableException(sourceURN); } @GET @@ -183,12 +167,8 @@ public void setStudyId(String studyId) { this.studyId = studyId; } - public void setProject(String project) { - this.project = project; - } - - public void setTable(String table) { - this.table = table; + public void setSourceURN(String sourceURN) { + this.sourceURN = sourceURN; } public void setTableType(String tableType) { @@ -199,10 +179,8 @@ private Pair getContingencyVariables(String cr if (Strings.isNullOrEmpty(crossVariable)) throw new BadRequestException("Cross variable name is required for the contingency table"); - DatasetVariable var = getDatasetVariable(datasetId, variableName, DatasetVariable.Type.Harmonized, studyId, project, - table, tableType); - DatasetVariable crossVar = getDatasetVariable(datasetId, crossVariable, DatasetVariable.Type.Harmonized, studyId, - project, table, tableType); + DatasetVariable var = getDatasetVariable(datasetId, variableName, DatasetVariable.Type.Harmonized, studyId, sourceURN, tableType); + DatasetVariable crossVar = getDatasetVariable(datasetId, crossVariable, DatasetVariable.Type.Harmonized, studyId, sourceURN, tableType); return Pair.create(var, crossVar); } diff --git a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/variable/PublishedDatasetVariableResource.java b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/variable/PublishedDatasetVariableResource.java index 0a590df80f..ae337460a2 100644 --- a/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/variable/PublishedDatasetVariableResource.java +++ b/mica-search/src/main/java/org/obiba/mica/dataset/search/rest/variable/PublishedDatasetVariableResource.java @@ -64,8 +64,7 @@ public DatasetVariableResource getVariable(@PathParam("id") String id, if (!harmonizedDatasetService.isPublished(resolver.getDatasetId())) throw NoSuchDatasetException.withId(resolver.getDatasetId()); resource = applicationContext.getBean(PublishedHarmonizedDatasetVariableResource.class); ((PublishedHarmonizedDatasetVariableResource)resource).setStudyId(resolver.getStudyId()); - ((PublishedHarmonizedDatasetVariableResource)resource).setProject(resolver.getProject()); - ((PublishedHarmonizedDatasetVariableResource)resource).setTable(resolver.getTable()); + ((PublishedHarmonizedDatasetVariableResource)resource).setSourceURN(resolver.getSourceURN()); ((PublishedHarmonizedDatasetVariableResource)resource).setTableType(resolver.getTableType()); ((PublishedHarmonizedDatasetVariableResource)resource).setLocale(locale); break; diff --git a/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSource.java b/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSource.java new file mode 100644 index 0000000000..88aedb999c --- /dev/null +++ b/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSource.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022 OBiBa. All rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.obiba.mica.spi.dataset; + +import org.obiba.magma.ValueTable; +import org.obiba.opal.web.model.Math; +import org.obiba.opal.web.model.Search; + +/** + * Describes the parameters to establish a connection with a Datasource + * and retrieve a ValueTable containing the dataset's variables. + */ +public interface StudyTableSource { + + /** + * Get the {@link ValueTable} implementing the data dictionary and the data values. + * + * @return + */ + ValueTable getValueTable(); + + /** + * Make a facet search, to retrieve contingency table results. + * + * @param query + * @return + */ + Search.QueryResultDto getFacets(Search.QueryTermsDto query); + + /** + * Get a variable summary statistics. + * + * @param variableName + * @return + */ + Math.SummaryStatisticsDto getVariableSummary(String variableName); + + /** + * URN representation of a value table source, indicates the identifier of the value table, in the namespace of the source. + * + * @return + */ + String getURN(); + +} diff --git a/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSourceService.java b/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSourceService.java new file mode 100644 index 0000000000..6d4901c3fc --- /dev/null +++ b/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSourceService.java @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 OBiBa. All rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.obiba.mica.spi.dataset; + +import org.obiba.plugins.spi.ServicePlugin; + +/** + * Makes a {@link StudyTableSource} from a URN. + */ +public interface StudyTableSourceService extends ServicePlugin { + + boolean isFor(String sourceURN); + + StudyTableSource makeSource(String sourceURN); + +} diff --git a/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSourceServiceLoader.java b/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSourceServiceLoader.java new file mode 100644 index 0000000000..f458a6f4c0 --- /dev/null +++ b/mica-spi/src/main/java/org/obiba/mica/spi/dataset/StudyTableSourceServiceLoader.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 OBiBa. All rights reserved. + * + * This program and the accompanying materials + * are made available under the terms of the GNU Public License v3.0. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package org.obiba.mica.spi.dataset; + +import com.google.common.collect.Lists; + +import java.net.URLClassLoader; +import java.util.Collection; +import java.util.ServiceLoader; + +/** + * {@link StudyTableSourceService} loader. + */ +public class StudyTableSourceServiceLoader { + + public static Collection get(URLClassLoader classLoader) { + return Lists.newArrayList(ServiceLoader.load(StudyTableSourceService.class, classLoader).iterator()); + } + +} diff --git a/mica-spi/src/main/java/org/obiba/mica/spi/search/SearchEngineService.java b/mica-spi/src/main/java/org/obiba/mica/spi/search/SearchEngineService.java index fe42507de8..c2479efd9a 100644 --- a/mica-spi/src/main/java/org/obiba/mica/spi/search/SearchEngineService.java +++ b/mica-spi/src/main/java/org/obiba/mica/spi/search/SearchEngineService.java @@ -15,7 +15,7 @@ public interface SearchEngineService extends ServicePlugin { /** - * Provides some Mica configurations usefull for the search engine. + * Provides some Mica configurations useful for the search engine. * * @param configurationProvider */ diff --git a/mica-web-model/src/main/protobuf/Mica.proto b/mica-web-model/src/main/protobuf/Mica.proto index 2b7dcb7e44..fc88385b71 100644 --- a/mica-web-model/src/main/protobuf/Mica.proto +++ b/mica-web-model/src/main/protobuf/Mica.proto @@ -542,8 +542,8 @@ message DatasetDto { extensions 1000 to max; message StudyTableDto { - required string project = 1; - required string table = 2; + optional string project = 1; + optional string table = 2; repeated LocalizedStringDto name = 3; repeated LocalizedStringDto description = 4; @@ -554,11 +554,12 @@ message DatasetDto { optional StudySummaryDto studySummary = 9; optional int32 weight = 10; repeated LocalizedStringDto additionalInformation = 11; + optional string sourceURN = 12; } message HarmonizationTableDto { - required string project = 1; - required string table = 2; + optional string project = 1; + optional string table = 2; repeated LocalizedStringDto name = 3; repeated LocalizedStringDto description = 4; @@ -566,6 +567,7 @@ message DatasetDto { optional StudySummaryDto studySummary = 7; optional int32 weight = 8; repeated LocalizedStringDto additionalInformation = 9; + optional string sourceURN = 10; } } @@ -665,6 +667,7 @@ message DatasetVariableResolverDto { repeated LocalizedStringDto populationName = 29; repeated LocalizedStringDto dceName = 30; optional string entityType = 31; + optional string sourceURN = 32; } message DatasetVariableSummaryDto { diff --git a/mica-webapp/src/main/java/org/obiba/mica/web/controller/VariableController.java b/mica-webapp/src/main/java/org/obiba/mica/web/controller/VariableController.java index 3c7805e9f0..b4a6b7d4f9 100644 --- a/mica-webapp/src/main/java/org/obiba/mica/web/controller/VariableController.java +++ b/mica-webapp/src/main/java/org/obiba/mica/web/controller/VariableController.java @@ -83,7 +83,17 @@ public ModelAndView variable(@PathVariable String id) { break; } - DatasetVariable variable = resolver.getType().equals(DatasetVariable.Type.Harmonized) ? getHarmonizedDatasetVariable(resolver.getDatasetId(), id, variableName) : getDatasetVariable(id, variableName); + DatasetVariable variable; + if (resolver.getType().equals(DatasetVariable.Type.Harmonized)) { + try { + variable = getHarmonizedDatasetVariable(resolver.getDatasetId(), resolver.getId(), variableName); + } catch (NoSuchVariableException e) { + // legacy variable id format + variable = getHarmonizedDatasetVariable(resolver.getDatasetId(), id, variableName); + } + } else + variable = getDatasetVariable(resolver.getId(), variableName); + params.put("variable", variable); params.put("type", resolver.getType().toString()); @@ -163,10 +173,11 @@ private DatasetVariable getDatasetVariableInternal(String indexName, String inde } private DatasetVariable getHarmonizedDatasetVariable(String datasetId, String variableId, String variableName) { - String dataSchemaVariableId = DatasetVariable.IdResolver - .encode(datasetId, variableName, DatasetVariable.Type.Dataschema, null, null, null, null); DatasetVariable harmonizedDatasetVariable = getDatasetVariableInternal(Indexer.PUBLISHED_HVARIABLE_INDEX, Indexer.HARMONIZED_VARIABLE_TYPE, variableId, variableName); + + String dataSchemaVariableId = DatasetVariable.IdResolver + .encode(datasetId, variableName, DatasetVariable.Type.Dataschema); DatasetVariable dataSchemaVariable = getDatasetVariableInternal(Indexer.PUBLISHED_VARIABLE_INDEX, Indexer.VARIABLE_TYPE, dataSchemaVariableId, variableName); @@ -208,13 +219,13 @@ private void addStudyTableParameters(Map params, DatasetVariable if (DatasetVariable.OpalTableType.Study.equals(variable.getOpalTableType())) { Optional studyTable = dataset.getStudyTables().stream().filter(st -> - variable.getStudyId().equals(st.getStudyId()) && variable.getProject().equals(st.getProject()) && variable.getTable().equals(st.getTable())) + variable.getStudyId().equals(st.getStudyId()) && variable.getSourceURN().equals(st.getSourceURN())) .findFirst(); if (studyTable.isPresent()) params.put("opalTable", studyTable.get()); } else { Optional harmoStudyTable = dataset.getHarmonizationTables().stream().filter(st -> - variable.getStudyId().equals(st.getStudyId()) && variable.getProject().equals(st.getProject()) && variable.getTable().equals(st.getTable())) + variable.getStudyId().equals(st.getStudyId()) && variable.getSourceURN().equals(st.getSourceURN())) .findFirst(); if (harmoStudyTable.isPresent()) params.put("opalTable", harmoStudyTable.get());