diff --git a/src/main/resources/swagger/agora.json b/src/main/resources/swagger/agora.json index 586e2fcc..ae0cbd7b 100644 --- a/src/main/resources/swagger/agora.json +++ b/src/main/resources/swagger/agora.json @@ -1507,7 +1507,7 @@ "payload": { "type": "string", "description": "Payload of method -- must be in WDL format", - "default": "{ \"methodStoreMethod\": { \"methodNamespace\": \"YOUR_NAMESPACE\", \"methodName\": \"BWA\", \"methodVersion\": 1}}\n" + "default": "{ \"methodRepoMethod\": { \"methodNamespace\": \"YOUR_NAMESPACE\", \"methodName\": \"BWA\", \"methodVersion\": 1}}\n" }, "entityType": { "type": "string", @@ -1556,7 +1556,7 @@ "payload": { "type": "string", "description": "Payload of method -- must be in WDL format. MUST BE REQUESTED EXPLICITLY.", - "default": "{ \"methodStoreMethod\": { \"methodNamespace\": \"YOUR_NAMESPACE\", \"methodName\": \"BWA\", \"methodVersion\": 1}}\n" + "default": "{ \"methodRepoMethod\": { \"methodNamespace\": \"YOUR_NAMESPACE\", \"methodName\": \"BWA\", \"methodVersion\": 1}}\n" }, "entityType": { "type": "string", diff --git a/src/main/resources/swagger/agora.yaml b/src/main/resources/swagger/agora.yaml index a7f678a6..972d3c46 100644 --- a/src/main/resources/swagger/agora.yaml +++ b/src/main/resources/swagger/agora.yaml @@ -1055,7 +1055,7 @@ definitions: type: string description: Payload of method -- must be in WDL format default: > - { "methodStoreMethod": { "methodNamespace": "YOUR_NAMESPACE", + { "methodRepoMethod": { "methodNamespace": "YOUR_NAMESPACE", "methodName": "BWA", "methodVersion": 1}} entityType: type: string @@ -1097,7 +1097,7 @@ definitions: type: string description: Payload of method -- must be in WDL format. MUST BE REQUESTED EXPLICITLY. default: > - { "methodStoreMethod": { "methodNamespace": "YOUR_NAMESPACE", + { "methodRepoMethod": { "methodNamespace": "YOUR_NAMESPACE", "methodName": "BWA", "methodVersion": 1}} entityType: type: string diff --git a/src/main/scala/org/broadinstitute/dsde/agora/server/business/AgoraBusiness.scala b/src/main/scala/org/broadinstitute/dsde/agora/server/business/AgoraBusiness.scala index ed525195..cfa3401c 100644 --- a/src/main/scala/org/broadinstitute/dsde/agora/server/business/AgoraBusiness.scala +++ b/src/main/scala/org/broadinstitute/dsde/agora/server/business/AgoraBusiness.scala @@ -2,7 +2,7 @@ package org.broadinstitute.dsde.agora.server.business import cromwell.parser.BackendType import cromwell.parser.WdlParser.SyntaxError -import org.broadinstitute.dsde.agora.server.exceptions.{AgoraEntityNotFoundException, NamespaceAuthorizationException} +import org.broadinstitute.dsde.agora.server.exceptions.{ValidationException, AgoraException, AgoraEntityNotFoundException, NamespaceAuthorizationException} import org.broadinstitute.dsde.agora.server.webservice.util.{DockerImageReference, DockerHubClient} import cromwell.binding._ @@ -105,13 +105,18 @@ class AgoraBusiness { // Passed basic validation. Now check if (any) docker images that are referenced exist namespace.tasks.foreach { validateDockerImage } case AgoraEntityType.Configuration => - val json = agoraEntity.payload.get.parseJson - val fields = json.asJsObject.getFields("methodStoreMethod") - require(fields.size == 1) - val subFields = fields(0).asJsObject.getFields("methodNamespace", "methodName", "methodVersion") - require(subFields(0).isInstanceOf[JsString]) - require(subFields(1).isInstanceOf[JsString]) - require(subFields(2).isInstanceOf[JsNumber]) + try { + val json = agoraEntity.payload.get.parseJson + val fields = json.asJsObject.getFields("methodRepoMethod") + require(fields.size == 1, "Configuration payload must define at least one field named 'methodRepoMethod'.") + val subFields = fields(0).asJsObject.getFields("methodNamespace", "methodName", "methodVersion") + require(subFields(0).isInstanceOf[JsString], "Configuration methodRepoMethod must include a 'methodNamespace' key with a string value") + require(subFields(1).isInstanceOf[JsString], "Configuration methodRepoMethod must include a 'methodName' key with a string value") + require(subFields(2).isInstanceOf[JsNumber], "Configuration methodRepoMethod must include a 'methodVersion' key with a JSNumber value") + } catch { + case e: IllegalArgumentException => + throw new ValidationException(e) + } } } diff --git a/src/main/scala/org/broadinstitute/dsde/agora/server/exceptions/ValidationException.scala b/src/main/scala/org/broadinstitute/dsde/agora/server/exceptions/ValidationException.scala new file mode 100644 index 00000000..59fba10b --- /dev/null +++ b/src/main/scala/org/broadinstitute/dsde/agora/server/exceptions/ValidationException.scala @@ -0,0 +1,12 @@ +package org.broadinstitute.dsde.agora.server.exceptions + +import com.typesafe.scalalogging.slf4j.LazyLogging + +/** + * Sugar over a generic underlying exception such that it can be handled properly higher in the system. + * @param ex - The underlying exception + */ +class ValidationException(ex: Throwable = null) extends Exception with LazyLogging { + override def getCause: Throwable = ex + override def getMessage: String = ex.getMessage +} diff --git a/src/main/scala/org/broadinstitute/dsde/agora/server/model/AgoraApiJsonSupport.scala b/src/main/scala/org/broadinstitute/dsde/agora/server/model/AgoraApiJsonSupport.scala index ceee35ff..f25a632b 100644 --- a/src/main/scala/org/broadinstitute/dsde/agora/server/model/AgoraApiJsonSupport.scala +++ b/src/main/scala/org/broadinstitute/dsde/agora/server/model/AgoraApiJsonSupport.scala @@ -144,7 +144,7 @@ object AgoraApiJsonSupport extends DefaultJsonProtocol { def methodRef(payload: String): AgoraEntity = { val json = payload.parseJson - val refJson = json.asJsObject.fields("methodStoreMethod").asJsObject + val refJson = json.asJsObject.fields("methodRepoMethod").asJsObject val namespace = refJson.fields("methodNamespace").convertTo[String] val name = refJson.fields("methodName").convertTo[String] val snapshotId = refJson.fields("methodVersion").convertTo[Int] diff --git a/src/main/scala/org/broadinstitute/dsde/agora/server/webservice/PerRequest.scala b/src/main/scala/org/broadinstitute/dsde/agora/server/webservice/PerRequest.scala index 616bec7a..f0e26c09 100644 --- a/src/main/scala/org/broadinstitute/dsde/agora/server/webservice/PerRequest.scala +++ b/src/main/scala/org/broadinstitute/dsde/agora/server/webservice/PerRequest.scala @@ -80,6 +80,9 @@ trait PerRequest extends Actor { case e: SyntaxError => r.complete(BadRequest, AgoraException(e.getMessage, e.getCause, BadRequest)) Stop + case e: ValidationException => + r.complete(BadRequest,AgoraException(e.getMessage, e.getCause, BadRequest)) + Stop case e: Throwable => r.complete(InternalServerError, AgoraException(e.getMessage, e.getCause, InternalServerError)) Stop diff --git a/src/test/scala/org/broadinstitute/dsde/agora/server/AgoraTestData.scala b/src/test/scala/org/broadinstitute/dsde/agora/server/AgoraTestData.scala index 50340e41..b0487a7e 100644 --- a/src/test/scala/org/broadinstitute/dsde/agora/server/AgoraTestData.scala +++ b/src/test/scala/org/broadinstitute/dsde/agora/server/AgoraTestData.scala @@ -171,7 +171,7 @@ object AgoraTestData { | """.stripMargin) val taskConfigPayload = Option( s"""{ - | "methodStoreMethod": { + | "methodRepoMethod": { | "methodNamespace": "${namespace1.get}", | "methodName": "${name1.get}", | "methodVersion": 1 @@ -195,7 +195,7 @@ object AgoraTestData { |}""".stripMargin) val taskConfigPayload2 = Option( s"""{ - | "methodStoreMethod": { + | "methodRepoMethod": { | "methodNamespace": "${namespace2.get}", | "methodName": "${name1.get}", | "methodVersion": 1 @@ -220,7 +220,7 @@ object AgoraTestData { val taskConfigPayload3 = Option( s"""{ - | "methodStoreMethod": { + | "methodRepoMethod": { | "methodNamespace": "${namespace3.get}", | "methodName": "${name3.get}", | "methodVersion": 1