http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java deleted file mode 100644 index 132f0d2..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/LocationResource.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import java.net.URI; -import java.util.Comparator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.ws.rs.core.Response; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import org.apache.brooklyn.catalog.CatalogItem; -import brooklyn.catalog.internal.CatalogUtils; -import brooklyn.location.Location; -import brooklyn.location.LocationDefinition; -import brooklyn.location.basic.LocationConfigKeys; -import brooklyn.rest.api.LocationApi; -import brooklyn.rest.domain.LocationSpec; -import brooklyn.rest.domain.LocationSummary; -import brooklyn.rest.filter.HaHotStateRequired; -import brooklyn.rest.transform.LocationTransformer; -import brooklyn.rest.transform.LocationTransformer.LocationDetailLevel; -import brooklyn.rest.util.EntityLocationUtils; -import brooklyn.rest.util.WebResourceUtils; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.text.NaturalOrderComparator; -import brooklyn.util.text.Strings; - -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Sets; - -@SuppressWarnings("deprecation") -@HaHotStateRequired -public class LocationResource extends AbstractBrooklynRestResource implements LocationApi { - - private static final Logger log = LoggerFactory.getLogger(LocationResource.class); - - private final Set<String> specsWarnedOnException = Sets.newConcurrentHashSet(); - - @Override - public List<LocationSummary> list() { - Function<LocationDefinition, LocationSummary> transformer = new Function<LocationDefinition, LocationSummary>() { - @Override - public LocationSummary apply(LocationDefinition l) { - try { - return LocationTransformer.newInstance(mgmt(), l, LocationDetailLevel.LOCAL_EXCLUDING_SECRET); - } catch (Exception e) { - Exceptions.propagateIfFatal(e); - String spec = l.getSpec(); - if (spec == null || specsWarnedOnException.add(spec)) { - log.warn("Unable to find details of location {} in REST call to list (ignoring location): {}", l, e); - if (log.isDebugEnabled()) log.debug("Error details for location " + l, e); - } else { - if (log.isTraceEnabled()) - log.trace("Unable again to find details of location {} in REST call to list (ignoring location): {}", l, e); - } - return null; - } - } - }; - return FluentIterable.from(brooklyn().getLocationRegistry().getDefinedLocations().values()) - .transform(transformer) - .filter(LocationSummary.class) - .toSortedList(nameOrSpecComparator()); - } - - private static NaturalOrderComparator COMPARATOR = new NaturalOrderComparator(); - private static Comparator<LocationSummary> nameOrSpecComparator() { - return new Comparator<LocationSummary>() { - @Override - public int compare(LocationSummary o1, LocationSummary o2) { - return COMPARATOR.compare(getNameOrSpec(o1).toLowerCase(), getNameOrSpec(o2).toLowerCase()); - } - }; - } - private static String getNameOrSpec(LocationSummary o) { - if (Strings.isNonBlank(o.getName())) return o.getName(); - if (Strings.isNonBlank(o.getSpec())) return o.getSpec(); - return o.getId(); - } - - // this is here to support the web GUI's circles - @Override - public Map<String,Map<String,Object>> getLocatedLocations() { - Map<String,Map<String,Object>> result = new LinkedHashMap<String,Map<String,Object>>(); - Map<Location, Integer> counts = new EntityLocationUtils(mgmt()).countLeafEntitiesByLocatedLocations(); - for (Map.Entry<Location,Integer> count: counts.entrySet()) { - Location l = count.getKey(); - Map<String,Object> m = MutableMap.<String,Object>of( - "id", l.getId(), - "name", l.getDisplayName(), - "leafEntityCount", count.getValue(), - "latitude", l.getConfig(LocationConfigKeys.LATITUDE), - "longitude", l.getConfig(LocationConfigKeys.LONGITUDE) - ); - result.put(l.getId(), m); - } - return result; - } - - /** @deprecated since 0.7.0; REST call now handled by below (optional query parameter added) */ - public LocationSummary get(String locationId) { - return get(locationId, false); - } - - @Override - public LocationSummary get(String locationId, String fullConfig) { - return get(locationId, Boolean.valueOf(fullConfig)); - } - - public LocationSummary get(String locationId, boolean fullConfig) { - LocationDetailLevel configLevel = fullConfig ? LocationDetailLevel.FULL_EXCLUDING_SECRET : LocationDetailLevel.LOCAL_EXCLUDING_SECRET; - Location l1 = mgmt().getLocationManager().getLocation(locationId); - if (l1!=null) { - return LocationTransformer.newInstance(mgmt(), l1, configLevel); - } - - LocationDefinition l2 = brooklyn().getLocationRegistry().getDefinedLocationById(locationId); - if (l2==null) throw WebResourceUtils.notFound("No location matching %s", locationId); - return LocationTransformer.newInstance(mgmt(), l2, configLevel); - } - - @Override - public Response create(LocationSpec locationSpec) { - String name = locationSpec.getName(); - ImmutableList.Builder<String> yaml = ImmutableList.<String>builder().add( - "brooklyn.catalog:", - " symbolicName: "+name, - "", - "brooklyn.locations:", - "- type: "+locationSpec.getSpec()); - if (locationSpec.getConfig().size() > 0) { - yaml.add(" brooklyn.config:"); - for (Map.Entry<String, ?> entry : locationSpec.getConfig().entrySet()) { - yaml.add(" "+entry.getKey()+": "+entry.getValue()); - } - } - - brooklyn().getCatalog().addItems(Joiner.on("\n").join(yaml.build())); - LocationDefinition l = brooklyn().getLocationRegistry().getDefinedLocationByName(name); - return Response.created(URI.create(name)) - .entity(LocationTransformer.newInstance(mgmt(), l, LocationDetailLevel.LOCAL_EXCLUDING_SECRET)) - .build(); - } - - @Override - @Deprecated - public void delete(String locationId) { - // TODO make all locations be part of the catalog, then flip the JS GUI to use catalog api - if (deleteAllVersions(locationId)>0) return; - throw WebResourceUtils.notFound("No catalog item location matching %s; only catalog item locations can be deleted", locationId); - } - - private int deleteAllVersions(String locationId) { - CatalogItem<?, ?> item = CatalogUtils.getCatalogItemOptionalVersion(mgmt(), locationId); - if (item==null) return 0; - brooklyn().getCatalog().deleteCatalogItem(item.getSymbolicName(), item.getVersion()); - return 1 + deleteAllVersions(locationId); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java deleted file mode 100644 index 471cd22..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyConfigResource.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.core.Response; - -import brooklyn.basic.BrooklynObjectInternal; -import brooklyn.config.ConfigKey; -import brooklyn.entity.Entity; -import brooklyn.entity.basic.EntityLocal; -import brooklyn.management.entitlement.Entitlements; -import brooklyn.policy.Policy; -import brooklyn.rest.api.PolicyConfigApi; -import brooklyn.rest.domain.PolicyConfigSummary; -import brooklyn.rest.filter.HaHotStateRequired; -import brooklyn.rest.transform.PolicyTransformer; -import brooklyn.rest.util.BrooklynRestResourceUtils; -import brooklyn.rest.util.WebResourceUtils; -import brooklyn.util.flags.TypeCoercions; - -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -@HaHotStateRequired -public class PolicyConfigResource extends AbstractBrooklynRestResource implements PolicyConfigApi { - - @Override - public List<PolicyConfigSummary> list( - final String application, final String entityToken, final String policyToken) { - EntityLocal entity = brooklyn().getEntity(application, entityToken); - Policy policy = brooklyn().getPolicy(entity, policyToken); - - List<PolicyConfigSummary> result = Lists.newArrayList(); - for (ConfigKey<?> key : policy.getPolicyType().getConfigKeys()) { - result.add(PolicyTransformer.policyConfigSummary(brooklyn(), entity, policy, key)); - } - return result; - } - - // TODO support parameters ?show=value,summary&name=xxx &format={string,json,xml} - // (and in sensors class) - @Override - public Map<String, Object> batchConfigRead(String application, String entityToken, String policyToken) { - // TODO: add test - Policy policy = brooklyn().getPolicy(application, entityToken, policyToken); - Map<String, Object> source = ((BrooklynObjectInternal)policy).config().getBag().getAllConfig(); - Map<String, Object> result = Maps.newLinkedHashMap(); - for (Map.Entry<String, Object> ek : source.entrySet()) { - result.put(ek.getKey(), getStringValueForDisplay(brooklyn(), policy, ek.getValue())); - } - return result; - } - - @Override - public String get(String application, String entityToken, String policyToken, String configKeyName) { - Policy policy = brooklyn().getPolicy(application, entityToken, policyToken); - ConfigKey<?> ck = policy.getPolicyType().getConfigKey(configKeyName); - if (ck == null) throw WebResourceUtils.notFound("Cannot find config key '%s' in policy '%s' of entity '%s'", configKeyName, policy, entityToken); - - return getStringValueForDisplay(brooklyn(), policy, policy.getConfig(ck)); - } - - @Override - @Deprecated - public Response set(String application, String entityToken, String policyToken, String configKeyName, String value) { - return set(application, entityToken, policyToken, configKeyName, (Object) value); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Response set(String application, String entityToken, String policyToken, String configKeyName, Object value) { - Entity entity = brooklyn().getEntity(application, entityToken); - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) { - throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'", - Entitlements.getEntitlementContext().user(), entity); - } - - Policy policy = brooklyn().getPolicy(application, entityToken, policyToken); - ConfigKey<?> ck = policy.getPolicyType().getConfigKey(configKeyName); - if (ck == null) throw WebResourceUtils.notFound("Cannot find config key '%s' in policy '%s' of entity '%s'", configKeyName, policy, entityToken); - - policy.config().set((ConfigKey) ck, TypeCoercions.coerce(value, ck.getTypeToken())); - - return Response.status(Response.Status.OK).build(); - } - - public static String getStringValueForDisplay(BrooklynRestResourceUtils utils, Policy policy, Object value) { - return utils.getStringValueForDisplay(value); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java deleted file mode 100644 index c677bf5..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/PolicyResource.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import java.util.List; -import java.util.Map; - -import javax.ws.rs.core.Response; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.Entity; -import brooklyn.entity.basic.EntityLocal; -import brooklyn.policy.Policy; -import brooklyn.policy.PolicySpec; -import brooklyn.policy.basic.Policies; -import brooklyn.rest.api.PolicyApi; -import brooklyn.rest.domain.PolicySummary; -import brooklyn.rest.domain.Status; -import brooklyn.rest.domain.SummaryComparators; -import brooklyn.rest.filter.HaHotStateRequired; -import brooklyn.rest.transform.ApplicationTransformer; -import brooklyn.rest.transform.PolicyTransformer; -import brooklyn.rest.util.WebResourceUtils; -import brooklyn.util.exceptions.Exceptions; - -import com.google.common.base.Function; -import com.google.common.collect.FluentIterable; -import com.google.common.collect.Maps; - -@HaHotStateRequired -public class PolicyResource extends AbstractBrooklynRestResource implements PolicyApi { - - private static final Logger log = LoggerFactory.getLogger(PolicyResource.class); - - @Override - public List<PolicySummary> list( final String application, final String entityToken) { - final Entity entity = brooklyn().getEntity(application, entityToken); - return FluentIterable.from(entity.getPolicies()) - .transform(new Function<Policy, PolicySummary>() { - @Override - public PolicySummary apply(Policy policy) { - return PolicyTransformer.policySummary(entity, policy); - } - }) - .toSortedList(SummaryComparators.nameComparator()); - } - - // TODO support parameters ?show=value,summary&name=xxx - // (and in sensors class) - @Override - public Map<String, Boolean> batchConfigRead( String application, String entityToken) { - // TODO: add test - EntityLocal entity = brooklyn().getEntity(application, entityToken); - Map<String, Boolean> result = Maps.newLinkedHashMap(); - for (Policy p : entity.getPolicies()) { - result.put(p.getId(), !p.isSuspended()); - } - return result; - } - - // TODO would like to make 'config' arg optional but jersey complains if we do - @SuppressWarnings("unchecked") - @Override - public PolicySummary addPolicy( String application,String entityToken, String policyTypeName, - Map<String, String> config) { - EntityLocal entity = brooklyn().getEntity(application, entityToken); - Class<? extends Policy> policyType; - try { - policyType = (Class<? extends Policy>) Class.forName(policyTypeName); - } catch (ClassNotFoundException e) { - throw WebResourceUtils.badRequest("No policy with type %s found", policyTypeName); - } catch (ClassCastException e) { - throw WebResourceUtils.badRequest("No policy with type %s found", policyTypeName); - } catch (Exception e) { - throw Exceptions.propagate(e); - } - - Policy policy = entity.addPolicy(PolicySpec.create(policyType).configure(config)); - log.debug("REST API added policy " + policy + " to " + entity); - - return PolicyTransformer.policySummary(entity, policy); - } - - @Override - public Status getStatus(String application, String entityToken, String policyId) { - Policy policy = brooklyn().getPolicy(application, entityToken, policyId); - return ApplicationTransformer.statusFromLifecycle(Policies.getPolicyStatus(policy)); - } - - @Override - public Response start( String application, String entityToken, String policyId) { - Policy policy = brooklyn().getPolicy(application, entityToken, policyId); - - policy.resume(); - return Response.status(Response.Status.NO_CONTENT).build(); - } - - @Override - public Response stop(String application, String entityToken, String policyId) { - Policy policy = brooklyn().getPolicy(application, entityToken, policyId); - - policy.suspend(); - return Response.status(Response.Status.NO_CONTENT).build(); - } - - @Override - public Response destroy(String application, String entityToken, String policyToken) { - EntityLocal entity = brooklyn().getEntity(application, entityToken); - Policy policy = brooklyn().getPolicy(entity, policyToken); - - policy.suspend(); - entity.removePolicy(policy); - return Response.status(Response.Status.NO_CONTENT).build(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/ScriptResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/ScriptResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/ScriptResource.java deleted file mode 100644 index 9a8cef9..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/ScriptResource.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import brooklyn.rest.api.ScriptApi; -import brooklyn.rest.domain.ScriptExecutionSummary; -import brooklyn.util.stream.ThreadLocalPrintStream; -import brooklyn.util.stream.ThreadLocalPrintStream.OutputCapturingContext; -import groovy.lang.Binding; -import groovy.lang.GroovyShell; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; -import java.util.LinkedHashMap; -import java.util.Map; - -public class ScriptResource extends AbstractBrooklynRestResource implements ScriptApi { - - private static final Logger log = LoggerFactory.getLogger(ScriptResource.class); - - public static final String USER_DATA_MAP_SESSION_ATTRIBUTE = "brooklyn.script.groovy.user.data"; - public static final String USER_LAST_VALUE_SESSION_ATTRIBUTE = "brooklyn.script.groovy.user.last"; - - @SuppressWarnings("rawtypes") - @Override - public ScriptExecutionSummary groovy(HttpServletRequest request, String script) { - log.info("Web REST executing user-supplied script"); - if (log.isDebugEnabled()) { - log.debug("Web REST user-supplied script contents:\n"+script); - } - - Binding binding = new Binding(); - binding.setVariable("mgmt", mgmt()); - - HttpSession session = request!=null ? request.getSession() : null; - if (session!=null) { - Map data = (Map) session.getAttribute(USER_DATA_MAP_SESSION_ATTRIBUTE); - if (data==null) { - data = new LinkedHashMap(); - session.setAttribute(USER_DATA_MAP_SESSION_ATTRIBUTE, data); - } - binding.setVariable("data", data); - - Object last = session.getAttribute(USER_LAST_VALUE_SESSION_ATTRIBUTE); - binding.setVariable("last", last); - } - - GroovyShell shell = new GroovyShell(binding); - - OutputCapturingContext stdout = ThreadLocalPrintStream.stdout().captureTee(); - OutputCapturingContext stderr = ThreadLocalPrintStream.stderr().captureTee(); - - Object value = null; - Throwable problem = null; - try { - value = shell.evaluate(script); - if (session!=null) - session.setAttribute(USER_LAST_VALUE_SESSION_ATTRIBUTE, value); - } catch (Throwable t) { - log.warn("Problem in user-supplied script: "+t, t); - problem = t; - } finally { - stdout.end(); - stderr.end(); - } - - if (log.isDebugEnabled()) { - log.debug("Web REST user-supplied script completed:\n"+ - (value!=null ? "RESULT: "+value.toString()+"\n" : "")+ - (problem!=null ? "ERROR: "+problem.toString()+"\n" : "")+ - (!stdout.isEmpty() ? "STDOUT: "+stdout.toString()+"\n" : "")+ - (!stderr.isEmpty() ? "STDERR: "+stderr.toString()+"\n" : "")); - } - - // call toString on the result, in case it is not serializable - return new ScriptExecutionSummary( - value!=null ? value.toString() : null, - problem!=null ? problem.toString() : null, - stdout.toString(), stderr.toString()); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java deleted file mode 100644 index 05bf73e..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/SensorResource.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import static com.google.common.collect.Iterables.filter; -import static com.google.common.collect.Iterables.transform; - -import java.util.List; -import java.util.Map; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.basic.EntityInternal; -import brooklyn.entity.basic.EntityLocal; -import brooklyn.event.AttributeSensor; -import brooklyn.event.Sensor; -import brooklyn.event.basic.BasicAttributeSensor; -import brooklyn.management.entitlement.Entitlements; -import brooklyn.rest.api.SensorApi; -import brooklyn.rest.domain.SensorSummary; -import brooklyn.rest.filter.HaHotStateRequired; -import brooklyn.rest.transform.SensorTransformer; -import brooklyn.rest.util.WebResourceUtils; -import brooklyn.util.task.ValueResolver; -import brooklyn.util.text.Strings; -import brooklyn.util.time.Duration; - -import com.google.common.base.Function; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; - -@HaHotStateRequired -public class SensorResource extends AbstractBrooklynRestResource implements SensorApi { - - private static final Logger log = LoggerFactory.getLogger(SensorResource.class); - - @SuppressWarnings("rawtypes") - @Override - public List<SensorSummary> list(final String application, final String entityToken) { - final EntityLocal entity = brooklyn().getEntity(application, entityToken); - - return Lists.newArrayList(transform(filter(entity.getEntityType().getSensors(), AttributeSensor.class), - new Function<AttributeSensor, SensorSummary>() { - @Override - public SensorSummary apply(AttributeSensor sensor) { - return SensorTransformer.sensorSummary(entity, sensor); - } - })); - } - - @Override - public Map<String, Object> batchSensorRead(final String application, final String entityToken, final Boolean raw) { - final EntityLocal entity = brooklyn().getEntity(application, entityToken); - Map<String, Object> sensorMap = Maps.newHashMap(); - @SuppressWarnings("rawtypes") - Iterable<AttributeSensor> sensors = filter(entity.getEntityType().getSensors(), AttributeSensor.class); - - for (AttributeSensor<?> sensor : sensors) { - Object value = entity.getAttribute(findSensor(entity, sensor.getName())); - sensorMap.put(sensor.getName(), - resolving(value).preferJson(true).asJerseyOutermostReturnValue(false).raw(raw).context(entity).timeout(Duration.ZERO).renderAs(sensor).resolve()); - } - return sensorMap; - } - - protected Object get(boolean preferJson, String application, String entityToken, String sensorName, Boolean raw) { - final EntityLocal entity = brooklyn().getEntity(application, entityToken); - AttributeSensor<?> sensor = findSensor(entity, sensorName); - Object value = entity.getAttribute(sensor); - return resolving(value).preferJson(preferJson).asJerseyOutermostReturnValue(true).raw(raw).context(entity).timeout(ValueResolver.PRETTY_QUICK_WAIT).renderAs(sensor).resolve(); - } - - @Override - public String getPlain(String application, String entityToken, String sensorName, final Boolean raw) { - return (String) get(false, application, entityToken, sensorName, raw); - } - - @Override - public Object get(final String application, final String entityToken, String sensorName, final Boolean raw) { - return get(true, application, entityToken, sensorName, raw); - } - - private AttributeSensor<?> findSensor(EntityLocal entity, String name) { - Sensor<?> s = entity.getEntityType().getSensor(name); - if (s instanceof AttributeSensor) return (AttributeSensor<?>) s; - return new BasicAttributeSensor<Object>(Object.class, name); - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public void setFromMap(String application, String entityToken, Map newValues) { - final EntityLocal entity = brooklyn().getEntity(application, entityToken); - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) { - throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'", - Entitlements.getEntitlementContext().user(), entity); - } - - if (log.isDebugEnabled()) - log.debug("REST user "+Entitlements.getEntitlementContext()+" setting sensors "+newValues); - for (Object entry: newValues.entrySet()) { - String sensorName = Strings.toString(((Map.Entry)entry).getKey()); - Object newValue = ((Map.Entry)entry).getValue(); - - AttributeSensor sensor = findSensor(entity, sensorName); - entity.setAttribute(sensor, newValue); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - @Override - public void set(String application, String entityToken, String sensorName, Object newValue) { - final EntityLocal entity = brooklyn().getEntity(application, entityToken); - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) { - throw WebResourceUtils.unauthorized("User '%s' is not authorized to modify entity '%s'", - Entitlements.getEntitlementContext().user(), entity); - } - - AttributeSensor sensor = findSensor(entity, sensorName); - if (log.isDebugEnabled()) - log.debug("REST user "+Entitlements.getEntitlementContext()+" setting sensor "+sensorName+" to "+newValue); - entity.setAttribute(sensor, newValue); - } - - @Override - public void delete(String application, String entityToken, String sensorName) { - final EntityLocal entity = brooklyn().getEntity(application, entityToken); - AttributeSensor<?> sensor = findSensor(entity, sensorName); - if (log.isDebugEnabled()) - log.debug("REST user "+Entitlements.getEntitlementContext()+" deleting sensor "+sensorName); - ((EntityInternal)entity).removeAttribute(sensor); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java deleted file mode 100644 index 24e0e05..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/ServerResource.java +++ /dev/null @@ -1,496 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; - -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.base.Preconditions; -import com.google.common.collect.FluentIterable; - -import brooklyn.BrooklynVersion; -import brooklyn.config.ConfigKey; -import brooklyn.entity.Application; -import brooklyn.entity.basic.Attributes; -import brooklyn.entity.basic.ConfigKeys; -import brooklyn.entity.basic.Entities; -import brooklyn.entity.basic.EntityLocal; -import brooklyn.entity.basic.Lifecycle; -import brooklyn.entity.basic.StartableApplication; -import brooklyn.entity.rebind.persister.BrooklynPersistenceUtils; -import brooklyn.entity.rebind.persister.FileBasedObjectStore; -import brooklyn.entity.rebind.persister.PersistenceObjectStore; -import brooklyn.management.ManagementContext; -import brooklyn.management.Task; -import brooklyn.management.entitlement.EntitlementContext; -import brooklyn.management.entitlement.Entitlements; -import brooklyn.management.ha.HighAvailabilityManager; -import brooklyn.management.ha.HighAvailabilityMode; -import brooklyn.management.ha.ManagementNodeState; -import brooklyn.management.ha.ManagementPlaneSyncRecord; -import brooklyn.management.ha.MementoCopyMode; -import brooklyn.management.internal.ManagementContextInternal; -import brooklyn.rest.api.ServerApi; -import brooklyn.rest.domain.BrooklynFeatureSummary; -import brooklyn.rest.domain.HighAvailabilitySummary; -import brooklyn.rest.domain.VersionSummary; -import brooklyn.rest.transform.BrooklynFeatureTransformer; -import brooklyn.rest.transform.HighAvailabilityTransformer; -import brooklyn.rest.util.ShutdownHandler; -import brooklyn.rest.util.WebResourceUtils; -import brooklyn.util.ResourceUtils; -import brooklyn.util.collections.MutableMap; -import brooklyn.util.exceptions.Exceptions; -import brooklyn.util.file.ArchiveBuilder; -import brooklyn.util.flags.TypeCoercions; -import brooklyn.util.guava.Maybe; -import brooklyn.util.os.Os; -import brooklyn.util.text.Identifiers; -import brooklyn.util.text.Strings; -import brooklyn.util.time.CountdownTimer; -import brooklyn.util.time.Duration; -import brooklyn.util.time.Time; - -public class ServerResource extends AbstractBrooklynRestResource implements ServerApi { - - private static final int SHUTDOWN_TIMEOUT_CHECK_INTERVAL = 200; - - private static final Logger log = LoggerFactory.getLogger(ServerResource.class); - - private static final String BUILD_SHA_1_PROPERTY = "git-sha-1"; - private static final String BUILD_BRANCH_PROPERTY = "git-branch-name"; - - @Context - private ShutdownHandler shutdownHandler; - - @Override - public void reloadBrooklynProperties() { - brooklyn().reloadBrooklynProperties(); - } - - private boolean isMaster() { - return ManagementNodeState.MASTER.equals(mgmt().getHighAvailabilityManager().getNodeState()); - } - - @Override - public void shutdown(final boolean stopAppsFirst, final boolean forceShutdownOnError, - String shutdownTimeoutRaw, String requestTimeoutRaw, String delayForHttpReturnRaw, - Long delayMillis) { - - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ALL_SERVER_INFO, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - - log.info("REST call to shutdown server, stopAppsFirst="+stopAppsFirst+", delayForHttpReturn="+shutdownTimeoutRaw); - - if (stopAppsFirst && !isMaster()) { - log.warn("REST call to shutdown non-master server while stopping apps is disallowed"); - throw WebResourceUtils.forbidden("Not allowed to stop all apps when server is not master"); - } - final Duration shutdownTimeout = parseDuration(shutdownTimeoutRaw, Duration.of(20, TimeUnit.SECONDS)); - Duration requestTimeout = parseDuration(requestTimeoutRaw, Duration.of(20, TimeUnit.SECONDS)); - final Duration delayForHttpReturn; - if (delayMillis == null) { - delayForHttpReturn = parseDuration(delayForHttpReturnRaw, Duration.FIVE_SECONDS); - } else { - log.warn("'delayMillis' is deprecated, use 'delayForHttpReturn' instead."); - delayForHttpReturn = Duration.of(delayMillis, TimeUnit.MILLISECONDS); - } - - Preconditions.checkState(delayForHttpReturn.nanos() >= 0, "Only positive or 0 delay allowed for delayForHttpReturn"); - - boolean isSingleTimeout = shutdownTimeout.equals(requestTimeout); - final AtomicBoolean completed = new AtomicBoolean(); - final AtomicBoolean hasAppErrorsOrTimeout = new AtomicBoolean(); - - new Thread("shutdown") { - @Override - public void run() { - boolean terminateTried = false; - ManagementContext mgmt = mgmt(); - try { - if (stopAppsFirst) { - CountdownTimer shutdownTimeoutTimer = null; - if (!shutdownTimeout.equals(Duration.ZERO)) { - shutdownTimeoutTimer = shutdownTimeout.countdownTimer(); - } - - log.debug("Stopping applications"); - List<Task<?>> stoppers = new ArrayList<Task<?>>(); - int allStoppableApps = 0; - for (Application app: mgmt.getApplications()) { - allStoppableApps++; - Lifecycle appState = app.getAttribute(Attributes.SERVICE_STATE_ACTUAL); - if (app instanceof StartableApplication && - // Don't try to stop an already stopping app. Subsequent stops will complete faster - // cancelling the first stop task. - appState != Lifecycle.STOPPING) { - stoppers.add(Entities.invokeEffector((EntityLocal)app, app, StartableApplication.STOP)); - } else { - log.debug("App " + app + " is already stopping, will not stop second time. Will wait for original stop to complete."); - } - } - - log.debug("Waiting for " + allStoppableApps + " apps to stop, of which " + stoppers.size() + " stopped explicitly."); - for (Task<?> t: stoppers) { - if (!waitAppShutdown(shutdownTimeoutTimer, t)) { - //app stop error - hasAppErrorsOrTimeout.set(true); - } - } - - // Wait for apps which were already stopping when we tried to shut down. - if (hasStoppableApps(mgmt)) { - log.debug("Apps are still stopping, wait for proper unmanage."); - while (hasStoppableApps(mgmt) && (shutdownTimeoutTimer == null || !shutdownTimeoutTimer.isExpired())) { - Duration wait; - if (shutdownTimeoutTimer != null) { - wait = Duration.min(shutdownTimeoutTimer.getDurationRemaining(), Duration.ONE_SECOND); - } else { - wait = Duration.ONE_SECOND; - } - Time.sleep(wait); - } - if (hasStoppableApps(mgmt)) { - hasAppErrorsOrTimeout.set(true); - } - } - } - - terminateTried = true; - ((ManagementContextInternal)mgmt).terminate(); - - } catch (Throwable e) { - Throwable interesting = Exceptions.getFirstInteresting(e); - if (interesting instanceof TimeoutException) { - //timeout while waiting for apps to stop - log.warn("Timeout shutting down: "+Exceptions.collapseText(e)); - log.debug("Timeout shutting down: "+e, e); - hasAppErrorsOrTimeout.set(true); - - } else { - // swallow fatal, so we notify the outer loop to continue with shutdown - log.error("Unexpected error shutting down: "+Exceptions.collapseText(e), e); - - } - hasAppErrorsOrTimeout.set(true); - - if (!terminateTried) { - ((ManagementContextInternal)mgmt).terminate(); - } - } finally { - - complete(); - - if (!hasAppErrorsOrTimeout.get() || forceShutdownOnError) { - //give the http request a chance to complete gracefully, the server will be stopped in a shutdown hook - Time.sleep(delayForHttpReturn); - - if (shutdownHandler != null) { - shutdownHandler.onShutdownRequest(); - } else { - log.warn("ShutdownHandler not set, exiting process"); - System.exit(0); - } - - } else { - // There are app errors, don't exit the process, allowing any exception to continue throwing - log.warn("Abandoning shutdown because there were errors and shutdown was not forced."); - - } - } - } - - private boolean hasStoppableApps(ManagementContext mgmt) { - for (Application app : mgmt.getApplications()) { - if (app instanceof StartableApplication) { - Lifecycle state = app.getAttribute(Attributes.SERVICE_STATE_ACTUAL); - if (state != Lifecycle.STOPPING && state != Lifecycle.STOPPED) { - log.warn("Shutting down, expecting all apps to be in stopping state, but found application " + app + " to be in state " + state + ". Just started?"); - } - return true; - } - } - return false; - } - - private void complete() { - synchronized (completed) { - completed.set(true); - completed.notifyAll(); - } - } - - private boolean waitAppShutdown(CountdownTimer shutdownTimeoutTimer, Task<?> t) throws TimeoutException { - Duration waitInterval = null; - //wait indefinitely if no shutdownTimeoutTimer (shutdownTimeout == 0) - if (shutdownTimeoutTimer != null) { - waitInterval = Duration.of(SHUTDOWN_TIMEOUT_CHECK_INTERVAL, TimeUnit.MILLISECONDS); - } - // waitInterval == null - blocks indefinitely - while(!t.blockUntilEnded(waitInterval)) { - if (shutdownTimeoutTimer.isExpired()) { - log.warn("Timeout while waiting for applications to stop at "+t+".\n"+t.getStatusDetail(true)); - throw new TimeoutException(); - } - } - if (t.isError()) { - log.warn("Error stopping application "+t+" during shutdown (ignoring)\n"+t.getStatusDetail(true)); - return false; - } else { - return true; - } - } - }.start(); - - synchronized (completed) { - if (!completed.get()) { - try { - long waitTimeout = 0; - //If the timeout for both shutdownTimeout and requestTimeout is equal - //then better wait until the 'completed' flag is set, rather than timing out - //at just about the same time (i.e. always wait for the shutdownTimeout in this case). - //This will prevent undefined behaviour where either one of shutdownTimeout or requestTimeout - //will be first to expire and the error flag won't be set predictably, it will - //toggle depending on which expires first. - //Note: shutdownTimeout is checked at SHUTDOWN_TIMEOUT_CHECK_INTERVAL interval, meaning it is - //practically rounded up to the nearest SHUTDOWN_TIMEOUT_CHECK_INTERVAL. - if (!isSingleTimeout) { - waitTimeout = requestTimeout.toMilliseconds(); - } - completed.wait(waitTimeout); - } catch (InterruptedException e) { - throw Exceptions.propagate(e); - } - } - } - - if (hasAppErrorsOrTimeout.get()) { - WebResourceUtils.badRequest("Error or timeout while stopping applications. See log for details."); - } - } - - private Duration parseDuration(String str, Duration defaultValue) { - if (Strings.isEmpty(str)) { - return defaultValue; - } else { - return Duration.parse(str); - } - } - - @Override - public VersionSummary getVersion() { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SERVER_STATUS, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - - // TODO - // * "build-metadata.properties" is probably the wrong name - // * we should include brooklyn.version and a build timestamp in this file - // * the authority for brooklyn should probably be core rather than brooklyn-rest-server - InputStream input = ResourceUtils.create().getResourceFromUrl("classpath://build-metadata.properties"); - Properties properties = new Properties(); - String gitSha1 = null, gitBranch = null; - try { - properties.load(input); - gitSha1 = properties.getProperty(BUILD_SHA_1_PROPERTY); - gitBranch = properties.getProperty(BUILD_BRANCH_PROPERTY); - } catch (IOException e) { - log.error("Failed to load build-metadata.properties", e); - } - gitSha1 = BrooklynVersion.INSTANCE.getSha1FromOsgiManifest(); - - FluentIterable<BrooklynFeatureSummary> features = FluentIterable.from(BrooklynVersion.getFeatures(mgmt())) - .transform(BrooklynFeatureTransformer.FROM_FEATURE); - - return new VersionSummary(BrooklynVersion.get(), gitSha1, gitBranch, features.toList()); - } - - @Override - public boolean isUp() { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SERVER_STATUS, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - - Maybe<ManagementContext> mm = mgmtMaybe(); - return !mm.isAbsent() && mm.get().isStartupComplete() && mm.get().isRunning(); - } - - @Override - public boolean isShuttingDown() { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SERVER_STATUS, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - Maybe<ManagementContext> mm = mgmtMaybe(); - return !mm.isAbsent() && mm.get().isStartupComplete() && !mm.get().isRunning(); - } - - @Override - public boolean isHealthy() { - return isUp() && ((ManagementContextInternal) mgmt()).errors().isEmpty(); - } - - @Override - public Map<String,Object> getUpExtended() { - return MutableMap.<String,Object>of( - "up", isUp(), - "shuttingDown", isShuttingDown(), - "healthy", isHealthy(), - "ha", getHighAvailabilityPlaneStates()); - } - - - @Deprecated - @Override - public String getStatus() { - return getHighAvailabilityNodeState().toString(); - } - - @Override - public String getConfig(String configKey) { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ALL_SERVER_INFO, null)) { - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - } - ConfigKey<String> config = ConfigKeys.newStringConfigKey(configKey); - return mgmt().getConfig().getConfig(config); - } - - @Deprecated - @Override - public HighAvailabilitySummary getHighAvailability() { - return getHighAvailabilityPlaneStates(); - } - - @Override - public ManagementNodeState getHighAvailabilityNodeState() { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SERVER_STATUS, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - - Maybe<ManagementContext> mm = mgmtMaybe(); - if (mm.isAbsent()) return ManagementNodeState.INITIALIZING; - return mm.get().getHighAvailabilityManager().getNodeState(); - } - - @Override - public ManagementNodeState setHighAvailabilityNodeState(HighAvailabilityMode mode) { - if (mode==null) - throw new IllegalStateException("Missing parameter: mode"); - - HighAvailabilityManager haMgr = mgmt().getHighAvailabilityManager(); - ManagementNodeState existingState = haMgr.getNodeState(); - haMgr.changeMode(mode); - return existingState; - } - - @Override - public Map<String, Object> getHighAvailabilityMetrics() { - return mgmt().getHighAvailabilityManager().getMetrics(); - } - - @Override - public long getHighAvailabitlityPriority() { - return mgmt().getHighAvailabilityManager().getPriority(); - } - - @Override - public long setHighAvailabilityPriority(long priority) { - HighAvailabilityManager haMgr = mgmt().getHighAvailabilityManager(); - long oldPrio = haMgr.getPriority(); - haMgr.setPriority(priority); - return oldPrio; - } - - @Override - public HighAvailabilitySummary getHighAvailabilityPlaneStates() { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SERVER_STATUS, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - ManagementPlaneSyncRecord memento = mgmt().getHighAvailabilityManager().getLastManagementPlaneSyncRecord(); - if (memento==null) memento = mgmt().getHighAvailabilityManager().loadManagementPlaneSyncRecord(true); - if (memento==null) return null; - return HighAvailabilityTransformer.highAvailabilitySummary(mgmt().getManagementNodeId(), memento); - } - - @Override - public Response clearHighAvailabilityPlaneStates() { - mgmt().getHighAvailabilityManager().publishClearNonMaster(); - return Response.ok().build(); - } - - @Override - public String getUser() { - EntitlementContext entitlementContext = Entitlements.getEntitlementContext(); - if (entitlementContext!=null && entitlementContext.user()!=null){ - return entitlementContext.user(); - } else { - return null; //User can be null if no authentication was requested - } - } - - @Override - public Response exportPersistenceData(String preferredOrigin) { - return exportPersistenceData(TypeCoercions.coerce(preferredOrigin, MementoCopyMode.class)); - } - - protected Response exportPersistenceData(MementoCopyMode preferredOrigin) { - if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ALL_SERVER_INFO, null)) - throw WebResourceUtils.unauthorized("User '%s' is not authorized for this operation", Entitlements.getEntitlementContext().user()); - - File dir = null; - try { - String label = mgmt().getManagementNodeId()+"-"+Time.makeDateSimpleStampString(); - PersistenceObjectStore targetStore = BrooklynPersistenceUtils.newPersistenceObjectStore(mgmt(), null, - "tmp/web-persistence-"+label+"-"+Identifiers.makeRandomId(4)); - dir = ((FileBasedObjectStore)targetStore).getBaseDir(); - // only register the parent dir because that will prevent leaks for the random ID - Os.deleteOnExitEmptyParentsUpTo(dir.getParentFile(), dir.getParentFile()); - BrooklynPersistenceUtils.writeMemento(mgmt(), targetStore, preferredOrigin); - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - ArchiveBuilder.zip().addDirContentsAt( ((FileBasedObjectStore)targetStore).getBaseDir(), ((FileBasedObjectStore)targetStore).getBaseDir().getName() ).stream(baos); - Os.deleteRecursively(dir); - String filename = "brooklyn-state-"+label+".zip"; - return Response.ok(baos.toByteArray(), MediaType.APPLICATION_OCTET_STREAM_TYPE) - .header("Content-Disposition","attachment; filename = "+filename) - .build(); - } catch (Exception e) { - log.warn("Unable to serve persistence data (rethrowing): "+e, e); - if (dir!=null) { - try { - Os.deleteRecursively(dir); - } catch (Exception e2) { - log.warn("Ignoring error deleting '"+dir+"' after another error, throwing original error ("+e+"); ignored error deleting is: "+e2); - } - } - throw Exceptions.propagate(e); - } - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java deleted file mode 100644 index 08c0668..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/UsageResource.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import static brooklyn.rest.util.WebResourceUtils.notFound; - -import java.net.URI; -import java.util.Date; -import java.util.List; -import java.util.Set; - -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.entity.basic.Lifecycle; -import brooklyn.management.internal.ManagementContextInternal; -import brooklyn.management.usage.ApplicationUsage; -import brooklyn.management.usage.ApplicationUsage.ApplicationEvent; -import brooklyn.management.usage.LocationUsage; -import brooklyn.rest.api.UsageApi; -import brooklyn.rest.domain.UsageStatistic; -import brooklyn.rest.domain.UsageStatistics; -import brooklyn.rest.transform.ApplicationTransformer; -import brooklyn.util.exceptions.UserFacingException; -import brooklyn.util.text.Strings; -import brooklyn.util.time.Time; - -import com.google.common.base.Objects; -import com.google.common.base.Predicate; -import com.google.common.base.Predicates; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; - - -public class UsageResource extends AbstractBrooklynRestResource implements UsageApi { - - private static final Logger log = LoggerFactory.getLogger(UsageResource.class); - - private static final Set<Lifecycle> WORKING_LIFECYCLES = ImmutableSet.of(Lifecycle.RUNNING, Lifecycle.CREATED, Lifecycle.STARTING); - - @Override - public List<UsageStatistics> listApplicationsUsage(@Nullable String start, @Nullable String end) { - log.debug("REST call to get application usage for all applications: dates {} -> {}", new Object[] {start, end}); - - List<UsageStatistics> response = Lists.newArrayList(); - - Date startDate = parseDate(start, new Date(0)); - Date endDate = parseDate(end, new Date()); - - checkDates(startDate, endDate); - - Set<ApplicationUsage> usages = ((ManagementContextInternal) mgmt()).getUsageManager().getApplicationUsage(Predicates.alwaysTrue()); - - for (ApplicationUsage usage : usages) { - List<UsageStatistic> statistics = retrieveApplicationUsage(usage, startDate, endDate); - if (statistics.size() > 0) { - response.add(new UsageStatistics(statistics, ImmutableMap.<String,URI>of())); - } - } - return response; - } - - @Override - public UsageStatistics getApplicationUsage(String application, String start, String end) { - log.debug("REST call to get application usage for application {}: dates {} -> {}", new Object[] {application, start, end}); - - Date startDate = parseDate(start, new Date(0)); - Date endDate = parseDate(end, new Date()); - - checkDates(startDate, endDate); - - ApplicationUsage usage = ((ManagementContextInternal) mgmt()).getUsageManager().getApplicationUsage(application); - if (usage != null) { - List<UsageStatistic> statistics = retrieveApplicationUsage(usage, startDate, endDate); - return new UsageStatistics(statistics, ImmutableMap.<String,URI>of()); - } else { - throw notFound("Application '%s' not found", application); - } - } - - private List<UsageStatistic> retrieveApplicationUsage(ApplicationUsage usage, Date startDate, Date endDate) { - log.debug("Determining application usage for application {}: dates {} -> {}", new Object[] {usage.getApplicationId(), startDate, endDate}); - log.trace("Considering application usage events of {}: {}", usage.getApplicationId(), usage.getEvents()); - - List<UsageStatistic> result = Lists.newArrayList(); - - // Getting duration of state by comparing with next event (if next event is of same type, we just generate two statistics)... - for (int i = 0; i < usage.getEvents().size(); i++) { - ApplicationEvent current = usage.getEvents().get(i); - Date eventStartDate = current.getDate(); - Date eventEndDate; - - if (i < usage.getEvents().size() - 1) { - ApplicationEvent next = usage.getEvents().get(i + 1); - eventEndDate = next.getDate(); - } else if (current.getState() == Lifecycle.DESTROYED) { - eventEndDate = eventStartDate; - } else { - eventEndDate = new Date(); - } - - if (eventStartDate.compareTo(endDate) > 0 || eventEndDate.compareTo(startDate) < 0) { - continue; - } - - if (eventStartDate.compareTo(startDate) < 0) { - eventStartDate = startDate; - } - if (eventEndDate.compareTo(endDate) > 0) { - eventEndDate = endDate; - } - long duration = eventEndDate.getTime() - eventStartDate.getTime(); - UsageStatistic statistic = new UsageStatistic(ApplicationTransformer.statusFromLifecycle(current.getState()), usage.getApplicationId(), usage.getApplicationId(), format(eventStartDate), format(eventEndDate), duration, usage.getMetadata()); - log.trace("Adding application usage statistic to response for app {}: {}", usage.getApplicationId(), statistic); - result.add(statistic); - } - - return result; - } - - @Override - public List<UsageStatistics> listMachinesUsage(final String application, final String start, final String end) { - log.debug("REST call to get machine usage for application {}: dates {} -> {}", new Object[] {application, start, end}); - - final Date startDate = parseDate(start, new Date(0)); - final Date endDate = parseDate(end, new Date()); - - checkDates(startDate, endDate); - - // Note currently recording ALL metrics for a machine that contains an Event from given Application - Set<LocationUsage> matches = ((ManagementContextInternal) mgmt()).getUsageManager().getLocationUsage(new Predicate<LocationUsage>() { - @Override - public boolean apply(LocationUsage input) { - LocationUsage.LocationEvent first = input.getEvents().get(0); - if (endDate.compareTo(first.getDate()) < 0) { - return false; - } - LocationUsage.LocationEvent last = input.getEvents().get(input.getEvents().size() - 1); - if (!WORKING_LIFECYCLES.contains(last.getState()) && startDate.compareTo(last.getDate()) > 0) { - return false; - } - if (application != null) { - for (LocationUsage.LocationEvent e : input.getEvents()) { - if (Objects.equal(application, e.getApplicationId())) { - return true; - } - } - return false; - } - return true; - } - }); - - List<UsageStatistics> response = Lists.newArrayList(); - for (LocationUsage usage : matches) { - List<UsageStatistic> statistics = retrieveMachineUsage(usage, startDate, endDate); - if (statistics.size() > 0) { - response.add(new UsageStatistics(statistics, ImmutableMap.<String,URI>of())); - } - } - return response; - } - - @Override - public UsageStatistics getMachineUsage(final String machine, final String start, final String end) { - log.debug("REST call to get machine usage for machine {}: dates {} -> {}", new Object[] {machine, start, end}); - - final Date startDate = parseDate(start, new Date(0)); - final Date endDate = parseDate(end, new Date()); - - checkDates(startDate, endDate); - - // Note currently recording ALL metrics for a machine that contains an Event from given Application - LocationUsage usage = ((ManagementContextInternal) mgmt()).getUsageManager().getLocationUsage(machine); - - if (usage == null) { - throw notFound("Machine '%s' not found", machine); - } - - List<UsageStatistic> statistics = retrieveMachineUsage(usage, startDate, endDate); - return new UsageStatistics(statistics, ImmutableMap.<String,URI>of()); - } - - private List<UsageStatistic> retrieveMachineUsage(LocationUsage usage, Date startDate, Date endDate) { - log.debug("Determining machine usage for location {}", usage.getLocationId()); - log.trace("Considering machine usage events of {}: {}", usage.getLocationId(), usage.getEvents()); - - List<UsageStatistic> result = Lists.newArrayList(); - - // Getting duration of state by comparing with next event (if next event is of same type, we just generate two statistics)... - for (int i = 0; i < usage.getEvents().size(); i++) { - LocationUsage.LocationEvent current = usage.getEvents().get(i); - Date eventStartDate = current.getDate(); - Date eventEndDate; - - if (i < usage.getEvents().size() - 1) { - LocationUsage.LocationEvent next = usage.getEvents().get(i + 1); - eventEndDate = next.getDate(); - } else if (current.getState() == Lifecycle.DESTROYED || current.getState() == Lifecycle.STOPPED) { - eventEndDate = eventStartDate; - } else { - eventEndDate = new Date(); - } - - if (eventStartDate.compareTo(endDate) > 0 || eventEndDate.compareTo(startDate) < 0) { - continue; - } - - if (eventStartDate.compareTo(startDate) < 0) { - eventStartDate = startDate; - } - if (eventEndDate.compareTo(endDate) > 0) { - eventEndDate = endDate; - } - long duration = eventEndDate.getTime() - eventStartDate.getTime(); - UsageStatistic statistic = new UsageStatistic(ApplicationTransformer.statusFromLifecycle(current.getState()), usage.getLocationId(), current.getApplicationId(), format(eventStartDate), format(eventEndDate), duration, usage.getMetadata()); - log.trace("Adding machine usage statistic to response for app {}: {}", usage.getLocationId(), statistic); - result.add(statistic); - } - - return result; - } - - private void checkDates(Date startDate, Date endDate) { - if (startDate.compareTo(endDate) > 0) { - throw new UserFacingException(new IllegalArgumentException("Start must be less than or equal to end: " + startDate + " > " + endDate + - " (" + startDate.getTime() + " > " + endDate.getTime() + ")")); - } - } - - private Date parseDate(String toParse, Date def) { - return Strings.isBlank(toParse) ? def : Time.parseDate(toParse); - } - - private String format(Date date) { - return Time.makeDateString(date, Time.DATE_FORMAT_ISO8601_NO_MILLIS, Time.TIME_ZONE_UTC); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/resources/VersionResource.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/resources/VersionResource.java b/usage/rest-server/src/main/java/brooklyn/rest/resources/VersionResource.java deleted file mode 100644 index 44e26ab..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/resources/VersionResource.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 brooklyn.rest.resources; - -import brooklyn.BrooklynVersion; -import brooklyn.rest.api.VersionApi; - -/** @deprecated since 0.7.0; use /v1/server/version */ -@Deprecated -public class VersionResource extends AbstractBrooklynRestResource implements VersionApi { - - @Override - public String getVersion() { - return BrooklynVersion.get(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/security/PasswordHasher.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/PasswordHasher.java b/usage/rest-server/src/main/java/brooklyn/rest/security/PasswordHasher.java deleted file mode 100644 index 262920c..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/security/PasswordHasher.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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 brooklyn.rest.security; - -import com.google.common.base.Charsets; -import com.google.common.hash.HashCode; -import com.google.common.hash.Hashing; - -public class PasswordHasher { - public static String sha256(String salt, String password) { - if (salt == null) salt = ""; - byte[] bytes = (salt + password).getBytes(Charsets.UTF_8); - HashCode hash = Hashing.sha256().hashBytes(bytes); - return hash.toString(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AbstractSecurityProvider.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AbstractSecurityProvider.java b/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AbstractSecurityProvider.java deleted file mode 100644 index 6ff5007..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AbstractSecurityProvider.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 brooklyn.rest.security.provider; - -import javax.servlet.http.HttpSession; - -import brooklyn.util.text.Strings; - -/** - * Provides default implementations of {@link #isAuthenticated(HttpSession)} and - * {@link #logout(HttpSession)}. - */ -public abstract class AbstractSecurityProvider implements SecurityProvider { - - @Override - public boolean isAuthenticated(HttpSession session) { - if (session == null) return false; - Object value = session.getAttribute(getAuthenticationKey()); - return Strings.isNonBlank(Strings.toString(value)); - } - - @Override - public boolean logout(HttpSession session) { - if (session == null) return false; - session.removeAttribute(getAuthenticationKey()); - return true; - } - - /** - * Sets an authentication token for the user on the session. Always returns true. - */ - protected boolean allow(HttpSession session, String user) { - session.setAttribute(getAuthenticationKey(), user); - return true; - } - - protected String getAuthenticationKey() { - return getClass().getName() + ".AUTHENTICATED"; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AnyoneSecurityProvider.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AnyoneSecurityProvider.java b/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AnyoneSecurityProvider.java deleted file mode 100644 index 13d520e..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/AnyoneSecurityProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 brooklyn.rest.security.provider; - -import javax.servlet.http.HttpSession; - -/** provider who allows everyone */ -public class AnyoneSecurityProvider implements SecurityProvider { - - @Override - public boolean isAuthenticated(HttpSession session) { - return true; - } - - @Override - public boolean authenticate(HttpSession session, String user, String password) { - return true; - } - - @Override - public boolean logout(HttpSession session) { - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BlackholeSecurityProvider.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BlackholeSecurityProvider.java b/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BlackholeSecurityProvider.java deleted file mode 100644 index 4add0eb..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BlackholeSecurityProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * 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 brooklyn.rest.security.provider; - -import javax.servlet.http.HttpSession; - -/** provider who disallows everyone */ -public class BlackholeSecurityProvider implements SecurityProvider { - - @Override - public boolean isAuthenticated(HttpSession session) { - return false; - } - - @Override - public boolean authenticate(HttpSession session, String user, String password) { - return false; - } - - @Override - public boolean logout(HttpSession session) { - return true; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a9e5ca55/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java ---------------------------------------------------------------------- diff --git a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java b/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java deleted file mode 100644 index 9cf63ca..0000000 --- a/usage/rest-server/src/main/java/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 brooklyn.rest.security.provider; - -import javax.servlet.http.HttpSession; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.management.ManagementContext; -import brooklyn.rest.filter.BrooklynPropertiesSecurityFilter; -import brooklyn.util.net.Networking; -import brooklyn.util.text.Identifiers; - -public class BrooklynUserWithRandomPasswordSecurityProvider extends AbstractSecurityProvider implements SecurityProvider { - - public static final Logger LOG = LoggerFactory.getLogger(BrooklynUserWithRandomPasswordSecurityProvider.class); - private static final String USER = "brooklyn"; - private final String password; - - public BrooklynUserWithRandomPasswordSecurityProvider() { - this.password = Identifiers.makeRandomId(10); - LOG.info("Allowing access to web console from localhost or with {}:{}", USER, password); - } - - public BrooklynUserWithRandomPasswordSecurityProvider(ManagementContext mgmt) { - this(); - } - - @Override - public boolean authenticate(HttpSession session, String user, String password) { - if ((USER.equals(user) && this.password.equals(password)) || isRemoteAddressLocalhost(session)) { - return allow(session, user); - } else { - return false; - } - } - - private boolean isRemoteAddressLocalhost(HttpSession session) { - Object remoteAddress = session.getAttribute(BrooklynPropertiesSecurityFilter.REMOTE_ADDRESS_SESSION_ATTRIBUTE); - if (!(remoteAddress instanceof String)) return false; - if (Networking.isLocalhost((String)remoteAddress)) { - if (LOG.isTraceEnabled()) { - LOG.trace(this+": granting passwordless access to "+session+" originating from "+remoteAddress); - } - return true; - } else { - LOG.debug(this+": password required for "+session+" originating from "+remoteAddress); - return false; - } - } -}
