http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/main/webapp/WEB-INF/web.xml ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/main/webapp/WEB-INF/web.xml b/rest/rest-api/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index bab259b..0000000 --- a/rest/rest-api/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,121 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. ---> -<!DOCTYPE web-app PUBLIC - "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" - "http://java.sun.com/dtd/web-app_2_3.dtd" > - -<web-app> - <display-name>Brooklyn REST API v1</display-name> - - <filter> - <filter-name>Brooklyn Request Tagging Filter</filter-name> - <filter-class>org.apache.brooklyn.rest.filter.RequestTaggingFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>Brooklyn Request Tagging Filter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> - - <filter> - <filter-name>Brooklyn Properties Authentication Filter</filter-name> - <filter-class>org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>Brooklyn Properties Authentication Filter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> - - <filter> - <filter-name>Brooklyn Logging Filter</filter-name> - <filter-class>org.apache.brooklyn.rest.filter.LoggingFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>Brooklyn Logging Filter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> - - <filter> - <filter-name>Brooklyn HA Master Filter</filter-name> - <filter-class>org.apache.brooklyn.rest.filter.HaMasterCheckFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>Brooklyn HA Master Filter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> - <filter> - <filter-name>Brooklyn Swagger Bootstrap</filter-name> - <filter-class>org.apache.brooklyn.rest.filter.SwaggerFilter</filter-class> - </filter> - <filter-mapping> - <filter-name>Brooklyn Swagger Bootstrap</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> - -<!-- Brooklyn REST is usually run as a filter so static content can be placed in a webapp - to which this is added; to run as a servlet directly, replace the filter tags - below (after the comment) with the servlet tags (commented out immediately below), - (and do the same for the matching tags at the bottom) - <servlet> - <servlet-name>Brooklyn REST API v1 Servlet</servlet-name> - <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class> - --> - <filter> - <filter-name>Brooklyn REST API v1 Filter</filter-name> - <filter-class>com.sun.jersey.spi.container.servlet.ServletContainer</filter-class> - - <!-- load our REST API jersey resources --> - <init-param> - <param-name>com.sun.jersey.config.property.packages</param-name> - <param-value>io.swagger.jaxrs.listing;com.fasterxml.jackson.jaxrs;org.apache.brooklyn.rest.resources;org.apache.brooklyn.rest.util</param-value> - </init-param> - - <!-- install Jackson and turn on pojo/json serialization (could add org.codehaus.jackson.jaxrs - above but seems cleaner to pull in just the class --> - <init-param> - <param-name>com.sun.jersey.config.property.classnames</param-name> - <param-value>com.fasterxml.jackson.jaxrs.JacksonJsonProvider</param-value> - </init-param> - <init-param> - <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> - <param-value>true</param-value> - </init-param> - - <!-- no need for WADL. of course you can turn it back on it you want. --> - <init-param> - <param-name>com.sun.jersey.config.feature.DisableWADL</param-name> - <param-value>true</param-value> - </init-param> - - </filter> - <filter-mapping> - <filter-name>Brooklyn REST API v1 Filter</filter-name> - <url-pattern>/*</url-pattern> - </filter-mapping> -<!-- Brooklyn REST as a filter above; replace above 5 lines with those commented out below, - to run it as a servlet (see note above) - <load-on-startup>1</load-on-startup> - </servlet> - <servlet-mapping> - <servlet-name>Brooklyn REST API v1 Servlet</servlet-name> - <url-pattern>/*</url-pattern> - </servlet-mapping> ---> - -</web-app>
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java index b2690d6..82bbb43 100644 --- a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java +++ b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/ApplicationSpecTest.java @@ -33,7 +33,7 @@ public class ApplicationSpecTest extends AbstractDomainTest { EntitySpec entitySpec = new EntitySpec("Vanilla Java App", "org.apache.brooklyn.entity.java.VanillaJavaApp", ImmutableMap.of("initialSize", "1", "creationScriptUrl", "http://my.brooklyn.io/storage/foo.sql")); return ApplicationSpec.builder().name("myapp") - .entities(ImmutableSet.of(entitySpec)).locations(ImmutableSet.of("/v1/locations/1")) + .entities(ImmutableSet.of(entitySpec)).locations(ImmutableSet.of("/locations/1")) .build(); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java index 71cb64d..f71399c 100644 --- a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java +++ b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EffectorSummaryTest.java @@ -38,7 +38,7 @@ public class EffectorSummaryTest extends AbstractDomainTest { ImmutableSet.<EffectorSummary.ParameterSummary<?>>of(), "Effector description", ImmutableMap.of( - "self", URI.create("/v1/applications/redis-app/entities/redis-ent/effectors/stop"))); + "self", URI.create("/applications/redis-app/entities/redis-ent/effectors/stop"))); } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java index 2d39cc9..6eb38c8 100644 --- a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java +++ b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/EntitySummaryTest.java @@ -33,10 +33,10 @@ public class EntitySummaryTest extends AbstractDomainTest { @Override protected Object getDomainObject() { Map<String, URI> links = Maps.newLinkedHashMap(); - links.put("self", URI.create("/v1/applications/tesr/entities/zQsqdXzi")); - links.put("catalog", URI.create("/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer")); - links.put("application", URI.create("/v1/applications/tesr")); - links.put("children", URI.create("/v1/applications/tesr/entities/zQsqdXzi/children")); + links.put("self", URI.create("/applications/tesr/entities/zQsqdXzi")); + links.put("catalog", URI.create("/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer")); + links.put("application", URI.create("/applications/tesr")); + links.put("children", URI.create("/applications/tesr/entities/zQsqdXzi/children")); links.put("effectors", URI.create("fixtures/effector-summary-list.json")); links.put("sensors", URI.create("fixtures/sensor-summary-list.json")); links.put("activities", URI.create("fixtures/task-summary-list.json")); http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java index 6279546..8d40e75 100644 --- a/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java +++ b/rest/rest-api/src/test/java/org/apache/brooklyn/rest/domain/LocationSummaryTest.java @@ -33,7 +33,7 @@ public class LocationSummaryTest extends AbstractDomainTest { @Override protected Object getDomainObject() { Map<String, URI> links = Maps.newLinkedHashMap(); - links.put("self", URI.create("/v1/locations/123")); + links.put("self", URI.create("/locations/123")); return new LocationSummary("123", "localhost", "localhost", null, null, links); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/application-list.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/application-list.json b/rest/rest-api/src/test/resources/fixtures/application-list.json index 029cf68..a4e7980 100644 --- a/rest/rest-api/src/test/resources/fixtures/application-list.json +++ b/rest/rest-api/src/test/resources/fixtures/application-list.json @@ -10,12 +10,12 @@ } ], "locations":[ - "/v1/locations/0" + "/locations/0" ] }, "status":"STARTING", "links":{ - "self":"/v1/applications/tesr", + "self":"/applications/tesr", "entities":"fixtures/entity-summary-list.json" } }, @@ -32,11 +32,11 @@ } } ], - "locations":["/v1/locations/1"] + "locations":["/locations/1"] }, "status":"STARTING", "links":{ - "self":"/v1/applications/myapp", + "self":"/applications/myapp", "entities":"fixtures/entity-summary-list.json" } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/application-spec.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/application-spec.json b/rest/rest-api/src/test/resources/fixtures/application-spec.json index 9f042c6..48e9e5f 100644 --- a/rest/rest-api/src/test/resources/fixtures/application-spec.json +++ b/rest/rest-api/src/test/resources/fixtures/application-spec.json @@ -11,6 +11,6 @@ } ], "locations":[ - "/v1/locations/1" + "/locations/1" ] } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/application.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/application.json b/rest/rest-api/src/test/resources/fixtures/application.json index cd6a21a..c7b9aed 100644 --- a/rest/rest-api/src/test/resources/fixtures/application.json +++ b/rest/rest-api/src/test/resources/fixtures/application.json @@ -12,11 +12,11 @@ } } ], - "locations":["/v1/locations/1"] + "locations":["/locations/1"] }, "status":"STARTING", "links":{ - "self":"/v1/applications/myapp", + "self":"/applications/myapp", "entities":"fixtures/entity-summary-list.json" } } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json b/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json index fe2828c..2b7e7c5 100644 --- a/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json +++ b/rest/rest-api/src/test/resources/fixtures/effector-summary-list.json @@ -17,9 +17,9 @@ } ], "links":{ - "self":"/v1/applications/tesr/entities/ZgoDhGQA/effectors/start", - "entity":"/v1/applications/tesr/entities/ZgoDhGQA", - "application":"/v1/applications/tesr" + "self":"/applications/tesr/entities/ZgoDhGQA/effectors/start", + "entity":"/applications/tesr/entities/ZgoDhGQA", + "application":"/applications/tesr" } }, { @@ -28,9 +28,9 @@ "returnType":"void", "parameters":[ ], "links":{ - "self":"/v1/applications/tesr/entities/ZgoDhGQA/effectors/restart", - "entity":"/v1/applications/tesr/entities/ZgoDhGQA", - "application":"/v1/applications/tesr" + "self":"/applications/tesr/entities/ZgoDhGQA/effectors/restart", + "entity":"/applications/tesr/entities/ZgoDhGQA", + "application":"/applications/tesr" } }, { @@ -39,9 +39,9 @@ "returnType":"void", "parameters":[ ], "links":{ - "self":"/v1/applications/tesr/entities/ZgoDhGQA/effectors/stop", - "entity":"/v1/applications/tesr/entities/ZgoDhGQA", - "application":"/v1/applications/tesr" + "self":"/applications/tesr/entities/ZgoDhGQA/effectors/stop", + "entity":"/applications/tesr/entities/ZgoDhGQA", + "application":"/applications/tesr" } } ] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/effector-summary.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/effector-summary.json b/rest/rest-api/src/test/resources/fixtures/effector-summary.json index eda97dd..1ba826d 100644 --- a/rest/rest-api/src/test/resources/fixtures/effector-summary.json +++ b/rest/rest-api/src/test/resources/fixtures/effector-summary.json @@ -4,6 +4,6 @@ "parameters":[], "description":"Effector description", "links":{ - "self":"/v1/applications/redis-app/entities/redis-ent/effectors/stop" + "self":"/applications/redis-app/entities/redis-ent/effectors/stop" } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json b/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json index 6e2dc4e..bf71c36 100644 --- a/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json +++ b/rest/rest-api/src/test/resources/fixtures/entity-summary-list.json @@ -2,10 +2,10 @@ { "type":"org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", "links":{ - "self":"/v1/applications/tesr/entities/zQsqdXzi", - "catalog":"/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", - "application":"/v1/applications/tesr", - "children":"/v1/applications/tesr/entities/zQsqdXzi/entities", + "self":"/applications/tesr/entities/zQsqdXzi", + "catalog":"/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", + "application":"/applications/tesr", + "children":"/applications/tesr/entities/zQsqdXzi/entities", "effectors":"fixtures/effector-summary-list.json", "sensors":"fixtures/sensor-summary-list.json", "activities":"fixtures/task-summary-list.json" http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/entity-summary.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/entity-summary.json b/rest/rest-api/src/test/resources/fixtures/entity-summary.json index 05d2e8f..fe0343c 100644 --- a/rest/rest-api/src/test/resources/fixtures/entity-summary.json +++ b/rest/rest-api/src/test/resources/fixtures/entity-summary.json @@ -2,10 +2,10 @@ "name":"MyTomcat", "type":"org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", "links":{ - "self":"/v1/applications/tesr/entities/zQsqdXzi", - "catalog":"/v1/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", - "application":"/v1/applications/tesr", - "children":"/v1/applications/tesr/entities/zQsqdXzi/children", + "self":"/applications/tesr/entities/zQsqdXzi", + "catalog":"/catalog/entities/org.apache.brooklyn.entity.webapp.tomcat.TomcatServer", + "application":"/applications/tesr", + "children":"/applications/tesr/entities/zQsqdXzi/children", "effectors":"fixtures/effector-summary-list.json", "sensors":"fixtures/sensor-summary-list.json", "activities":"fixtures/task-summary-list.json" http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/location-list.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/location-list.json b/rest/rest-api/src/test/resources/fixtures/location-list.json index c4e05de..6faa0b9 100644 --- a/rest/rest-api/src/test/resources/fixtures/location-list.json +++ b/rest/rest-api/src/test/resources/fixtures/location-list.json @@ -4,7 +4,7 @@ "name":"localhost", "spec":"localhost", "links":{ - "self":"/v1/locations/123" + "self":"/locations/123" } } ] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/location-summary.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/location-summary.json b/rest/rest-api/src/test/resources/fixtures/location-summary.json index d1d0573..57749aa 100644 --- a/rest/rest-api/src/test/resources/fixtures/location-summary.json +++ b/rest/rest-api/src/test/resources/fixtures/location-summary.json @@ -3,6 +3,6 @@ "name":"localhost", "spec":"localhost", "links":{ - "self":"/v1/locations/123" + "self":"/locations/123" } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json b/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json index 6ab457b..10d7ee2 100644 --- a/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json +++ b/rest/rest-api/src/test/resources/fixtures/sensor-summary-list.json @@ -5,8 +5,8 @@ "description":"Service lifecycle state", "links":{ "self":"fixtures/service-state.json", - "application":"/v1/applications/tesr", - "entity":"/v1/applications/tesr/entities/zQsqdXzi" + "application":"/applications/tesr", + "entity":"/applications/tesr/entities/zQsqdXzi" } }, { @@ -15,8 +15,8 @@ "description":"JMX context path", "links":{ "self":"fixtures/service-state.json", - "application":"/v1/applications/tesr", - "entity":"/v1/applications/tesr/entities/zQsqdXzi" + "application":"/applications/tesr", + "entity":"/applications/tesr/entities/zQsqdXzi" } }, { @@ -25,8 +25,8 @@ "description":"Suggested shutdown port", "links":{ "self":"fixtures/service-state.json", - "application":"/v1/applications/tesr", - "entity":"/v1/applications/tesr/entities/zQsqdXzi" + "application":"/applications/tesr", + "entity":"/applications/tesr/entities/zQsqdXzi" } }, { @@ -35,8 +35,8 @@ "description":"Service has been started successfully and is running", "links":{ "self":"fixtures/service-state.json", - "application":"/v1/applications/tesr", - "entity":"/v1/applications/tesr/entities/zQsqdXzi" + "application":"/applications/tesr", + "entity":"/applications/tesr/entities/zQsqdXzi" } } ] \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-api/src/test/resources/fixtures/sensor-summary.json ---------------------------------------------------------------------- diff --git a/rest/rest-api/src/test/resources/fixtures/sensor-summary.json b/rest/rest-api/src/test/resources/fixtures/sensor-summary.json index 0803b37..0ab6c8e 100644 --- a/rest/rest-api/src/test/resources/fixtures/sensor-summary.json +++ b/rest/rest-api/src/test/resources/fixtures/sensor-summary.json @@ -3,6 +3,6 @@ "type":"Integer", "description":"Description", "links":{ - "self":"/v1/applications/redis-app/entities/redis-ent/sensors/redis.uptime" + "self":"/applications/redis-app/entities/redis-ent/sensors/redis.uptime" } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-client/pom.xml ---------------------------------------------------------------------- diff --git a/rest/rest-client/pom.xml b/rest/rest-client/pom.xml index d133518..afb9d65 100644 --- a/rest/rest-client/pom.xml +++ b/rest/rest-client/pom.xml @@ -133,6 +133,13 @@ </dependency> <dependency> <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-rest-resources</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> <artifactId>brooklyn-rest-server</artifactId> <version>${project.version}</version> <classifier>tests</classifier> http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java ---------------------------------------------------------------------- diff --git a/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java b/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java index da3966f..adbdeda 100644 --- a/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java +++ b/rest/rest-client/src/test/java/org/apache/brooklyn/rest/client/BrooklynApiRestClientTest.java @@ -18,7 +18,6 @@ */ package org.apache.brooklyn.rest.client; -import java.net.URISyntaxException; import java.net.URL; import java.nio.charset.Charset; import java.nio.file.Files; @@ -76,7 +75,7 @@ public class BrooklynApiRestClientTest { .securityProvider(TestSecurityProvider.class) .start(); - api = BrooklynApi.newInstance("http://localhost:" + ((NetworkConnector)server.getConnectors()[0]).getPort() + "/", + api = BrooklynApi.newInstance("http://localhost:" + ((NetworkConnector)server.getConnectors()[0]).getPort() + "/v1", TestSecurityProvider.USER, TestSecurityProvider.PASSWORD); } http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/pom.xml ---------------------------------------------------------------------- diff --git a/rest/rest-resources/pom.xml b/rest/rest-resources/pom.xml new file mode 100644 index 0000000..2f171f8 --- /dev/null +++ b/rest/rest-resources/pom.xml @@ -0,0 +1,220 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>brooklyn-rest-resources</artifactId> + <packaging>jar</packaging> + <name>Brooklyn REST Resources</name> + <description> + Brooklyn REST Endpoint (CXF) + </description> + + <parent> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-parent</artifactId> + <version>0.9.0-SNAPSHOT</version><!-- BROOKLYN_VERSION --> + <relativePath>../../parent/pom.xml</relativePath> + </parent> + + <dependencies> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-rest-api</artifactId> + <version>${project.version}</version> + <exclusions> + <exclusion> + <groupId>javax.ws.rs</groupId> + <artifactId>jsr311-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-camp</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.brooklyn.camp</groupId> + <artifactId>camp-base</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-utils-common</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-software-base</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-utils-rest-swagger</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>javax.ws.rs</groupId> + <artifactId>javax.ws.rs-api</artifactId> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-frontend-jaxrs</artifactId> + </dependency> + <dependency> + <groupId>org.yaml</groupId> + <artifactId>snakeyaml</artifactId> + </dependency> + <dependency> + <groupId>org.reflections</groupId> + <artifactId>reflections</artifactId> + </dependency> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + <dependency> + <groupId>com.google.code.findbugs</groupId> + <artifactId>jsr305</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> + </dependency> + <dependency> + <groupId>com.fasterxml.jackson.jaxrs</groupId> + <artifactId>jackson-jaxrs-json-provider</artifactId> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-test-support</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-policy</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-core</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-software-base</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-rest-api</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-locations-jclouds</artifactId> + <version>${project.version}</version> + <scope>test</scope> + <exclusions> + <exclusion> + <groupId>javax.ws.rs</groupId> + <artifactId>jsr311-api</artifactId> + </exclusion> + </exclusions> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-software-nosql</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-software-webapp</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-software-database</artifactId> + <version>${project.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-all</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.testng</groupId> + <artifactId>testng</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-local</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-transports-http-jetty</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.cxf</groupId> + <artifactId>cxf-rt-rs-client</artifactId> + <scope>test</scope> + </dependency> + <dependency> + <groupId>org.apache.brooklyn</groupId> + <artifactId>brooklyn-rt-osgi</artifactId> + <version>${project.version}</version> + <classifier>tests</classifier> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>${basedir}/src/main/resources</directory> + <!-- Required to set values in build-metadata.properties --> + <filtering>true</filtering> + </resource> + <resource> + <directory>${basedir}/src/main/webapp</directory> + </resource> + </resources> + </build> +</project> http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java new file mode 100644 index 0000000..f42548f --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApi.java @@ -0,0 +1,91 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.brooklyn.rest.resources.AbstractBrooklynRestResource; +import org.apache.brooklyn.rest.resources.AccessResource; +import org.apache.brooklyn.rest.resources.ActivityResource; +import org.apache.brooklyn.rest.resources.ApidocResource; +import org.apache.brooklyn.rest.resources.ApplicationResource; +import org.apache.brooklyn.rest.resources.CatalogResource; +import org.apache.brooklyn.rest.resources.EffectorResource; +import org.apache.brooklyn.rest.resources.EntityConfigResource; +import org.apache.brooklyn.rest.resources.EntityResource; +import org.apache.brooklyn.rest.resources.LocationResource; +import org.apache.brooklyn.rest.resources.PolicyConfigResource; +import org.apache.brooklyn.rest.resources.PolicyResource; +import org.apache.brooklyn.rest.resources.ScriptResource; +import org.apache.brooklyn.rest.resources.SensorResource; +import org.apache.brooklyn.rest.resources.ServerResource; +import org.apache.brooklyn.rest.resources.UsageResource; +import org.apache.brooklyn.rest.resources.VersionResource; +import org.apache.brooklyn.rest.util.DefaultExceptionMapper; +import org.apache.brooklyn.rest.util.FormMapProvider; +import org.apache.brooklyn.rest.util.json.BrooklynJacksonJsonProvider; + +import com.google.common.collect.Iterables; + +import io.swagger.jaxrs.listing.SwaggerSerializers; + + +@SuppressWarnings("deprecation") +public class BrooklynRestApi { + + public static Iterable<AbstractBrooklynRestResource> getBrooklynRestResources() { + List<AbstractBrooklynRestResource> resources = new ArrayList<>(); + resources.add(new LocationResource()); + resources.add(new CatalogResource()); + resources.add(new ApplicationResource()); + resources.add(new EntityResource()); + resources.add(new EntityConfigResource()); + resources.add(new SensorResource()); + resources.add(new EffectorResource()); + resources.add(new PolicyResource()); + resources.add(new PolicyConfigResource()); + resources.add(new ActivityResource()); + resources.add(new AccessResource()); + resources.add(new ScriptResource()); + resources.add(new ServerResource()); + resources.add(new UsageResource()); + resources.add(new VersionResource()); + return resources; + } + + public static Iterable<Object> getApidocResources() { + List<Object> resources = new ArrayList<Object>(); + resources.add(new SwaggerSerializers()); + resources.add(new ApidocResource()); + return resources; + } + + public static Iterable<Object> getMiscResources() { + List<Object> resources = new ArrayList<Object>(); + resources.add(new DefaultExceptionMapper()); + resources.add(new BrooklynJacksonJsonProvider()); + resources.add(new FormMapProvider()); + return resources; + } + + public static Iterable<Object> getAllResources() { + return Iterables.concat(getBrooklynRestResources(), getApidocResources(), getMiscResources()); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java new file mode 100644 index 0000000..419715b --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynRestApp.java @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest; + +import java.util.Map; +import java.util.Set; + +import javax.ws.rs.core.Application; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.Sets; + +public class BrooklynRestApp extends Application { + private Set<Object> singletons; + + public BrooklynRestApp() { + singletons = Sets.newHashSet(BrooklynRestApi.getAllResources()); + } + + public BrooklynRestApp singleton(Object singleton) { + singletons.add(singleton); + return this; + } + + @Override + public Set<Object> getSingletons() { + return singletons; + } + + //Uncomment after removing jersey dependencies + //@Override + public Map<String, Object> getProperties() { + return ImmutableMap.<String, Object>of( + // Makes sure that all exceptions are handled by our custom DefaultExceptionMapper + "default.wae.mapper.least.specific", Boolean.TRUE); + } + +} + + http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java new file mode 100644 index 0000000..69342a0 --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/BrooklynWebConfig.java @@ -0,0 +1,164 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest; + +import org.apache.brooklyn.api.location.PortRange; +import org.apache.brooklyn.config.ConfigKey; +import org.apache.brooklyn.config.ConfigMap; +import org.apache.brooklyn.core.config.ConfigKeys; +import org.apache.brooklyn.core.config.ConfigPredicates; +import org.apache.brooklyn.rest.security.provider.DelegatingSecurityProvider; +import org.apache.brooklyn.rest.security.provider.ExplicitUsersSecurityProvider; +import org.apache.brooklyn.rest.security.provider.SecurityProvider; + +public class BrooklynWebConfig { + + public final static String BASE_NAME = "brooklyn.webconsole"; + public final static String BASE_NAME_SECURITY = BASE_NAME+".security"; + + /** + * The session attribute set to indicate the remote address of the HTTP request. + * Corresponds to {@link javax.servlet.http.HttpServletRequest#getRemoteAddr()}. + */ + public static final String REMOTE_ADDRESS_SESSION_ATTRIBUTE = "request.remoteAddress"; + + /** + * The security provider to be loaded by {@link DelegatingSecurityProvider}. + * e.g. <code>brooklyn.webconsole.security.provider=org.apache.brooklyn.rest.security.provider.AnyoneSecurityProvider</code> + * will allow anyone to log in. + */ + public final static ConfigKey<String> SECURITY_PROVIDER_CLASSNAME = ConfigKeys.newStringConfigKey( + BASE_NAME_SECURITY+".provider", "class name of a Brooklyn SecurityProvider", + ExplicitUsersSecurityProvider.class.getCanonicalName()); + public final static ConfigKey<SecurityProvider> SECURITY_PROVIDER_INSTANCE = ConfigKeys.newConfigKey(SecurityProvider.class, + SECURITY_PROVIDER_CLASSNAME.getName()+".internal.instance", "instance of a pre-configured security provider"); + + /** + * Explicitly set the users/passwords, e.g. in brooklyn.properties: + * brooklyn.webconsole.security.users=admin,bob + * brooklyn.webconsole.security.user.admin.password=password + * brooklyn.webconsole.security.user.bob.password=bobspass + */ + public final static ConfigKey<String> USERS = ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY+".users"); + + public final static ConfigKey<String> PASSWORD_FOR_USER(String user) { + return ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY + ".user." + user + ".password"); + } + + public final static ConfigKey<String> SALT_FOR_USER(String user) { + return ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY + ".user." + user + ".salt"); + } + + public final static ConfigKey<String> SHA256_FOR_USER(String user) { + return ConfigKeys.newStringConfigKey(BASE_NAME_SECURITY + ".user." + user + ".sha256"); + } + + public final static ConfigKey<String> LDAP_URL = ConfigKeys.newStringConfigKey( + BASE_NAME_SECURITY+".ldap.url"); + + public final static ConfigKey<String> LDAP_REALM = ConfigKeys.newStringConfigKey( + BASE_NAME_SECURITY+".ldap.realm"); + + public final static ConfigKey<String> LDAP_OU = ConfigKeys.newStringConfigKey( + BASE_NAME_SECURITY+".ldap.ou"); + + public final static ConfigKey<Boolean> HTTPS_REQUIRED = ConfigKeys.newBooleanConfigKey( + BASE_NAME+".security.https.required", + "Whether HTTPS is required; false here can be overridden by CLI option", false); + + public final static ConfigKey<PortRange> WEB_CONSOLE_PORT = ConfigKeys.newConfigKey(PortRange.class, + BASE_NAME+".port", + "Port/range for the web console to listen on; can be overridden by CLI option"); + + public final static ConfigKey<String> KEYSTORE_URL = ConfigKeys.newStringConfigKey( + BASE_NAME+".security.keystore.url", + "Keystore from which to take the certificate to present when running HTTPS; " + + "note that normally the password is also required, and an alias for the certificate if the keystore has more than one"); + + public final static ConfigKey<String> KEYSTORE_PASSWORD = ConfigKeys.newStringConfigKey( + BASE_NAME+".security.keystore.password", + "Password for the "+KEYSTORE_URL); + + public final static ConfigKey<String> KEYSTORE_CERTIFICATE_ALIAS = ConfigKeys.newStringConfigKey( + BASE_NAME+".security.keystore.certificate.alias", + "Alias in "+KEYSTORE_URL+" for the certificate to use; defaults to the first if not supplied"); + + public final static ConfigKey<String> TRANSPORT_PROTOCOLS = ConfigKeys.newStringConfigKey( + BASE_NAME+".security.transport.protocols", + "SSL/TLS protocol versions to use for web console connections", + "TLSv1, TLSv1.1, TLSv1.2"); + + // https://wiki.mozilla.org/Security/Server_Side_TLS (v3.4) + // http://stackoverflow.com/questions/19846020/how-to-map-a-openssls-cipher-list-to-java-jsse + // list created on 05.05.2015, Intermediate config from first link + public final static ConfigKey<String> TRANSPORT_CIPHERS = ConfigKeys.newStringConfigKey( + BASE_NAME+".security.transport.ciphers", + "SSL/TLS cipher suites to use for web console connections", + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384," + + "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_DSS_WITH_AES_128_GCM_SHA256," + + "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384," + + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384," + + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + + "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_128_CBC_SHA," + + "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,TLS_DHE_RSA_WITH_AES_256_CBC_SHA256," + + "TLS_DHE_DSS_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA," + + "TLS_RSA_WITH_AES_128_GCM_SHA256,TLS_RSA_WITH_AES_256_GCM_SHA384," + + "TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256," + + "TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA," + + "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA," + + "TLS_SRP_SHA_WITH_AES_256_CBC_SHA,TLS_DHE_DSS_WITH_AES_256_CBC_SHA256," + + "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA," + + "TLS_SRP_SHA_WITH_AES_128_CBC_SHA,TLS_DHE_DSS_WITH_AES_128_CBC_SHA," + + "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA," + + "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA,TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA," + + "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,TLS_RSA_WITH_CAMELLIA_128_CBC_SHA," + + "TLS_RSA_WITH_3DES_EDE_CBC_SHA," + + // Same as above but with SSL_ prefix, IBM Java compatibility (cipher is independent of protocol) + // https://www-01.ibm.com/support/knowledgecenter/SSYKE2_7.0.0/com.ibm.java.security.component.70.doc/security-component/jsse2Docs/ciphersuites.html + "SSL_ECDHE_RSA_WITH_AES_128_GCM_SHA256,SSL_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256," + + "SSL_ECDHE_RSA_WITH_AES_256_GCM_SHA384,SSL_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384," + + "SSL_DHE_RSA_WITH_AES_128_GCM_SHA256,SSL_DHE_DSS_WITH_AES_128_GCM_SHA256," + + "SSL_DHE_DSS_WITH_AES_256_GCM_SHA384,SSL_DHE_RSA_WITH_AES_256_GCM_SHA384," + + "SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA256,SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256," + + "SSL_ECDHE_RSA_WITH_AES_128_CBC_SHA,SSL_ECDHE_ECDSA_WITH_AES_128_CBC_SHA," + + "SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA384,SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384," + + "SSL_ECDHE_RSA_WITH_AES_256_CBC_SHA,SSL_ECDHE_ECDSA_WITH_AES_256_CBC_SHA," + + "SSL_DHE_RSA_WITH_AES_128_CBC_SHA256,SSL_DHE_RSA_WITH_AES_128_CBC_SHA," + + "SSL_DHE_DSS_WITH_AES_128_CBC_SHA256,SSL_DHE_RSA_WITH_AES_256_CBC_SHA256," + + "SSL_DHE_DSS_WITH_AES_256_CBC_SHA,SSL_DHE_RSA_WITH_AES_256_CBC_SHA," + + "SSL_RSA_WITH_AES_128_GCM_SHA256,SSL_RSA_WITH_AES_256_GCM_SHA384," + + "SSL_RSA_WITH_AES_128_CBC_SHA256,SSL_RSA_WITH_AES_256_CBC_SHA256," + + "SSL_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_AES_256_CBC_SHA," + + "SSL_SRP_SHA_DSS_WITH_AES_256_CBC_SHA,SSL_SRP_SHA_RSA_WITH_AES_256_CBC_SHA," + + "SSL_SRP_SHA_WITH_AES_256_CBC_SHA,SSL_DHE_DSS_WITH_AES_256_CBC_SHA256," + + "SSL_SRP_SHA_DSS_WITH_AES_128_CBC_SHA,SSL_SRP_SHA_RSA_WITH_AES_128_CBC_SHA," + + "SSL_SRP_SHA_WITH_AES_128_CBC_SHA,SSL_DHE_DSS_WITH_AES_128_CBC_SHA," + + "SSL_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA,SSL_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA," + + "SSL_RSA_WITH_CAMELLIA_256_CBC_SHA,SSL_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA," + + "SSL_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA,SSL_RSA_WITH_CAMELLIA_128_CBC_SHA," + + "SSL_RSA_WITH_3DES_EDE_CBC_SHA"); + + public final static boolean hasNoSecurityOptions(ConfigMap config) { + return config.submap(ConfigPredicates.nameStartsWith(BASE_NAME_SECURITY)).isEmpty(); + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java new file mode 100644 index 0000000..13c5cbf --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotCheckResourceFilter.java @@ -0,0 +1,159 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.filter; + +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.util.Set; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ResourceInfo; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.ContextResolver; +import javax.ws.rs.ext.Provider; + +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState; +import org.apache.brooklyn.rest.domain.ApiError; +import org.apache.brooklyn.util.text.Strings; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.ImmutableSet; + +/** + * Checks that if the method or resource class corresponding to a request + * has a {@link HaHotStateRequired} annotation, + * that the server is in that state (and up). + * Requests with {@link #SKIP_CHECK_HEADER} set as a header skip this check. + * <p> + * This follows a different pattern to {@link HaMasterCheckFilter} + * as this needs to know the method being invoked. + */ +@Provider +public class HaHotCheckResourceFilter implements ContainerRequestFilter { + public static final String SKIP_CHECK_HEADER = "Brooklyn-Allow-Non-Master-Access"; + + private static final Logger log = LoggerFactory.getLogger(HaHotCheckResourceFilter.class); + + private static final Set<ManagementNodeState> HOT_STATES = ImmutableSet.of( + ManagementNodeState.MASTER, ManagementNodeState.HOT_STANDBY, ManagementNodeState.HOT_BACKUP); + + // Not quite standards compliant. Should instead be: + // @Context Providers providers + // .... + // ContextResolver<ManagementContext> resolver = providers.getContextResolver(ManagementContext.class, MediaType.WILDCARD_TYPE) + // ManagementContext engine = resolver.get(ManagementContext.class); + @Context + private ContextResolver<ManagementContext> mgmt; + + @Context + private ResourceInfo resourceInfo; + + public HaHotCheckResourceFilter() { + } + + @VisibleForTesting + public HaHotCheckResourceFilter(ContextResolver<ManagementContext> mgmt) { + this.mgmt = mgmt; + } + + private ManagementContext mgmt() { + return mgmt.getContext(ManagementContext.class); + } + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + String problem = lookForProblem(requestContext); + if (Strings.isNonBlank(problem)) { + log.warn("Disallowing web request as "+problem+": "+requestContext.getUriInfo()+"/"+resourceInfo.getResourceMethod()+" (caller should set '"+SKIP_CHECK_HEADER+"' to force)"); + requestContext.abortWith(ApiError.builder() + .message("This request is only permitted against an active hot Brooklyn server") + .errorCode(Response.Status.FORBIDDEN).build().asJsonResponse()); + } + } + + private String lookForProblem(ContainerRequestContext requestContext) { + if (isSkipCheckHeaderSet(requestContext)) + return null; + + if (!isHaHotStateRequired()) + return null; + + String problem = lookForProblemIfServerNotRunning(mgmt()); + if (Strings.isNonBlank(problem)) + return problem; + + if (!isHaHotStatus()) + return "server not in required HA hot state"; + if (isStateNotYetValid()) + return "server not yet completed loading data for required HA hot state"; + + return null; + } + + public static String lookForProblemIfServerNotRunning(ManagementContext mgmt) { + if (mgmt==null) return "no management context available"; + if (!mgmt.isRunning()) return "server no longer running"; + if (!mgmt.isStartupComplete()) return "server not in required startup-completed state"; + return null; + } + + // Maybe there should be a separate state to indicate that we have switched state + // but still haven't finished rebinding. (Previously there was a time delay and an + // isRebinding check, but introducing RebindManager#isAwaitingInitialRebind() seems cleaner.) + private boolean isStateNotYetValid() { + return mgmt().getRebindManager().isAwaitingInitialRebind(); + } + + private boolean isHaHotStateRequired() { + // TODO support super annotations + Method m = resourceInfo.getResourceMethod(); + return getAnnotation(m, HaHotStateRequired.class) != null; + } + + private <T extends Annotation> T getAnnotation(Method m, Class<T> annotation) { + T am = m.getAnnotation(annotation); + if (am != null) { + return am; + } + Class<?> superClass = m.getDeclaringClass(); + T ac = superClass.getAnnotation(annotation); + if (ac != null) { + return ac; + } + // TODO could look in super classes but not needed now, we are in control of where to put the annotation + return null; + } + + private boolean isSkipCheckHeaderSet(ContainerRequestContext requestContext) { + return "true".equalsIgnoreCase(requestContext.getHeaderString(SKIP_CHECK_HEADER)); + } + + private boolean isHaHotStatus() { + ManagementNodeState state = mgmt().getHighAvailabilityManager().getNodeState(); + return HOT_STATES.contains(state); + } + + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java new file mode 100644 index 0000000..babfe43 --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/HaHotStateRequired.java @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.filter; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * When a REST method (or its containing class) is marked with this annotation + * requests to it will fail with a 403 response if the instance is not in MASTER + * mode (or has recently switched or is still rebinding). Guards the method so + * that when it returns the caller can be certain of the response. For example + * if the response is 404, then the resource doesn't exist as opposed to + * not being loaded from persistence store yet. + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.METHOD, ElementType.TYPE}) +@Inherited +public @interface HaHotStateRequired {} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java new file mode 100644 index 0000000..97fdda1 --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/filter/NoCacheFilter.java @@ -0,0 +1,40 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.filter; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.Provider; + +@Provider +public class NoCacheFilter implements ContainerResponseFilter { + + @Override + public void filter(ContainerRequestContext request, ContainerResponseContext response) { + //https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching_FAQ + MultivaluedMap<String, Object> headers = response.getHeaders(); + headers.putSingle(HttpHeaders.CACHE_CONTROL, "no-cache, no-store"); + headers.putSingle("Pragma", "no-cache"); + headers.putSingle(HttpHeaders.EXPIRES, "0"); + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java new file mode 100644 index 0000000..9882eb3 --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AbstractBrooklynRestResource.java @@ -0,0 +1,156 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.resources; + +import javax.annotation.Nullable; +import javax.servlet.ServletContext; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.UriInfo; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.mgmt.ManagementContext; +import org.apache.brooklyn.core.config.render.RendererHints; +import org.apache.brooklyn.core.mgmt.ManagementContextInjectable; +import org.apache.brooklyn.rest.util.BrooklynRestResourceUtils; +import org.apache.brooklyn.rest.util.OsgiCompat; +import org.apache.brooklyn.rest.util.WebResourceUtils; +import org.apache.brooklyn.rest.util.json.BrooklynJacksonJsonProvider; +import org.apache.brooklyn.util.core.task.Tasks; +import org.apache.brooklyn.util.guava.Maybe; +import org.apache.brooklyn.util.time.Duration; + +import com.fasterxml.jackson.databind.ObjectMapper; + +public abstract class AbstractBrooklynRestResource implements ManagementContextInjectable { + + // can be injected by jersey when ManagementContext in not injected manually + // (seems there is no way to make this optional so note it _must_ be injected; + // most of the time that happens for free, but with test framework it doesn't, + // so we have set up a NullServletContextProvider in our tests) + private @Context ServletContext servletContext; + + protected @Context UriInfo ui; + + + private ManagementContext managementContext; + private BrooklynRestResourceUtils brooklynRestResourceUtils; + private ObjectMapper mapper; + + public ManagementContext mgmt() { + return mgmtMaybe().get(); + } + + protected synchronized Maybe<ManagementContext> mgmtMaybe() { + if (managementContext!=null) return Maybe.of(managementContext); + managementContext = OsgiCompat.getManagementContext(servletContext); + if (managementContext!=null) return Maybe.of(managementContext); + + return Maybe.absent("ManagementContext not available for Brooklyn Jersey Resource "+this); + } + + @Override + public void setManagementContext(ManagementContext managementContext) { + if (this.managementContext!=null) { + if (this.managementContext.equals(managementContext)) return; + throw new IllegalStateException("ManagementContext cannot be changed: specified twice for Brooklyn Jersey Resource "+this); + } + this.managementContext = managementContext; + } + + public synchronized BrooklynRestResourceUtils brooklyn() { + if (brooklynRestResourceUtils!=null) return brooklynRestResourceUtils; + brooklynRestResourceUtils = new BrooklynRestResourceUtils(mgmt()); + return brooklynRestResourceUtils; + } + + protected ObjectMapper mapper() { + if (mapper==null) + mapper = BrooklynJacksonJsonProvider.findAnyObjectMapper(servletContext, managementContext); + return mapper; + } + + /** @deprecated since 0.7.0 use {@link #getValueForDisplay(Object, boolean, boolean, Boolean, EntityLocal, Duration)} */ @Deprecated + protected Object getValueForDisplay(Object value, boolean preferJson, boolean isJerseyReturnValue) { + return resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(isJerseyReturnValue).resolve(); + } + + protected RestValueResolver resolving(Object v) { + return new RestValueResolver(v).mapper(mapper()); + } + + public static class RestValueResolver { + final private Object valueToResolve; + private @Nullable ObjectMapper mapper; + private boolean preferJson; + private boolean isJerseyReturnValue; + private @Nullable Boolean raw; + private @Nullable Entity entity; + private @Nullable Duration timeout; + private @Nullable Object rendererHintSource; + + public static RestValueResolver resolving(Object v) { return new RestValueResolver(v); } + + private RestValueResolver(Object v) { valueToResolve = v; } + + public RestValueResolver mapper(ObjectMapper mapper) { this.mapper = mapper; return this; } + + /** whether JSON is the ultimate product; + * main effect here is to give null for null if true, else to give empty string + * <p> + * conversion to JSON for complex types is done subsequently (often by the framework) + * <p> + * default is true */ + public RestValueResolver preferJson(boolean preferJson) { this.preferJson = preferJson; return this; } + /** whether an outermost string must be wrapped in quotes, because a String return object is treated as + * already JSON-encoded + * <p> + * default is false */ + public RestValueResolver asJerseyOutermostReturnValue(boolean asJerseyReturnJson) { + isJerseyReturnValue = asJerseyReturnJson; + return this; + } + public RestValueResolver raw(Boolean raw) { this.raw = raw; return this; } + public RestValueResolver context(Entity entity) { this.entity = entity; return this; } + public RestValueResolver timeout(Duration timeout) { this.timeout = timeout; return this; } + public RestValueResolver renderAs(Object rendererHintSource) { this.rendererHintSource = rendererHintSource; return this; } + + public Object resolve() { + Object valueResult = getImmediateValue(valueToResolve, entity, timeout); + if (valueResult==UNRESOLVED) valueResult = valueToResolve; + if (rendererHintSource!=null && Boolean.FALSE.equals(raw)) { + valueResult = RendererHints.applyDisplayValueHintUnchecked(rendererHintSource, valueResult); + } + return WebResourceUtils.getValueForDisplay(mapper, valueResult, preferJson, isJerseyReturnValue); + } + + private static Object UNRESOLVED = "UNRESOLVED".toCharArray(); + + private static Object getImmediateValue(Object value, @Nullable Entity context, @Nullable Duration timeout) { + return Tasks.resolving(value) + .as(Object.class) + .defaultValue(UNRESOLVED) + .timeout(timeout) + .context(context) + .swallowExceptions() + .get(); + } + + } + +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java new file mode 100644 index 0000000..bb40edf --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/AccessResource.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.resources; + +import javax.ws.rs.core.Response; + +import org.apache.brooklyn.core.mgmt.internal.AccessManager; +import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal; +import org.apache.brooklyn.rest.api.AccessApi; +import org.apache.brooklyn.rest.domain.AccessSummary; +import org.apache.brooklyn.rest.transform.AccessTransformer; + +import com.google.common.annotations.Beta; + +@Beta +public class AccessResource extends AbstractBrooklynRestResource implements AccessApi { + + @Override + public AccessSummary get() { + AccessManager accessManager = ((ManagementContextInternal) mgmt()).getAccessManager(); + return AccessTransformer.accessSummary(accessManager, ui.getBaseUriBuilder()); + } + + @Override + public Response locationProvisioningAllowed(boolean allowed) { + AccessManager accessManager = ((ManagementContextInternal) mgmt()).getAccessManager(); + accessManager.setLocationProvisioningAllowed(allowed); + return Response.status(Response.Status.OK).build(); + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java new file mode 100644 index 0000000..f29827b --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ActivityResource.java @@ -0,0 +1,99 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.resources; + +import java.util.Collections; +import java.util.LinkedList; +import java.util.List; + +import org.apache.brooklyn.api.entity.Entity; +import org.apache.brooklyn.api.mgmt.HasTaskChildren; +import org.apache.brooklyn.api.mgmt.Task; +import org.apache.brooklyn.core.mgmt.BrooklynTaskTags; +import org.apache.brooklyn.core.mgmt.BrooklynTaskTags.WrappedStream; +import org.apache.brooklyn.core.mgmt.entitlement.Entitlements; +import org.apache.brooklyn.rest.api.ActivityApi; +import org.apache.brooklyn.rest.domain.TaskSummary; +import org.apache.brooklyn.rest.transform.TaskTransformer; +import org.apache.brooklyn.rest.util.WebResourceUtils; + +import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; + +public class ActivityResource extends AbstractBrooklynRestResource implements ActivityApi { + + @Override + public TaskSummary get(String taskId) { + Task<?> t = mgmt().getExecutionManager().getTask(taskId); + if (t == null) { + throw WebResourceUtils.notFound("Cannot find task '%s'", taskId); + } + checkEntityEntitled(t); + + return TaskTransformer.fromTask(ui.getBaseUriBuilder()).apply(t); + } + + @Override + public List<TaskSummary> children(String taskId) { + Task<?> t = mgmt().getExecutionManager().getTask(taskId); + if (t == null) { + throw WebResourceUtils.notFound("Cannot find task '%s'", taskId); + } + checkEntityEntitled(t); + + if (!(t instanceof HasTaskChildren)) { + return Collections.emptyList(); + } + return new LinkedList<TaskSummary>(Collections2.transform(Lists.newArrayList(((HasTaskChildren) t).getChildren()), + TaskTransformer.fromTask(ui.getBaseUriBuilder()))); + } + + @Override + public String stream(String taskId, String streamId) { + Task<?> t = mgmt().getExecutionManager().getTask(taskId); + if (t == null) { + throw WebResourceUtils.notFound("Cannot find task '%s'", taskId); + } + checkEntityEntitled(t); + checkStreamEntitled(t, streamId); + + WrappedStream stream = BrooklynTaskTags.stream(t, streamId); + if (stream == null) { + throw WebResourceUtils.notFound("Cannot find stream '%s' in task '%s'", streamId, taskId); + } + return stream.streamContents.get(); + } + + protected void checkEntityEntitled(Task<?> task) { + Entity entity = BrooklynTaskTags.getContextEntity(task); + if (entity != null && !Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) { + throw WebResourceUtils.forbidden("User '%s' is not authorized to see activity of entity '%s'", + Entitlements.getEntitlementContext().user(), entity); + } + } + + protected void checkStreamEntitled(Task<?> task, String streamId) { + Entity entity = BrooklynTaskTags.getContextEntity(task); + Entitlements.TaskAndItem<String> item = new Entitlements.TaskAndItem<String>(task, streamId); + if (entity != null && !Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ACTIVITY_STREAMS, item)) { + throw WebResourceUtils.forbidden("User '%s' is not authorized to see activity stream of entity '%s'", + Entitlements.getEntitlementContext().user(), entity); + } + } +} http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java ---------------------------------------------------------------------- diff --git a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java new file mode 100644 index 0000000..220e4e3 --- /dev/null +++ b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/ApidocResource.java @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.brooklyn.rest.resources; + + +import javax.ws.rs.Path; + +import org.apache.brooklyn.rest.apidoc.ApiListingResource; + +import io.swagger.annotations.Api; + +/** + * @author Ciprian Ciubotariu <cheepe...@gmx.net> + */ +@Api("API Documentation") +@Path("/apidoc") +public class ApidocResource extends ApiListingResource { + +}