diff --git a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java index 806fbb6d818..48b5cf87114 100644 --- a/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java +++ b/opencga-analysis/src/main/java/org/opencb/opencga/analysis/variant/manager/VariantStorageManager.java @@ -49,6 +49,7 @@ import org.opencb.opencga.catalog.managers.StudyManager; import org.opencb.opencga.core.api.ParamConstants; import org.opencb.opencga.core.cellbase.CellBaseValidator; +import org.opencb.opencga.core.common.ExceptionUtils; import org.opencb.opencga.core.common.UriUtils; import org.opencb.opencga.core.config.storage.CellBaseConfiguration; import org.opencb.opencga.core.config.storage.SampleIndexConfiguration; @@ -564,7 +565,10 @@ public OpenCGAResult setCellbaseConfiguration(String project, CellBaseConfi String annotationSaveId, String token) throws CatalogException, StorageEngineException { StopWatch stopwatch = StopWatch.createStarted(); - return secureOperationByProject("configureCellbase", project, new ObjectMap(), token, engine -> { + return secureOperationByProject("configureCellbase", project, new ObjectMap() + .append("cellbaseConfiguration", cellbaseConfiguration) + .append("annotate", annotate) + .append("annotationSaveId", annotationSaveId), token, engine -> { OpenCGAResult result = new OpenCGAResult<>(); result.setResultType(Job.class.getCanonicalName()); result.setResults(new ArrayList<>()); @@ -1225,7 +1229,7 @@ private R secureTool(String toolId, boolean isOperation, ObjectMap params, S throw e; } catch (Exception e) { exception = e; - throw new StorageEngineException("Error executing operation " + toolId, e); + throw new StorageEngineException("Error executing operation '" + toolId + "' : " + e.getMessage(), e); } finally { if (result instanceof DataResult) { auditAttributes.append("dbTime", ((DataResult) result).getTime()); @@ -1237,6 +1241,8 @@ private R secureTool(String toolId, boolean isOperation, ObjectMap params, S if (exception != null) { auditAttributes.append("errorType", exception.getClass()); auditAttributes.append("errorMessage", exception.getMessage()); + auditAttributes.append("errorMessageFull", ExceptionUtils.prettyExceptionMessage(exception, false, true)); + auditAttributes.append("exceptionStackTrace", ExceptionUtils.prettyExceptionStackTrace(exception)); status = new AuditRecord.Status(AuditRecord.Status.Result.ERROR, new Error(-1, exception.getClass().getName(), exception.getMessage())); } else { diff --git a/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java b/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java index 21f5c79fecd..467dabf7b75 100644 --- a/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java +++ b/opencga-core/src/main/java/org/opencb/opencga/core/cellbase/CellBaseValidator.java @@ -1,6 +1,8 @@ package org.opencb.opencga.core.cellbase; +import io.jsonwebtoken.JwtException; import org.apache.commons.lang3.StringUtils; +import org.opencb.biodata.models.variant.avro.VariantAnnotation; import org.opencb.cellbase.client.rest.CellBaseClient; import org.opencb.cellbase.core.config.SpeciesConfiguration; import org.opencb.cellbase.core.config.SpeciesProperties; @@ -8,6 +10,7 @@ import org.opencb.cellbase.core.result.CellBaseDataResponse; import org.opencb.cellbase.core.token.DataAccessTokenManager; import org.opencb.cellbase.core.token.DataAccessTokenSources; +import org.opencb.commons.datastore.core.QueryOptions; import org.opencb.opencga.core.common.VersionUtils; import org.opencb.opencga.core.config.storage.CellBaseConfiguration; import org.slf4j.Logger; @@ -15,6 +18,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -46,6 +50,7 @@ private CellBaseClient newCellBaseClient(CellBaseConfiguration cellBaseConfigura toCellBaseSpeciesName(species), assembly, cellBaseConfiguration.getDataRelease(), + cellBaseConfiguration.getToken(), cellBaseConfiguration.toClientConfiguration()); } @@ -136,7 +141,7 @@ public void validate() throws IOException { validate(false); } - public CellBaseConfiguration validate(boolean autoComplete) throws IOException { + private CellBaseConfiguration validate(boolean autoComplete) throws IOException { CellBaseConfiguration cellBaseConfiguration = getCellBaseConfiguration(); String inputVersion = getVersion(); CellBaseDataResponse species; @@ -189,6 +194,41 @@ public CellBaseConfiguration validate(boolean autoComplete) throws IOException { } } } + String token = getToken(); + if (StringUtils.isEmpty(token)) { + cellBaseConfiguration.setToken(null); + } else { + // Check it's supported + if (!supportsToken(serverVersion)) { + throw new IllegalArgumentException("Token not supported for cellbase " + + "url: '" + getURL() + "'" + + ", version: '" + inputVersion + "'"); + } + + // Check it's an actual token + DataAccessTokenManager tokenManager = new DataAccessTokenManager(); + try { + tokenManager.decode(token); + } catch (JwtException e) { + throw new IllegalArgumentException("Malformed token for cellbase " + + "url: '" + getURL() + "'" + + ", version: '" + inputVersion + + "', species: '" + getSpecies() + + "', assembly: '" + getAssembly() + "'"); + } + + // Check it's a valid token + CellBaseDataResponse response = cellBaseClient.getVariantClient() + .getAnnotationByVariantIds(Collections.singletonList("1:1:N:C"), new QueryOptions(), true); + if (response.firstResult() == null) { + throw new IllegalArgumentException("Invalid token for cellbase " + + "url: '" + getURL() + "'" + + ", version: '" + inputVersion + + "', species: '" + getSpecies() + + "', assembly: '" + getAssembly() + "'"); + } + } + return cellBaseConfiguration; } @@ -231,6 +271,11 @@ public static boolean supportsDataReleaseActiveByDefaultIn(String serverVersion) return VersionUtils.isMinVersion("5.5.0", serverVersion, true); } + public static boolean supportsToken(String serverVersion) { + // Tokens support starts at version 5.4.0 + return VersionUtils.isMinVersion("5.4.0", serverVersion); + } + public String getVersionFromServerMajor() throws IOException { return major(getVersionFromServer()); } diff --git a/opencga-core/src/test/java/org/opencb/opencga/core/cellbase/CellBaseValidatorTest.java b/opencga-core/src/test/java/org/opencb/opencga/core/cellbase/CellBaseValidatorTest.java index 36db80985f0..36026700237 100644 --- a/opencga-core/src/test/java/org/opencb/opencga/core/cellbase/CellBaseValidatorTest.java +++ b/opencga-core/src/test/java/org/opencb/opencga/core/cellbase/CellBaseValidatorTest.java @@ -1,6 +1,8 @@ package org.opencb.opencga.core.cellbase; +import org.apache.commons.lang3.StringUtils; import org.junit.Assert; +import org.junit.Assume; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -70,4 +72,45 @@ public void testNoActiveReleases() throws IOException { thrown.expectMessage("No active data releases found on cellbase"); CellBaseValidator.validate(new CellBaseConfiguration(ParamConstants.CELLBASE_URL, "v5.1", null, null), "mmusculus", "GRCm38", true); } + + @Test + public void testToken() throws IOException { + String token = System.getenv("CELLBASE_HGMD_TOKEN"); + Assume.assumeTrue(StringUtils.isNotEmpty(token)); + CellBaseConfiguration validated = CellBaseValidator.validate(new CellBaseConfiguration(ParamConstants.CELLBASE_URL, "v5.4", null, token), "hsapiens", "grch38", true); + Assert.assertNotNull(validated.getToken()); + } + + @Test + public void testTokenNotSupported() throws IOException { + String token = System.getenv("CELLBASE_HGMD_TOKEN"); + Assume.assumeTrue(StringUtils.isNotEmpty(token)); + thrown.expectMessage("Token not supported"); + CellBaseConfiguration validated = CellBaseValidator.validate(new CellBaseConfiguration(ParamConstants.CELLBASE_URL, "v5.1", null, token), "hsapiens", "grch38", true); + Assert.assertNotNull(validated.getToken()); + } + + @Test + public void testTokenEmpty() throws IOException { + String token = ""; + CellBaseConfiguration validated = CellBaseValidator.validate(new CellBaseConfiguration(ParamConstants.CELLBASE_URL, "v5.1", null, token), "hsapiens", "grch38", true); + Assert.assertNull(validated.getToken()); + } + + @Test + public void testMalformedToken() throws IOException { + thrown.expectMessage("Malformed token for cellbase"); + String token = "MALFORMED_TOKEN"; + CellBaseConfiguration validated = CellBaseValidator.validate(new CellBaseConfiguration(ParamConstants.CELLBASE_URL, "v5.4", null, token), "hsapiens", "grch38", true); + Assert.assertNotNull(validated.getToken()); + } + + @Test + public void testUnsignedToken() throws IOException { + thrown.expectMessage("Invalid token for cellbase"); + String token = "eyJhbGciOiJIUzI1NiJ9.eyJzb3VyY2VzIjp7ImhnbWQiOjkyMjMzNzIwMzY4NTQ3NzU4MDd9LCJ2ZXJzaW9uIjoiMS4wIiwic3ViIjoiWkVUVEEiLCJpYXQiOjE2OTMyMTY5MDd9.invalidsignature"; + CellBaseConfiguration validated = CellBaseValidator.validate(new CellBaseConfiguration(ParamConstants.CELLBASE_URL, "v5.4", null, token), "hsapiens", "grch38", true); + Assert.assertNotNull(validated.getToken()); + } + } \ No newline at end of file