You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by he...@apache.org on 2016/02/18 16:47:26 UTC
[08/34] brooklyn-server git commit: [BROOKLYN-183] REST API using CXF
JAX-RS 2.0 implementation
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
deleted file mode 100644
index 7ec0b22..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/PolicyResource.java
+++ /dev/null
@@ -1,131 +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 org.apache.brooklyn.rest.resources;
-
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.core.Response;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.policy.Policy;
-import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.core.policy.Policies;
-import org.apache.brooklyn.rest.api.PolicyApi;
-import org.apache.brooklyn.rest.domain.PolicySummary;
-import org.apache.brooklyn.rest.domain.Status;
-import org.apache.brooklyn.rest.domain.SummaryComparators;
-import org.apache.brooklyn.rest.filter.HaHotStateRequired;
-import org.apache.brooklyn.rest.transform.ApplicationTransformer;
-import org.apache.brooklyn.rest.transform.PolicyTransformer;
-import org.apache.brooklyn.rest.util.WebResourceUtils;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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.policies())
- .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
- Entity entity = brooklyn().getEntity(application, entityToken);
- Map<String, Boolean> result = Maps.newLinkedHashMap();
- for (Policy p : entity.policies()) {
- 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) {
- Entity 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.policies().add(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) {
- Entity entity = brooklyn().getEntity(application, entityToken);
- Policy policy = brooklyn().getPolicy(entity, policyToken);
-
- policy.suspend();
- entity.policies().remove(policy);
- return Response.status(Response.Status.NO_CONTENT).build();
- }
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ScriptResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ScriptResource.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ScriptResource.java
deleted file mode 100644
index 77989c3..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ScriptResource.java
+++ /dev/null
@@ -1,102 +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 org.apache.brooklyn.rest.resources;
-
-import org.apache.brooklyn.rest.api.ScriptApi;
-import org.apache.brooklyn.rest.domain.ScriptExecutionSummary;
-import org.apache.brooklyn.util.stream.ThreadLocalPrintStream;
-import org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
deleted file mode 100644
index 2f03196..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
+++ /dev/null
@@ -1,184 +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 org.apache.brooklyn.rest.resources;
-
-import static com.google.common.collect.Iterables.filter;
-
-import java.util.List;
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.Sensor;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
-import org.apache.brooklyn.core.mgmt.entitlement.Entitlements.EntityAndItem;
-import org.apache.brooklyn.core.sensor.BasicAttributeSensor;
-import org.apache.brooklyn.rest.api.SensorApi;
-import org.apache.brooklyn.rest.domain.SensorSummary;
-import org.apache.brooklyn.rest.filter.HaHotStateRequired;
-import org.apache.brooklyn.rest.transform.SensorTransformer;
-import org.apache.brooklyn.rest.util.WebResourceUtils;
-import org.apache.brooklyn.util.core.task.ValueResolver;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.Duration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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);
-
- @Override
- public List<SensorSummary> list(final String application, final String entityToken) {
- final Entity entity = brooklyn().getEntity(application, entityToken);
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
- throw WebResourceUtils.forbidden("User '%s' is not authorized to see entity '%s'",
- Entitlements.getEntitlementContext().user(), entity);
- }
-
- List<SensorSummary> result = Lists.newArrayList();
-
- for (AttributeSensor<?> sensor : filter(entity.getEntityType().getSensors(), AttributeSensor.class)) {
- // Exclude config that user is not allowed to see
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_SENSOR, new EntityAndItem<String>(entity, sensor.getName()))) {
- log.trace("User {} not authorized to see sensor {} of entity {}; excluding from AttributeSensor list results",
- new Object[] {Entitlements.getEntitlementContext().user(), sensor.getName(), entity});
- continue;
- }
- result.add(SensorTransformer.sensorSummary(entity, sensor));
- }
-
- return result;
- }
-
- @Override
- public Map<String, Object> batchSensorRead(final String application, final String entityToken, final Boolean raw) {
- final Entity entity = brooklyn().getEntity(application, entityToken);
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
- throw WebResourceUtils.forbidden("User '%s' is not authorized to see entity '%s'",
- Entitlements.getEntitlementContext().user(), entity);
- }
-
- Map<String, Object> sensorMap = Maps.newHashMap();
- @SuppressWarnings("rawtypes")
- Iterable<AttributeSensor> sensors = filter(entity.getEntityType().getSensors(), AttributeSensor.class);
-
- for (AttributeSensor<?> sensor : sensors) {
- // Exclude sensors that user is not allowed to see
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_SENSOR, new EntityAndItem<String>(entity, sensor.getName()))) {
- log.trace("User {} not authorized to see sensor {} of entity {}; excluding from current-state results",
- new Object[] {Entitlements.getEntitlementContext().user(), sensor.getName(), entity});
- continue;
- }
-
- 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 Entity entity = brooklyn().getEntity(application, entityToken);
- AttributeSensor<?> sensor = findSensor(entity, sensorName);
-
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_ENTITY, entity)) {
- throw WebResourceUtils.forbidden("User '%s' is not authorized to see entity '%s'",
- Entitlements.getEntitlementContext().user(), entity);
- }
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.SEE_SENSOR, new EntityAndItem<String>(entity, sensor.getName()))) {
- throw WebResourceUtils.forbidden("User '%s' is not authorized to see entity '%s' sensor '%s'",
- Entitlements.getEntitlementContext().user(), entity, sensor.getName());
- }
-
- 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(Entity 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 Entity entity = brooklyn().getEntity(application, entityToken);
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
- throw WebResourceUtils.forbidden("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.sensors().set(sensor, newValue);
- }
- }
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- public void set(String application, String entityToken, String sensorName, Object newValue) {
- final Entity entity = brooklyn().getEntity(application, entityToken);
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
- throw WebResourceUtils.forbidden("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.sensors().set(sensor, newValue);
- }
-
- @Override
- public void delete(String application, String entityToken, String sensorName) {
- final Entity entity = brooklyn().getEntity(application, entityToken);
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(), Entitlements.MODIFY_ENTITY, entity)) {
- throw WebResourceUtils.forbidden("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()+" deleting sensor "+sensorName);
- ((EntityInternal)entity).sensors().remove(sensor);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
deleted file mode 100644
index 426870d..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/ServerResource.java
+++ /dev/null
@@ -1,495 +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 org.apache.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.apache.brooklyn.api.entity.Application;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.api.mgmt.Task;
-import org.apache.brooklyn.api.mgmt.entitlement.EntitlementContext;
-import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityManager;
-import org.apache.brooklyn.api.mgmt.ha.HighAvailabilityMode;
-import org.apache.brooklyn.api.mgmt.ha.ManagementNodeState;
-import org.apache.brooklyn.api.mgmt.ha.ManagementPlaneSyncRecord;
-import org.apache.brooklyn.api.mgmt.ha.MementoCopyMode;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.BrooklynVersion;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.Attributes;
-import org.apache.brooklyn.core.entity.Entities;
-import org.apache.brooklyn.core.entity.StartableApplication;
-import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.mgmt.entitlement.Entitlements;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.mgmt.persist.BrooklynPersistenceUtils;
-import org.apache.brooklyn.core.mgmt.persist.FileBasedObjectStore;
-import org.apache.brooklyn.core.mgmt.persist.PersistenceObjectStore;
-import org.apache.brooklyn.rest.api.ServerApi;
-import org.apache.brooklyn.rest.domain.BrooklynFeatureSummary;
-import org.apache.brooklyn.rest.domain.HighAvailabilitySummary;
-import org.apache.brooklyn.rest.domain.VersionSummary;
-import org.apache.brooklyn.rest.transform.BrooklynFeatureTransformer;
-import org.apache.brooklyn.rest.transform.HighAvailabilityTransformer;
-import org.apache.brooklyn.rest.util.ShutdownHandler;
-import org.apache.brooklyn.rest.util.WebResourceUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.apache.brooklyn.util.core.ResourceUtils;
-import org.apache.brooklyn.util.core.file.ArchiveBuilder;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.guava.Maybe;
-import org.apache.brooklyn.util.os.Os;
-import org.apache.brooklyn.util.text.Identifiers;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.brooklyn.util.time.CountdownTimer;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.FluentIterable;
-
-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.forbidden("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(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 {
- // should normally be set, as @Context is required by jersey injection
- 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.forbidden("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.forbidden("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.forbidden("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.forbidden("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.forbidden("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.forbidden("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.forbidden("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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/UsageResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/UsageResource.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/UsageResource.java
deleted file mode 100644
index ebcd2fa..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/UsageResource.java
+++ /dev/null
@@ -1,256 +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 org.apache.brooklyn.rest.resources;
-
-import static org.apache.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 org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.core.mgmt.usage.ApplicationUsage;
-import org.apache.brooklyn.core.mgmt.usage.LocationUsage;
-import org.apache.brooklyn.core.mgmt.usage.ApplicationUsage.ApplicationEvent;
-import org.apache.brooklyn.rest.api.UsageApi;
-import org.apache.brooklyn.rest.domain.UsageStatistic;
-import org.apache.brooklyn.rest.domain.UsageStatistics;
-import org.apache.brooklyn.rest.transform.ApplicationTransformer;
-import org.apache.brooklyn.util.exceptions.UserFacingException;
-import org.apache.brooklyn.util.text.Strings;
-import org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/VersionResource.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/VersionResource.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/resources/VersionResource.java
deleted file mode 100644
index 7492af6..0000000
--- a/rest/rest-server/src/main/java/org/apache/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 org.apache.brooklyn.rest.resources;
-
-import org.apache.brooklyn.core.BrooklynVersion;
-import org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/PasswordHasher.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/PasswordHasher.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/PasswordHasher.java
deleted file mode 100644
index 928a6bd..0000000
--- a/rest/rest-server/src/main/java/org/apache/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 org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/AbstractSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/AbstractSecurityProvider.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/AbstractSecurityProvider.java
deleted file mode 100644
index 91c2523..0000000
--- a/rest/rest-server/src/main/java/org/apache/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 org.apache.brooklyn.rest.security.provider;
-
-import javax.servlet.http.HttpSession;
-
-import org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/AnyoneSecurityProvider.java
deleted file mode 100644
index 97b4fe1..0000000
--- a/rest/rest-server/src/main/java/org/apache/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 org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BlackholeSecurityProvider.java
deleted file mode 100644
index a976975..0000000
--- a/rest/rest-server/src/main/java/org/apache/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 org.apache.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/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
deleted file mode 100644
index d5be027..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/BrooklynUserWithRandomPasswordSecurityProvider.java
+++ /dev/null
@@ -1,73 +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 org.apache.brooklyn.rest.security.provider;
-
-import javax.servlet.http.HttpSession;
-
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.rest.filter.BrooklynPropertiesSecurityFilter;
-import org.apache.brooklyn.util.javalang.JavaClassNames;
-import org.apache.brooklyn.util.net.Networking;
-import org.apache.brooklyn.util.text.Identifiers;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-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;
- }
- }
-
- @Override
- public String toString() {
- return JavaClassNames.cleanSimpleClassName(this);
- }
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
deleted file mode 100644
index 11884c3..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/DelegatingSecurityProvider.java
+++ /dev/null
@@ -1,166 +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 org.apache.brooklyn.rest.security.provider;
-
-import java.lang.reflect.Constructor;
-import java.util.concurrent.atomic.AtomicLong;
-
-import javax.servlet.http.HttpSession;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.rest.BrooklynWebConfig;
-import org.apache.brooklyn.util.text.Strings;
-
-public class DelegatingSecurityProvider implements SecurityProvider {
-
- private static final Logger log = LoggerFactory.getLogger(DelegatingSecurityProvider.class);
- protected final ManagementContext mgmt;
-
- public DelegatingSecurityProvider(ManagementContext mgmt) {
- this.mgmt = mgmt;
- mgmt.addPropertiesReloadListener(new PropertiesListener());
- }
-
- private SecurityProvider delegate;
- private final AtomicLong modCount = new AtomicLong();
-
- private class PropertiesListener implements ManagementContext.PropertiesReloadListener {
- private static final long serialVersionUID = 8148722609022378917L;
-
- @Override
- public void reloaded() {
- log.debug("{} reloading security provider", DelegatingSecurityProvider.this);
- synchronized (DelegatingSecurityProvider.this) {
- loadDelegate();
- invalidateExistingSessions();
- }
- }
- }
-
- public synchronized SecurityProvider getDelegate() {
- if (delegate == null) {
- delegate = loadDelegate();
- }
- return delegate;
- }
-
- @SuppressWarnings("unchecked")
- private synchronized SecurityProvider loadDelegate() {
- StringConfigMap brooklynProperties = mgmt.getConfig();
-
- SecurityProvider presetDelegate = brooklynProperties.getConfig(BrooklynWebConfig.SECURITY_PROVIDER_INSTANCE);
- if (presetDelegate!=null) {
- log.info("REST using pre-set security provider " + presetDelegate);
- return presetDelegate;
- }
-
- String className = brooklynProperties.getConfig(BrooklynWebConfig.SECURITY_PROVIDER_CLASSNAME);
-
- if (delegate != null && BrooklynWebConfig.hasNoSecurityOptions(mgmt.getConfig())) {
- log.debug("{} refusing to change from {}: No security provider set in reloaded properties.",
- this, delegate);
- return delegate;
- }
- log.info("REST using security provider " + className);
-
- try {
- Class<? extends SecurityProvider> clazz;
- try {
- clazz = (Class<? extends SecurityProvider>) Class.forName(className);
- } catch (Exception e) {
- String oldPackage = "brooklyn.web.console.security.";
- if (className.startsWith(oldPackage)) {
- className = Strings.removeFromStart(className, oldPackage);
- className = DelegatingSecurityProvider.class.getPackage().getName() + "." + className;
- clazz = (Class<? extends SecurityProvider>) Class.forName(className);
- log.warn("Deprecated package " + oldPackage + " detected; please update security provider to point to " + className);
- } else throw e;
- }
-
- Constructor<? extends SecurityProvider> constructor;
- try {
- constructor = clazz.getConstructor(ManagementContext.class);
- delegate = constructor.newInstance(mgmt);
- } catch (Exception e) {
- constructor = clazz.getConstructor();
- Object delegateO = constructor.newInstance();
- if (!(delegateO instanceof SecurityProvider)) {
- // if classloaders get mangled it will be a different CL's SecurityProvider
- throw new ClassCastException("Delegate is either not a security provider or has an incompatible classloader: "+delegateO);
- }
- delegate = (SecurityProvider) delegateO;
- }
- } catch (Exception e) {
- log.warn("REST unable to instantiate security provider " + className + "; all logins are being disallowed", e);
- delegate = new BlackholeSecurityProvider();
- }
-
- ((ManagementContextInternal)mgmt).getBrooklynProperties().put(BrooklynWebConfig.SECURITY_PROVIDER_INSTANCE, delegate);
-
- return delegate;
- }
-
- /**
- * Causes all existing sessions to be invalidated.
- */
- protected void invalidateExistingSessions() {
- modCount.incrementAndGet();
- }
-
- @Override
- public boolean isAuthenticated(HttpSession session) {
- if (session == null) return false;
- Object modCountWhenFirstAuthenticated = session.getAttribute(getModificationCountKey());
- boolean authenticated = getDelegate().isAuthenticated(session) &&
- Long.valueOf(modCount.get()).equals(modCountWhenFirstAuthenticated);
- return authenticated;
- }
-
- @Override
- public boolean authenticate(HttpSession session, String user, String password) {
- boolean authenticated = getDelegate().authenticate(session, user, password);
- if (authenticated) {
- session.setAttribute(getModificationCountKey(), modCount.get());
- }
- if (log.isTraceEnabled() && authenticated) {
- log.trace("User {} authenticated with provider {}", user, getDelegate());
- } else if (!authenticated && log.isDebugEnabled()) {
- log.debug("Failed authentication for user {} with provider {}", user, getDelegate());
- }
- return authenticated;
- }
-
- @Override
- public boolean logout(HttpSession session) {
- boolean logout = getDelegate().logout(session);
- if (logout) {
- session.removeAttribute(getModificationCountKey());
- }
- return logout;
- }
-
- private String getModificationCountKey() {
- return getClass().getName() + ".ModCount";
- }
-}
http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/6f624c78/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
----------------------------------------------------------------------
diff --git a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java b/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
deleted file mode 100644
index 562c85b..0000000
--- a/rest/rest-server/src/main/java/org/apache/brooklyn/rest/security/provider/ExplicitUsersSecurityProvider.java
+++ /dev/null
@@ -1,118 +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 org.apache.brooklyn.rest.security.provider;
-
-import java.util.LinkedHashSet;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.servlet.http.HttpSession;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.api.mgmt.ManagementContext;
-import org.apache.brooklyn.config.StringConfigMap;
-import org.apache.brooklyn.core.internal.BrooklynProperties;
-import org.apache.brooklyn.core.mgmt.internal.ManagementContextInternal;
-import org.apache.brooklyn.rest.BrooklynWebConfig;
-import org.apache.brooklyn.rest.security.PasswordHasher;
-
-/**
- * Security provider which validates users against passwords according to property keys,
- * as set in {@link BrooklynWebConfig#USERS} and {@link BrooklynWebConfig#PASSWORD_FOR_USER(String)}
- */
-public class ExplicitUsersSecurityProvider extends AbstractSecurityProvider implements SecurityProvider {
-
- public static final Logger LOG = LoggerFactory.getLogger(ExplicitUsersSecurityProvider.class);
-
- protected final ManagementContext mgmt;
- private boolean allowAnyUserWithValidPass;
- private Set<String> allowedUsers = null;
-
- public ExplicitUsersSecurityProvider(ManagementContext mgmt) {
- this.mgmt = mgmt;
- initialize();
- }
-
- private synchronized void initialize() {
- if (allowedUsers != null) return;
-
- StringConfigMap properties = mgmt.getConfig();
-
- allowedUsers = new LinkedHashSet<String>();
- String users = properties.getConfig(BrooklynWebConfig.USERS);
- if (users == null) {
- LOG.warn("REST has no users configured; no one will be able to log in!");
- } else if ("*".equals(users)) {
- LOG.info("REST allowing any user (so long as valid password is set)");
- allowAnyUserWithValidPass = true;
- } else {
- StringTokenizer t = new StringTokenizer(users, ",");
- while (t.hasMoreElements()) {
- allowedUsers.add(("" + t.nextElement()).trim());
- }
- LOG.info("REST allowing users: " + allowedUsers);
- }
- }
-
- @Override
- public boolean authenticate(HttpSession session, String user, String password) {
- if (session==null || user==null) return false;
-
- if (!allowAnyUserWithValidPass) {
- if (!allowedUsers.contains(user)) {
- LOG.debug("REST rejecting unknown user "+user);
- return false;
- }
- }
-
- if (checkExplicitUserPassword(mgmt, user, password)) {
- return allow(session, user);
- }
- return false;
- }
-
- /** checks the supplied candidate user and password against the
- * expect password (or SHA-256 + SALT thereof) defined as brooklyn properties.
- */
- public static boolean checkExplicitUserPassword(ManagementContext mgmt, String user, String password) {
- BrooklynProperties properties = ((ManagementContextInternal)mgmt).getBrooklynProperties();
- String expectedPassword = properties.getConfig(BrooklynWebConfig.PASSWORD_FOR_USER(user));
- String salt = properties.getConfig(BrooklynWebConfig.SALT_FOR_USER(user));
- String expectedSha256 = properties.getConfig(BrooklynWebConfig.SHA256_FOR_USER(user));
-
- return checkPassword(password, expectedPassword, expectedSha256, salt);
- }
- /**
- * checks a candidate password against the expected credential defined for a given user.
- * the expected credentials can be supplied as an expectedPassword OR as
- * a combination of the SHA-256 hash of the expected password plus a defined salt.
- * the combination of the SHA+SALT allows credentials to be supplied in a non-plaintext manner.
- */
- public static boolean checkPassword(String candidatePassword, String expectedPassword, String expectedPasswordSha256, String salt) {
- if (expectedPassword != null) {
- return expectedPassword.equals(candidatePassword);
- } else if (expectedPasswordSha256 != null) {
- String hashedCandidatePassword = PasswordHasher.sha256(salt, candidatePassword);
- return expectedPasswordSha256.equals(hashedCandidatePassword);
- }
-
- return false;
- }
-}