Merge pull request #1138 from tbouron/fix/application-rest-api
Fix /v1/applications REST endpoints
diff --git a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java
index cfcf5f3..435c6f9 100644
--- a/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java
+++ b/rest/rest-api/src/main/java/org/apache/brooklyn/rest/api/ApplicationApi.java
@@ -135,7 +135,7 @@
required = true)
@PathParam("application") String application);
- /** @deprecated since 1.1 use {@link #createWithFormat(byte[], String)} instead */
+ /** @deprecated since 1.1 use {@link #createWithFormat(String, String)} instead */
@Deprecated
@POST
@Consumes("application/deprecated-yaml-app-spec")
@@ -147,7 +147,8 @@
required = true)
String yaml);
- /** @deprecated since 1.1 use {@link #createFromYamlWithAppId(String, String, String)} instead */
+ /** @deprecated since 1.1 use {@link #createFromYamlAndAppId(String, String)}
+ * or {@link #createFromYamlAndFormatAndAppId(String, String, String)} instead */
@Deprecated
@POST
@Consumes("application/deprecated-yaml-app-spec")
@@ -156,10 +157,11 @@
@ApiParam(name = "applicationSpec", value = "App spec in CAMP YAML format", required = true) String yaml,
@ApiParam(name = "application", value = "Application id", required = true) @PathParam("application") String appId);
- @Beta
@PUT
@Path("/{application}")
- @Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED})
+ @Consumes({"application/x-yaml",
+ // see http://stackoverflow.com/questions/332129/yaml-mime-type
+ "text/yaml", "text/x-yaml", "application/yaml"})
@ApiOperation(
value = "[BETA] Create and start a new application from YAML, with the given id",
response = org.apache.brooklyn.rest.domain.TaskSummary.class
@@ -168,7 +170,23 @@
@ApiResponse(code = 404, message = "Undefined entity or location"),
@ApiResponse(code = 409, message = "Application already registered")
})
- public Response createFromYamlWithAppId(
+ public Response createFromYamlAndAppId(
+ @ApiParam(name = "plan", value = "Plan", required = true) String yaml,
+ @ApiParam(name = "application", value = "Application id", required = true) @PathParam("application") String appId);
+
+ @Beta
+ @PUT
+ @Path("/{application}")
+ @Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED})
+ @ApiOperation(
+ value = "[BETA] Create and start a new application from YAML and format with the given id",
+ response = org.apache.brooklyn.rest.domain.TaskSummary.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Undefined entity or location"),
+ @ApiResponse(code = 409, message = "Application already registered")
+ })
+ public Response createFromYamlAndFormatAndAppId(
@ApiParam(name = "plan", value = "Plan", required = true)
@FormParam("plan") String yaml,
@ApiParam(name = "format", value = "Format eg broolyn-camp", required = false)
@@ -204,6 +222,18 @@
required = true)
@Valid String contents);
+ @POST
+ @Consumes
+ @ApiOperation(
+ value = "Create and start a new application from YAML",
+ response = org.apache.brooklyn.rest.domain.TaskSummary.class
+ )
+ @ApiResponses(value = {
+ @ApiResponse(code = 404, message = "Undefined entity or location")
+ })
+ public Response createFromBytes(
+ @ApiParam(name = "plan", value = "Application plan to deploy", required = true) byte[] plan);
+
@Beta
@POST
@Consumes({MediaType.MULTIPART_FORM_DATA, MediaType.APPLICATION_FORM_URLENCODED})
diff --git a/rest/rest-resources/pom.xml b/rest/rest-resources/pom.xml
index 42753f7..824f961 100644
--- a/rest/rest-resources/pom.xml
+++ b/rest/rest-resources/pom.xml
@@ -207,6 +207,12 @@
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.httpcomponents</groupId>
+ <artifactId>httpmime</artifactId>
+ <version>4.3.1</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
index 925e5f6..e9803182 100644
--- a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
+++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApplicationResource.java
@@ -26,7 +26,7 @@
import java.net.URI;
import java.net.URISyntaxException;
-import java.util.Arrays;
+import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -397,7 +397,12 @@
}
@Override
- public Response createFromYamlWithAppId(String yaml, String format, String appId) {
+ public Response createFromYamlAndAppId(String yaml, String appId) {
+ return createFromYamlAndFormatAndAppId(yaml, null, appId);
+ }
+
+ @Override
+ public Response createFromYamlAndFormatAndAppId(String yaml, String format, String appId) {
return createFromYaml(yaml, format, Optional.of(appId));
}
@@ -505,7 +510,7 @@
@Override
public Response createPoly(byte[] inputToAutodetectType) {
- return createWithFormat(Arrays.toString(inputToAutodetectType), null);
+ return createWithFormat(new String(inputToAutodetectType, StandardCharsets.UTF_8), null);
}
@Override
@@ -515,6 +520,11 @@
}
@Override
+ public Response createFromBytes(byte[] plan) {
+ return createPoly(plan);
+ }
+
+ @Override
public Response createWithFormat(String inputToAutodetectType, String format) {
log.debug("Creating app from autodetecting input");
diff --git a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
index 71dbcc1..bd85306 100644
--- a/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
+++ b/rest/rest-resources/src/test/java/org/apache/brooklyn/rest/resources/ApplicationResourceTest.java
@@ -31,6 +31,7 @@
import java.io.InputStream;
import java.net.URI;
import java.util.Collection;
+import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -87,6 +88,7 @@
import org.apache.brooklyn.util.stream.Streams;
import org.apache.brooklyn.util.text.StringPredicates;
import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.apache.http.HttpHeaders;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
@@ -242,6 +244,25 @@
assertEquals(client().path(appUri).get(ApplicationSummary.class).getSpec().getName(), "simple-app-yaml");
}
+ @Test(dependsOnMethods = { "testDeployApplication", "testLocatedLocation" })
+ public void testDeployApplicationYamlWithFormat() throws Exception {
+ String yaml = "{ name: deploy-format-app-yaml, location: localhost, services: [ { serviceType: "+BasicApplication.class.getCanonicalName()+" } ] }";
+
+ List<Attachment> body = new LinkedList<Attachment>();
+ body.add(new Attachment("plan", "text/plain", yaml));
+ body.add(new Attachment("format", "text/plain", "brooklyn-camp"));
+
+ Response response = client().path("/applications")
+ .header(HttpHeaders.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA)
+ .post(body);
+ assertTrue(response.getStatus()/100 == 2, "response is "+response);
+
+ // Expect app to be running
+ URI appUri = response.getLocation();
+ waitForApplicationToBeRunning(response.getLocation());
+ assertEquals(client().path(appUri).get(ApplicationSummary.class).getSpec().getName(), "deploy-format-app-yaml");
+ }
+
@Test
public void testReferenceCatalogEntity() throws Exception {
getManagementContext().getCatalog().addItems(Strings.lines(