You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@brooklyn.apache.org by ha...@apache.org on 2015/10/15 18:16:42 UTC
[1/7] incubator-brooklyn git commit: [BROOKLYN-182] Move
winrm-dependent code from brooklyn-core to brooklyn-software-winrm
Repository: incubator-brooklyn
Updated Branches:
refs/heads/master d53bd189c -> f380b5836
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
new file mode 100644
index 0000000..ff659b1
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
@@ -0,0 +1,414 @@
+/*
+ * 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.feed.windows;
+
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.mgmt.ExecutionContext;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.effector.EffectorTasks;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.feed.AbstractFeed;
+import org.apache.brooklyn.core.feed.PollHandler;
+import org.apache.brooklyn.core.feed.Poller;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterPollConfig;
+import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.util.core.flags.TypeCoercions;
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.time.Duration;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Function;
+import com.google.common.base.Joiner;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import com.google.common.reflect.TypeToken;
+
+/**
+ * A sensor feed that retrieves performance counters from a Windows host and posts the values to sensors.
+ *
+ * <p>To use this feed, you must provide the entity, and a collection of mappings between Windows performance counter
+ * names and Brooklyn attribute sensors.</p>
+ *
+ * <p>This feed uses SSH to invoke the windows utility <tt>typeperf</tt> to query for a specific set of performance
+ * counters, by name. The values are extracted from the response, and published to the entity's sensors.</p>
+ *
+ * <p>Example:</p>
+ *
+ * {@code
+ * @Override
+ * protected void connectSensors() {
+ * WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
+ * .entity(entity)
+ * .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
+ * .addSensor("\\Memory\\Available MBytes", AVAILABLE_MEMORY)
+ * .build();
+ * }
+ * }
+ *
+ * @since 0.6.0
+ * @author richardcloudsoft
+ */
+public class WindowsPerformanceCounterFeed extends AbstractFeed {
+
+ private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeed.class);
+
+ // This pattern matches CSV line(s) with the date in the first field, and at least one further field.
+ protected static final Pattern lineWithPerfData = Pattern.compile("^\"[\\d:/\\-. ]+\",\".*\"$", Pattern.MULTILINE);
+ private static final Joiner JOINER_ON_SPACE = Joiner.on(' ');
+ private static final Joiner JOINER_ON_COMMA = Joiner.on(',');
+ private static final int OUTPUT_COLUMN_WIDTH = 100;
+
+ @SuppressWarnings("serial")
+ public static final ConfigKey<Collection<WindowsPerformanceCounterPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
+ new TypeToken<Collection<WindowsPerformanceCounterPollConfig<?>>>() {},
+ "polls");
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private EntityLocal entity;
+ private Set<WindowsPerformanceCounterPollConfig<?>> polls = Sets.newLinkedHashSet();
+ private Duration period = Duration.of(30, TimeUnit.SECONDS);
+ private String uniqueTag;
+ private volatile boolean built;
+
+ public Builder entity(EntityLocal val) {
+ this.entity = checkNotNull(val, "entity");
+ return this;
+ }
+ public Builder addSensor(WindowsPerformanceCounterPollConfig<?> config) {
+ polls.add(config);
+ return this;
+ }
+ public Builder addSensor(String performanceCounterName, AttributeSensor<?> sensor) {
+ return addSensor(new WindowsPerformanceCounterPollConfig(sensor).performanceCounterName(checkNotNull(performanceCounterName, "performanceCounterName")));
+ }
+ public Builder addSensors(Map<String, AttributeSensor> sensors) {
+ for (Map.Entry<String, AttributeSensor> entry : sensors.entrySet()) {
+ addSensor(entry.getKey(), entry.getValue());
+ }
+ return this;
+ }
+ public Builder period(Duration period) {
+ this.period = checkNotNull(period, "period");
+ return this;
+ }
+ public Builder period(long millis) {
+ return period(millis, TimeUnit.MILLISECONDS);
+ }
+ public Builder period(long val, TimeUnit units) {
+ return period(Duration.of(val, units));
+ }
+ public Builder uniqueTag(String uniqueTag) {
+ this.uniqueTag = uniqueTag;
+ return this;
+ }
+ public WindowsPerformanceCounterFeed build() {
+ built = true;
+ WindowsPerformanceCounterFeed result = new WindowsPerformanceCounterFeed(this);
+ result.setEntity(checkNotNull(entity, "entity"));
+ result.start();
+ return result;
+ }
+ @Override
+ protected void finalize() {
+ if (!built) log.warn("WindowsPerformanceCounterFeed.Builder created, but build() never called");
+ }
+ }
+
+ /**
+ * For rebind; do not call directly; use builder
+ */
+ public WindowsPerformanceCounterFeed() {
+ }
+
+ protected WindowsPerformanceCounterFeed(Builder builder) {
+ List<WindowsPerformanceCounterPollConfig<?>> polls = Lists.newArrayList();
+ for (WindowsPerformanceCounterPollConfig<?> config : builder.polls) {
+ if (!config.isEnabled()) continue;
+ @SuppressWarnings({ "unchecked", "rawtypes" })
+ WindowsPerformanceCounterPollConfig<?> configCopy = new WindowsPerformanceCounterPollConfig(config);
+ if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
+ polls.add(configCopy);
+ }
+ config().set(POLLS, polls);
+ initUniqueTag(builder.uniqueTag, polls);
+ }
+
+ @Override
+ protected void preStart() {
+ Collection<WindowsPerformanceCounterPollConfig<?>> polls = getConfig(POLLS);
+
+ long minPeriod = Integer.MAX_VALUE;
+ List<String> performanceCounterNames = Lists.newArrayList();
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ minPeriod = Math.min(minPeriod, config.getPeriod());
+ performanceCounterNames.add(config.getPerformanceCounterName());
+ }
+
+ Iterable<String> allParams = ImmutableList.<String>builder()
+ .add("(Get-Counter")
+ .add("-Counter")
+ .add(JOINER_ON_COMMA.join(Iterables.transform(performanceCounterNames, QuoteStringFunction.INSTANCE)))
+ .add("-SampleInterval")
+ .add("2") // TODO: extract SampleInterval as a config key
+ .add(").CounterSamples")
+ .add("|")
+ .add("Format-Table")
+ .add(String.format("@{Expression={$_.Path};width=%d},@{Expression={$_.CookedValue};width=%<d}", OUTPUT_COLUMN_WIDTH))
+ .add("-HideTableHeaders")
+ .add("|")
+ .add("Out-String")
+ .add("-Width")
+ .add(String.valueOf(OUTPUT_COLUMN_WIDTH * 2))
+ .build();
+ String command = JOINER_ON_SPACE.join(allParams);
+ log.debug("Windows performance counter poll command for {} will be: {}", entity, command);
+
+ GetPerformanceCountersJob<WinRmToolResponse> job = new GetPerformanceCountersJob(getEntity(), command);
+ getPoller().scheduleAtFixedRate(
+ new CallInEntityExecutionContext(entity, job),
+ new SendPerfCountersToSensors(getEntity(), polls),
+ minPeriod);
+ }
+
+ private static class GetPerformanceCountersJob<T> implements Callable<T> {
+
+ private final Entity entity;
+ private final String command;
+
+ GetPerformanceCountersJob(Entity entity, String command) {
+ this.entity = entity;
+ this.command = command;
+ }
+
+ @Override
+ public T call() throws Exception {
+ WinRmMachineLocation machine = EffectorTasks.getWinRmMachine(entity);
+ WinRmToolResponse response = machine.executePsScript(command);
+ return (T)response;
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ protected Poller<WinRmToolResponse> getPoller() {
+ return (Poller<WinRmToolResponse>) super.getPoller();
+ }
+
+ /**
+ * A {@link java.util.concurrent.Callable} that wraps another {@link java.util.concurrent.Callable}, where the
+ * inner {@link java.util.concurrent.Callable} is executed in the context of a
+ * specific entity.
+ *
+ * @param <T> The type of the {@link java.util.concurrent.Callable}.
+ */
+ private static class CallInEntityExecutionContext<T> implements Callable<T> {
+ private final Callable<T> job;
+ private EntityLocal entity;
+
+ private CallInEntityExecutionContext(EntityLocal entity, Callable<T> job) {
+ this.job = job;
+ this.entity = entity;
+ }
+
+ @Override
+ public T call() throws Exception {
+ ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext();
+ return executionContext.submit(Maps.newHashMap(), job).get();
+ }
+ }
+
+ @VisibleForTesting
+ static class SendPerfCountersToSensors implements PollHandler<WinRmToolResponse> {
+ private final EntityLocal entity;
+ private final List<WindowsPerformanceCounterPollConfig<?>> polls;
+ private final Set<AttributeSensor<?>> failedAttributes = Sets.newLinkedHashSet();
+ private static final Pattern MACHINE_NAME_LOOKBACK_PATTERN = Pattern.compile(String.format("(?<=\\\\\\\\.{0,%d})\\\\.*", OUTPUT_COLUMN_WIDTH));
+
+ public SendPerfCountersToSensors(EntityLocal entity, Collection<WindowsPerformanceCounterPollConfig<?>> polls) {
+ this.entity = entity;
+ this.polls = ImmutableList.copyOf(polls);
+ }
+
+ @Override
+ public boolean checkSuccess(WinRmToolResponse val) {
+ // TODO not just using statusCode; also looking at absence of stderr.
+ // Status code is (empirically) unreliable: it returns 0 sometimes even when failed
+ // (but never returns non-zero on success).
+ if (val.getStatusCode() != 0) return false;
+ String stderr = val.getStdErr();
+ if (stderr == null || stderr.length() != 0) return false;
+ String out = val.getStdOut();
+ if (out == null || out.length() == 0) return false;
+ return true;
+ }
+
+ @Override
+ public void onSuccess(WinRmToolResponse val) {
+ for (String pollResponse : val.getStdOut().split("\r\n")) {
+ if (Strings.isNullOrEmpty(pollResponse)) {
+ continue;
+ }
+ String path = pollResponse.substring(0, OUTPUT_COLUMN_WIDTH - 1);
+ // The performance counter output prepends the sensor name with "\\<machinename>" so we need to remove it
+ Matcher machineNameLookbackMatcher = MACHINE_NAME_LOOKBACK_PATTERN.matcher(path);
+ if (!machineNameLookbackMatcher.find()) {
+ continue;
+ }
+ String name = machineNameLookbackMatcher.group(0).trim();
+ String rawValue = pollResponse.substring(OUTPUT_COLUMN_WIDTH).replaceAll("^\\s+", "");
+ WindowsPerformanceCounterPollConfig<?> config = getPollConfig(name);
+ Class<?> clazz = config.getSensor().getType();
+ AttributeSensor<Object> attribute = (AttributeSensor<Object>) Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
+ try {
+ Object value = TypeCoercions.coerce(rawValue, TypeToken.of(clazz));
+ entity.sensors().set(attribute, value);
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ if (failedAttributes.add(attribute)) {
+ log.warn("Failed to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
+ } else {
+ if (log.isTraceEnabled()) log.trace("Failed (repeatedly) to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onFailure(WinRmToolResponse val) {
+ log.error("Windows Performance Counter query did not respond as expected. exitcode={} stdout={} stderr={}",
+ new Object[]{val.getStatusCode(), val.getStdOut(), val.getStdErr()});
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ Class<?> clazz = config.getSensor().getType();
+ AttributeSensor<?> attribute = Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
+ entity.sensors().set(attribute, null);
+ }
+ }
+
+ @Override
+ public void onException(Exception exception) {
+ log.error("Detected exception while retrieving Windows Performance Counters from entity " +
+ entity.getDisplayName(), exception);
+ for (WindowsPerformanceCounterPollConfig<?> config : polls) {
+ entity.sensors().set(Sensors.newSensor(config.getSensor().getClass(), config.getPerformanceCounterName(), config.getDescription()), null);
+ }
+ }
+
+ @Override
+ public String getDescription() {
+ return "" + polls;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString()+"["+getDescription()+"]";
+ }
+
+ private WindowsPerformanceCounterPollConfig<?> getPollConfig(String sensorName) {
+ for (WindowsPerformanceCounterPollConfig<?> poll : polls) {
+ if (poll.getPerformanceCounterName().equalsIgnoreCase(sensorName)) {
+ return poll;
+ }
+ }
+ throw new IllegalStateException(String.format("%s not found in configured polls: %s", sensorName, polls));
+ }
+ }
+
+ static class PerfCounterValueIterator implements Iterator<String> {
+
+ // This pattern matches the contents of the first field, and optionally matches the rest of the line as
+ // further fields. Feed the second match back into the pattern again to get the next field, and repeat until
+ // all fields are discovered.
+ protected static final Pattern splitPerfData = Pattern.compile("^\"([^\\\"]*)\"((,\"[^\\\"]*\")*)$");
+
+ private Matcher matcher;
+
+ public PerfCounterValueIterator(String input) {
+ matcher = splitPerfData.matcher(input);
+ // Throw away the first element (the timestamp) (and also confirm that we have a pattern match)
+ checkArgument(hasNext(), "input "+input+" does not match expected pattern "+splitPerfData.pattern());
+ next();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return matcher != null && matcher.find();
+ }
+
+ @Override
+ public String next() {
+ String next = matcher.group(1);
+
+ String remainder = matcher.group(2);
+ if (!Strings.isNullOrEmpty(remainder)) {
+ assert remainder.startsWith(",");
+ remainder = remainder.substring(1);
+ matcher = splitPerfData.matcher(remainder);
+ } else {
+ matcher = null;
+ }
+
+ return next;
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+ }
+
+ private static enum QuoteStringFunction implements Function<String, String> {
+ INSTANCE;
+
+ @Nullable
+ @Override
+ public String apply(@Nullable String input) {
+ return input != null ? "\"" + input + "\"" : null;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
new file mode 100644
index 0000000..5d3a0c8
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
@@ -0,0 +1,80 @@
+/*
+ * 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.location.winrm;
+
+import org.apache.brooklyn.api.entity.Entity;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.api.sensor.SensorEvent;
+import org.apache.brooklyn.api.sensor.SensorEventListener;
+import org.apache.brooklyn.core.entity.AbstractEntity;
+import org.apache.brooklyn.core.policy.AbstractPolicy;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.Beta;
+
+/**
+ * When attached to an entity, this will monitor for when an {@link WinRmMachineLocation} is added to that entity
+ * (e.g. when a VM has been provisioned for it).
+ *
+ * The policy will then add a sensor that advertises the Administrator login details.
+ *
+ * A preferred mechanism would be for an external key-management tool to provide access to the credentials.
+ */
+@Beta
+public class AdvertiseWinrmLoginPolicy extends AbstractPolicy implements SensorEventListener<Location> {
+
+ // TODO Would like support user-creation over WinRM
+
+ private static final Logger LOG = LoggerFactory.getLogger(AdvertiseWinrmLoginPolicy.class);
+
+ public static final AttributeSensor<String> VM_USER_CREDENTIALS = Sensors.newStringSensor(
+ "vm.user.credentials",
+ "The \"<user> : <password> @ <hostname>:<port>\"");
+
+ public void setEntity(EntityLocal entity) {
+ super.setEntity(entity);
+ subscriptions().subscribe(entity, AbstractEntity.LOCATION_ADDED, this);
+ }
+
+ @Override
+ public void onEvent(SensorEvent<Location> event) {
+ final Entity entity = event.getSource();
+ final Location loc = event.getValue();
+ if (loc instanceof WinRmMachineLocation) {
+ advertiseUserAsync(entity, (WinRmMachineLocation)loc);
+ }
+ }
+
+ protected void advertiseUserAsync(final Entity entity, final WinRmMachineLocation machine) {
+ String user = machine.getUser();
+ String hostname = machine.getHostname();
+ int port = machine.config().get(WinRmMachineLocation.WINRM_PORT);
+ String password = machine.config().get(WinRmMachineLocation.PASSWORD);
+
+ String creds = user + " : " + password + " @ " +hostname + ":" + port;
+
+ LOG.info("Advertising user "+user+" @ "+hostname+":"+port);
+
+ ((EntityLocal)entity).sensors().set(VM_USER_CREDENTIALS, creds);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
new file mode 100644
index 0000000..3a7dbd5
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
@@ -0,0 +1,362 @@
+/*
+ * 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.location.winrm;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.annotation.Nullable;
+
+import org.apache.brooklyn.api.location.MachineDetails;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.OsDetails;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.location.AbstractLocation;
+import org.apache.brooklyn.core.location.access.PortForwardManager;
+import org.apache.commons.codec.binary.Base64;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Lists;
+import com.google.common.net.HostAndPort;
+import com.google.common.reflect.TypeToken;
+
+import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.apache.brooklyn.util.stream.Streams;
+import org.apache.brooklyn.util.time.Duration;
+import org.apache.brooklyn.util.time.Time;
+
+import io.cloudsoft.winrm4j.winrm.WinRmTool;
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
+
+ // FIXME Respect `port` config when using {@link WinRmTool}
+ public static final ConfigKey<Integer> WINRM_PORT = ConfigKeys.newIntegerConfigKey(
+ "port",
+ "WinRM port to use when connecting to the remote machine",
+ 5985);
+
+ // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}
+ public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user",
+ "Username to use when connecting to the remote machine");
+
+ // TODO merge with {link SshTool#PROP_PASSWORD}
+ public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password",
+ "Password to use when connecting to the remote machine");
+
+ public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey("windows.copy.file.size.bytes",
+ "Size of file chunks (in bytes) to be used when copying a file to the remote server", 1024);
+
+ public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
+ InetAddress.class,
+ "address",
+ "Address of the remote machine");
+
+ public static final ConfigKey<Integer> EXECUTION_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
+ "windows.exec.attempts",
+ "Number of attempts to execute a remote command",
+ 1);
+
+ // TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
+ public static final ConfigKey<Integer> EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
+ "execTries",
+ "Max number of times to attempt WinRM operations",
+ 10);
+
+ public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
+ new TypeToken<Iterable<String>>() {},
+ "privateAddresses",
+ "Private addresses of this machine, e.g. those within the private network",
+ null);
+
+ public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
+ new TypeToken<Map<Integer, String>>() {},
+ "tcpPortMappings",
+ "NAT'ed ports, giving the mapping from private TCP port to a public host:port",
+ null);
+
+ @Override
+ public InetAddress getAddress() {
+ return getConfig(ADDRESS);
+ }
+
+ @Override
+ public OsDetails getOsDetails() {
+ return null;
+ }
+
+ @Override
+ public MachineDetails getMachineDetails() {
+ return null;
+ }
+
+ @Nullable
+ @Override
+ public String getHostname() {
+ InetAddress address = getAddress();
+ return (address != null) ? address.getHostAddress() : null;
+ }
+
+ @Nullable
+ protected String getHostAndPort() {
+ String host = getHostname();
+ return (host == null) ? null : host + ":" + config().get(WINRM_PORT);
+ }
+
+ @Override
+ public Set<String> getPublicAddresses() {
+ InetAddress address = getAddress();
+ return (address == null) ? ImmutableSet.<String>of() : ImmutableSet.of(address.getHostAddress());
+ }
+
+ @Override
+ public Set<String> getPrivateAddresses() {
+ Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
+ return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
+ }
+
+ public WinRmToolResponse executeScript(String script) {
+ return executeScript(ImmutableList.of(script));
+ }
+
+ public WinRmToolResponse executeScript(List<String> script) {
+ int execTries = getRequiredConfig(EXEC_TRIES);
+ Collection<Throwable> exceptions = Lists.newArrayList();
+ for (int i = 0; i < execTries; i++) {
+ try {
+ return executeScriptNoRetry(script);
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ if (i == (execTries+1)) {
+ LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+ } else if (i == 0) {
+ LOG.warn("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
+ } else {
+ LOG.debug("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
+ }
+ exceptions.add(e);
+ }
+ }
+ throw Exceptions.propagate("failed to execute shell script", exceptions);
+ }
+
+ protected WinRmToolResponse executeScriptNoRetry(List<String> script) {
+ WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
+ WinRmToolResponse response = winRmTool.executeScript(script);
+ return response;
+ }
+
+ public WinRmToolResponse executePsScript(String psScript) {
+ return executePsScript(ImmutableList.of(psScript));
+ }
+
+ public WinRmToolResponse executePsScript(List<String> psScript) {
+ int execTries = getRequiredConfig(EXEC_TRIES);
+ Collection<Throwable> exceptions = Lists.newArrayList();
+ for (int i = 0; i < execTries; i++) {
+ try {
+ return executePsScriptNoRetry(psScript);
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ if (i == (execTries+1)) {
+ LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
+ } else if (i == 0) {
+ LOG.warn("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
+ Time.sleep(Duration.FIVE_SECONDS);
+ } else {
+ LOG.debug("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
+ Time.sleep(Duration.FIVE_SECONDS);
+ }
+ exceptions.add(e);
+ }
+ }
+ throw Exceptions.propagate("failed to execute powershell script", exceptions);
+ }
+
+ public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
+ WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
+ WinRmToolResponse response = winRmTool.executePs(psScript);
+ return response;
+ }
+
+ public int copyTo(File source, String destination) {
+ FileInputStream sourceStream = null;
+ try {
+ sourceStream = new FileInputStream(source);
+ return copyTo(sourceStream, destination);
+ } catch (FileNotFoundException e) {
+ throw Exceptions.propagate(e);
+ } finally {
+ if (sourceStream != null) {
+ Streams.closeQuietly(sourceStream);
+ }
+ }
+ }
+
+ public int copyTo(InputStream source, String destination) {
+ executePsScript(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
+ try {
+ int chunkSize = getConfig(COPY_FILE_CHUNK_SIZE_BYTES);
+ byte[] inputData = new byte[chunkSize];
+ int bytesRead;
+ int expectedFileSize = 0;
+ while ((bytesRead = source.read(inputData)) > 0) {
+ byte[] chunk;
+ if (bytesRead == chunkSize) {
+ chunk = inputData;
+ } else {
+ chunk = Arrays.copyOf(inputData, bytesRead);
+ }
+ executePsScript(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
+ expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
+ " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
+ expectedFileSize += bytesRead;
+ }
+
+ return 0;
+ } catch (java.io.IOException e) {
+ throw Exceptions.propagate(e);
+ }
+ }
+
+ @Override
+ public void init() {
+ super.init();
+
+ // Register any pre-existing port-mappings with the PortForwardManager
+ Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
+ if (tcpPortMappings != null) {
+ PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
+ for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
+ int targetPort = entry.getKey();
+ HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
+ if (!publicEndpoint.hasPort()) {
+ throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
+ }
+ pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
+ }
+ }
+ }
+ public String getUser() {
+ return config().get(USER);
+ }
+
+ private String getPassword() {
+ return config().get(PASSWORD);
+ }
+
+ private <T> T getRequiredConfig(ConfigKey<T> key) {
+ return checkNotNull(getConfig(key), "key %s must be set", key);
+ }
+
+ public static String getDefaultUserMetadataString() {
+ // Using an encoded command obviates the need to escape
+ String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
+ // Allow TS connections
+ "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices -Authentication PacketPrivacy",
+ "$RDP.SetAllowTSConnections(1,1)",
+ "Set-ExecutionPolicy Unrestricted -Force",
+ // Set unlimited values for remote execution limits
+ "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 100",
+ "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0",
+ "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 0",
+ "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0",
+ "New-ItemProperty \"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name \"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"",
+ // The following allows scripts to re-authenticate with local credential - this is required
+ // as certain operations cannot be performed with remote credentials
+ "$allowed = @('WSMAN/*')",
+ "$key = 'hklm:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CredentialsDelegation'",
+ "if (!(Test-Path $key)) {",
+ " md $key",
+ "}",
+ "New-ItemProperty -Path $key -Name AllowFreshCredentials -Value 1 -PropertyType Dword -Force",
+ "New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force",
+ "$credKey = Join-Path $key 'AllowFreshCredentials'",
+ "if (!(Test-Path $credKey)) {",
+ " md $credkey",
+ "}",
+ "$ntlmKey = Join-Path $key 'AllowFreshCredentialsWhenNTLMOnly'",
+ "if (!(Test-Path $ntlmKey)) {",
+ " md $ntlmKey",
+ "}",
+ "$i = 1",
+ "$allowed |% {",
+ " # Script does not take into account existing entries in this key",
+ " New-ItemProperty -Path $credKey -Name $i -Value $_ -PropertyType String -Force",
+ " New-ItemProperty -Path $ntlmKey -Name $i -Value $_ -PropertyType String -Force",
+ " $i++",
+ "}"
+ ));
+
+ String encoded = new String(Base64.encodeBase64(unencodePowershell.getBytes(Charsets.UTF_16LE)));
+ return "winrm quickconfig -q & " +
+ "winrm set winrm/config/service/auth @{Basic=\"true\"} & " +
+ "winrm set winrm/config/service/auth @{CredSSP=\"true\"} & " +
+ "winrm set winrm/config/client/auth @{CredSSP=\"true\"} & " +
+ "winrm set winrm/config/client @{AllowUnencrypted=\"true\"} & " +
+ "winrm set winrm/config/service @{AllowUnencrypted=\"true\"} & " +
+ "winrm set winrm/config/winrs @{MaxConcurrentUsers=\"100\"} & " +
+ "winrm set winrm/config/winrs @{MaxMemoryPerShellMB=\"0\"} & " +
+ "winrm set winrm/config/winrs @{MaxProcessesPerShell=\"0\"} & " +
+ "winrm set winrm/config/winrs @{MaxShellsPerUser=\"0\"} & " +
+ "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any & " +
+ "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any & " +
+ "powershell -EncodedCommand " + encoded;
+ /* TODO: Find out why scripts with new line characters aren't working on AWS. The following appears as if it *should*
+ work but doesn't - the script simply isn't run. By connecting to the machine via RDP, you can get the script
+ from 'http://169.254.169.254/latest/user-data', and running it at the command prompt works, but for some
+ reason the script isn't run when the VM is provisioned
+ */
+// return Joiner.on("\r\n").join(ImmutableList.of(
+// "winrm quickconfig -q",
+// "winrm set winrm/config/service/auth @{Basic=\"true\"}",
+// "winrm set winrm/config/client @{AllowUnencrypted=\"true\"}",
+// "winrm set winrm/config/service @{AllowUnencrypted=\"true\"}",
+// "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any",
+// "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any",
+// // Using an encoded command necessitates the need to escape. The unencoded command is as follows:
+// // $RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\CIMV2\TerminalServices -Authentication PacketPrivacy
+// // $Result = $RDP.SetAllowTSConnections(1,1)
+// "powershell -EncodedCommand JABSAEQAUAAgAD0AIABHAGUAdAAtAFcAbQBpAE8AYgBqAGUAYwB0ACAALQBDAGwAYQBzAHMAI" +
+// "ABXAGkAbgAzADIAXwBUAGUAcgBtAGkAbgBhAGwAUwBlAHIAdgBpAGMAZQBTAGUAdAB0AGkAbgBnACAALQBDAG8AbQBwA" +
+// "HUAdABlAHIATgBhAG0AZQAgACQAZQBuAHYAOgBjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQAgAC0ATgBhAG0AZQBzAHAAY" +
+// "QBjAGUAIAByAG8AbwB0AFwAQwBJAE0AVgAyAFwAVABlAHIAbQBpAG4AYQBsAFMAZQByAHYAaQBjAGUAcwAgAC0AQQB1A" +
+// "HQAaABlAG4AdABpAGMAYQB0AGkAbwBuACAAUABhAGMAawBlAHQAUAByAGkAdgBhAGMAeQANAAoAJABSAGUAcwB1AGwAd" +
+// "AAgAD0AIAAkAFIARABQAC4AUwBlAHQAQQBsAGwAbwB3AFQAUwBDAG8AbgBuAGUAYwB0AGkAbwBuAHMAKAAxACwAMQApAA=="
+// ));
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
new file mode 100644
index 0000000..de7d481
--- /dev/null
+++ b/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.feed.windows;
+
+import java.util.Map;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+
+/**
+ * WindowsPerformanceCounterFeed Live Test.
+ * <p>
+ * This test is currently disabled. To run, you must configure a location named {@code WindowsLiveTest}
+ * or adapt the {@link #LOCATION_SPEC} below.
+ * <p>
+ * The location must provide Windows nodes that are running an SSH server on port 22. The login credentials must
+ * be either be auto-detectable or configured in brooklyn.properties in the usual fashion.
+ * <p>
+ * Here is an example configuration from brooklyn.properties for a pre-configured Windows VM
+ * running an SSH server with public key authentication:
+ * <pre>
+ * {@code brooklyn.location.named.WindowsLiveTest=byon:(hosts="ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com")
+ * brooklyn.location.named.WindowsLiveTest.user=Administrator
+ * brooklyn.location.named.WindowsLiveTest.privateKeyFile = ~/.ssh/id_rsa
+ * brooklyn.location.named.WindowsLiveTest.publicKeyFile = ~/.ssh/id_rsa.pub
+ * }</pre>
+ * The location must by {@code byon} or another primitive type. Unfortunately, it's not possible to
+ * use a jclouds location, as adding a dependency on brooklyn-locations-jclouds would cause a
+ * cyclic dependency.
+ */
+public class WindowsPerformanceCounterFeedLiveTest extends BrooklynAppLiveTestSupport {
+
+ final static AttributeSensor<Double> CPU_IDLE_TIME = Sensors.newDoubleSensor("cpu.idleTime", "");
+ final static AttributeSensor<Integer> TELEPHONE_LINES = Sensors.newIntegerSensor("telephone.lines", "");
+
+ private static final String LOCATION_SPEC = "named:WindowsLiveTest";
+
+ private Location loc;
+ private EntityLocal entity;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ super.setUp();
+
+ Map<String,?> allFlags = MutableMap.<String,Object>builder()
+ .put("tags", ImmutableList.of(getClass().getName()))
+ .build();
+ MachineProvisioningLocation<? extends MachineLocation> provisioningLocation =
+ (MachineProvisioningLocation<? extends MachineLocation>)
+ mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
+ loc = provisioningLocation.obtain(ImmutableMap.of());
+
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @Test(groups={"Live","Disabled"}, enabled=false)
+ public void testRetrievesPerformanceCounters() throws Exception {
+ // We can be pretty sure that a Windows instance in the cloud will have zero telephone lines...
+ entity.sensors().set(TELEPHONE_LINES, 42);
+ WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
+ .entity(entity)
+ .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
+ .addSensor("\\Telephony\\Lines", TELEPHONE_LINES)
+ .build();
+ try {
+ EntityTestUtils.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
+ } finally {
+ feed.stop();
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java b/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
new file mode 100644
index 0000000..059797b
--- /dev/null
+++ b/software/winrm/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
@@ -0,0 +1,130 @@
+/*
+ * 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.feed.windows;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.Location;
+import org.apache.brooklyn.api.sensor.AttributeSensor;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
+
+import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class WindowsPerformanceCounterFeedTest extends BrooklynAppUnitTestSupport {
+
+ private Location loc;
+ private EntityLocal entity;
+
+ @BeforeMethod(alwaysRun=true)
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ loc = new LocalhostMachineProvisioningLocation();
+ entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
+ app.start(ImmutableList.of(loc));
+ }
+
+ @AfterMethod(alwaysRun=true)
+ @Override
+ public void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeedTest.class);
+
+ @Test
+ public void testIteratorWithSingleValue() {
+ Iterator<?> iterator = new WindowsPerformanceCounterFeed
+ .PerfCounterValueIterator("\"10/14/2013 15:28:24.406\",\"0.000000\"");
+ assertTrue(iterator.hasNext());
+ assertEquals(iterator.next(), "0.000000");
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ public void testIteratorWithMultipleValues() {
+ Iterator<?> iterator = new WindowsPerformanceCounterFeed
+ .PerfCounterValueIterator("\"10/14/2013 15:35:50.582\",\"8803.000000\",\"405622.000000\"");
+ assertTrue(iterator.hasNext());
+ assertEquals(iterator.next(), "8803.000000");
+ assertTrue(iterator.hasNext());
+ assertEquals(iterator.next(), "405622.000000");
+ assertFalse(iterator.hasNext());
+ }
+
+ @Test
+ public void testSendPerfCountersToSensors() {
+ AttributeSensor<String> stringSensor = Sensors.newStringSensor("foo.bar");
+ AttributeSensor<Integer> integerSensor = Sensors.newIntegerSensor("bar.baz");
+ AttributeSensor<Double> doubleSensor = Sensors.newDoubleSensor("baz.quux");
+
+ Collection<WindowsPerformanceCounterPollConfig<?>> polls = ImmutableSet.<WindowsPerformanceCounterPollConfig<?>>of(
+ new WindowsPerformanceCounterPollConfig(stringSensor).performanceCounterName("\\processor information(_total)\\% processor time"),
+ new WindowsPerformanceCounterPollConfig(integerSensor).performanceCounterName("\\integer.sensor"),
+ new WindowsPerformanceCounterPollConfig(doubleSensor).performanceCounterName("\\double\\sensor\\with\\multiple\\sub\\paths")
+ );
+
+ WindowsPerformanceCounterFeed.SendPerfCountersToSensors sendPerfCountersToSensors = new WindowsPerformanceCounterFeed.SendPerfCountersToSensors(entity, polls);
+
+ assertNull(entity.getAttribute(stringSensor));
+
+ StringBuilder responseBuilder = new StringBuilder();
+ // NOTE: This builds the response in a different order to which they are passed to the SendPerfCountersToSensors constructor
+ // this tests that the values are applied correctly even if the (possibly non-deterministic) order in which
+ // they are returned by the Get-Counter scriptlet is different
+ addMockResponse(responseBuilder, "\\\\machine.name\\double\\sensor\\with\\multiple\\sub\\paths", "3.1415926");
+ addMockResponse(responseBuilder, "\\\\win-lge7uj2blau\\processor information(_total)\\% processor time", "99.9");
+ addMockResponse(responseBuilder, "\\\\machine.name\\integer.sensor", "15");
+
+ sendPerfCountersToSensors.onSuccess(new WinRmToolResponse(responseBuilder.toString(), "", 0));
+
+ EntityTestUtils.assertAttributeEquals(entity, stringSensor, "99.9");
+ EntityTestUtils.assertAttributeEquals(entity, integerSensor, 15);
+ EntityTestUtils.assertAttributeEquals(entity, doubleSensor, 3.1415926);
+ }
+
+ private void addMockResponse(StringBuilder responseBuilder, String path, String value) {
+ responseBuilder.append(path);
+ responseBuilder.append(Strings.repeat(" ", 200 - (path.length() + value.length())));
+ responseBuilder.append(value);
+ responseBuilder.append("\r\n");
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java b/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java
new file mode 100644
index 0000000..53b95c8
--- /dev/null
+++ b/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java
@@ -0,0 +1,49 @@
+/*
+ * 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.location.winrm;
+
+import org.apache.brooklyn.api.entity.EntitySpec;
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.api.policy.PolicySpec;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.core.test.entity.TestEntity;
+import org.apache.brooklyn.test.EntityTestUtils;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class AdvertiseWinrmLoginPolicyTest extends BrooklynAppUnitTestSupport {
+
+ @Test
+ public void testAdvertisesMachineLoginDetails() throws Exception {
+ TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
+ .policy(PolicySpec.create(AdvertiseWinrmLoginPolicy.class)));
+
+ WinRmMachineLocation machine = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
+ .configure("address", "1.2.3.4")
+ .configure("user", "myuser")
+ .configure("port", 5678)
+ .configure("password", "mypassword"));
+ app.start(ImmutableList.of(machine));
+
+ String expected = "myuser : mypassword @ 1.2.3.4:5678";
+
+ EntityTestUtils.assertAttributeEqualsEventually(entity, AdvertiseWinrmLoginPolicy.VM_USER_CREDENTIALS, expected);
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java b/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java
new file mode 100644
index 0000000..9fa0fe7
--- /dev/null
+++ b/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java
@@ -0,0 +1,43 @@
+/*
+ * 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.location.winrm;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.brooklyn.api.location.LocationSpec;
+import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
+import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
+import org.apache.brooklyn.util.net.Networking;
+import org.testng.annotations.Test;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
+public class WinRmMachineLocationTest extends BrooklynAppUnitTestSupport {
+
+ @Test
+ public void testConfigurePrivateAddresses() throws Exception {
+ WinRmMachineLocation host = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
+ .configure("address", Networking.getLocalHost())
+ .configure(WinRmMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
+ .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
+
+ assertEquals(host.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
+ }
+}
[2/7] incubator-brooklyn git commit: [BROOKLYN-182] Move
winrm-dependent code from brooklyn-core to brooklyn-software-winrm
Posted by ha...@apache.org.
[BROOKLYN-182] Move winrm-dependent code from brooklyn-core to brooklyn-software-winrm
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/8fa4df7d
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/8fa4df7d
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/8fa4df7d
Branch: refs/heads/master
Commit: 8fa4df7ddd525883553c5c57828426da31961020
Parents: 49eabd1
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Oct 14 17:15:56 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Oct 14 23:36:22 2015 +0300
----------------------------------------------------------------------
core/pom.xml | 5 -
.../location/access/BrooklynAccessUtils.java | 3 +-
.../WindowsPerformanceCounterSensors.java | 73 ----
.../windows/WindowsPerformanceCounterFeed.java | 412 ------------------
.../winrm/AdvertiseWinrmLoginPolicy.java | 80 ----
.../location/winrm/WinRmMachineLocation.java | 362 ----------------
.../core/plan/XmlPlanToSpecTransformerTest.java | 2 +-
.../WindowsPerformanceCounterFeedLiveTest.java | 104 -----
.../WindowsPerformanceCounterFeedTest.java | 132 ------
.../winrm/AdvertiseWinrmLoginPolicyTest.java | 51 ---
.../winrm/WinRmMachineLocationTest.java | 44 --
pom.xml | 1 +
software/winrm/pom.xml | 45 ++
.../WindowsPerformanceCounterSensors.java | 73 ++++
.../windows/WindowsPerformanceCounterFeed.java | 414 +++++++++++++++++++
.../winrm/AdvertiseWinrmLoginPolicy.java | 80 ++++
.../location/winrm/WinRmMachineLocation.java | 362 ++++++++++++++++
.../WindowsPerformanceCounterFeedLiveTest.java | 103 +++++
.../WindowsPerformanceCounterFeedTest.java | 130 ++++++
.../winrm/AdvertiseWinrmLoginPolicyTest.java | 49 +++
.../winrm/WinRmMachineLocationTest.java | 43 ++
21 files changed, 1302 insertions(+), 1266 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/pom.xml
----------------------------------------------------------------------
diff --git a/core/pom.xml b/core/pom.xml
index 7239baf..66ac533 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -54,11 +54,6 @@
<version>${project.version}</version>
</dependency>
<dependency>
- <groupId>io.cloudsoft.windows</groupId>
- <artifactId>winrm4j</artifactId>
- <version>${winrm4j.version}</version>
- </dependency>
- <dependency>
<groupId>net.schmizz</groupId>
<artifactId>sshj</artifactId>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/main/java/org/apache/brooklyn/core/location/access/BrooklynAccessUtils.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/access/BrooklynAccessUtils.java b/core/src/main/java/org/apache/brooklyn/core/location/access/BrooklynAccessUtils.java
index 1ac354f..b36ddf6 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/access/BrooklynAccessUtils.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/access/BrooklynAccessUtils.java
@@ -39,8 +39,7 @@ import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.net.Cidr;
import org.apache.brooklyn.util.text.Strings;
-import org.python.google.common.base.Predicates;
-import org.python.google.common.collect.Iterables;
+import com.google.common.collect.Iterables;
import com.google.common.base.Supplier;
import com.google.common.net.HostAndPort;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java b/core/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java
deleted file mode 100644
index f5c2271..0000000
--- a/core/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.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.core.sensor.windows;
-
-import java.util.Map;
-import java.util.Set;
-
-import org.apache.brooklyn.api.entity.EntityInitializer;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
-import org.apache.brooklyn.util.core.config.ConfigBag;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.reflect.TypeToken;
-
-public class WindowsPerformanceCounterSensors implements EntityInitializer {
-
- private static final Logger LOG = LoggerFactory.getLogger(WindowsPerformanceCounterSensors.class);
-
- public final static ConfigKey<Set<Map<String, String>>> PERFORMANCE_COUNTERS = ConfigKeys.newConfigKey(new TypeToken<Set<Map<String, String>>>(){}, "performance.counters");
-
- protected final Set<Map<String, String>> sensors;
-
- public WindowsPerformanceCounterSensors(ConfigBag params) {
- sensors = params.get(PERFORMANCE_COUNTERS);
- }
-
- public WindowsPerformanceCounterSensors(Map<String, String> params) {
- this(ConfigBag.newInstance(params));
- }
-
- @Override
- public void apply(EntityLocal entity) {
- WindowsPerformanceCounterFeed.Builder builder = WindowsPerformanceCounterFeed.builder()
- .entity(entity);
- for (Map<String, String> sensorConfig : sensors) {
- String name = sensorConfig.get("name");
- String sensorType = sensorConfig.get("sensorType");
- Class<?> clazz;
- try {
- clazz = Strings.isNonEmpty(sensorType)
- ? ((EntityInternal)entity).getManagementContext().getCatalog().getRootClassLoader().loadClass(sensorType)
- : String.class;
- } catch (ClassNotFoundException e) {
- throw new IllegalStateException("Could not load type "+sensorType+" for sensor "+name, e);
- }
- builder.addSensor(sensorConfig.get("counter"), Sensors.newSensor(clazz, name, sensorConfig.get("description")));
- }
- builder.build();
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
deleted file mode 100644
index 07cb8ea..0000000
--- a/core/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
+++ /dev/null
@@ -1,412 +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.feed.windows;
-
-import static com.google.common.base.Preconditions.checkArgument;
-import static com.google.common.base.Preconditions.checkNotNull;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Callable;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.mgmt.ExecutionContext;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.effector.EffectorTasks;
-import org.apache.brooklyn.core.entity.EntityInternal;
-import org.apache.brooklyn.core.feed.AbstractFeed;
-import org.apache.brooklyn.core.feed.PollHandler;
-import org.apache.brooklyn.core.feed.Poller;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-import org.apache.brooklyn.util.core.flags.TypeCoercions;
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.time.Duration;
-
-import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
-import com.google.common.base.Joiner;
-import com.google.common.base.Strings;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import com.google.common.reflect.TypeToken;
-
-/**
- * A sensor feed that retrieves performance counters from a Windows host and posts the values to sensors.
- *
- * <p>To use this feed, you must provide the entity, and a collection of mappings between Windows performance counter
- * names and Brooklyn attribute sensors.</p>
- *
- * <p>This feed uses SSH to invoke the windows utility <tt>typeperf</tt> to query for a specific set of performance
- * counters, by name. The values are extracted from the response, and published to the entity's sensors.</p>
- *
- * <p>Example:</p>
- *
- * {@code
- * @Override
- * protected void connectSensors() {
- * WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
- * .entity(entity)
- * .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
- * .addSensor("\\Memory\\Available MBytes", AVAILABLE_MEMORY)
- * .build();
- * }
- * }
- *
- * @since 0.6.0
- * @author richardcloudsoft
- */
-public class WindowsPerformanceCounterFeed extends AbstractFeed {
-
- private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeed.class);
-
- // This pattern matches CSV line(s) with the date in the first field, and at least one further field.
- protected static final Pattern lineWithPerfData = Pattern.compile("^\"[\\d:/\\-. ]+\",\".*\"$", Pattern.MULTILINE);
- private static final Joiner JOINER_ON_SPACE = Joiner.on(' ');
- private static final Joiner JOINER_ON_COMMA = Joiner.on(',');
- private static final int OUTPUT_COLUMN_WIDTH = 100;
-
- @SuppressWarnings("serial")
- public static final ConfigKey<Collection<WindowsPerformanceCounterPollConfig<?>>> POLLS = ConfigKeys.newConfigKey(
- new TypeToken<Collection<WindowsPerformanceCounterPollConfig<?>>>() {},
- "polls");
-
- public static Builder builder() {
- return new Builder();
- }
-
- public static class Builder {
- private EntityLocal entity;
- private Set<WindowsPerformanceCounterPollConfig<?>> polls = Sets.newLinkedHashSet();
- private Duration period = Duration.of(30, TimeUnit.SECONDS);
- private String uniqueTag;
- private volatile boolean built;
-
- public Builder entity(EntityLocal val) {
- this.entity = checkNotNull(val, "entity");
- return this;
- }
- public Builder addSensor(WindowsPerformanceCounterPollConfig<?> config) {
- polls.add(config);
- return this;
- }
- public Builder addSensor(String performanceCounterName, AttributeSensor<?> sensor) {
- return addSensor(new WindowsPerformanceCounterPollConfig(sensor).performanceCounterName(checkNotNull(performanceCounterName, "performanceCounterName")));
- }
- public Builder addSensors(Map<String, AttributeSensor> sensors) {
- for (Map.Entry<String, AttributeSensor> entry : sensors.entrySet()) {
- addSensor(entry.getKey(), entry.getValue());
- }
- return this;
- }
- public Builder period(Duration period) {
- this.period = checkNotNull(period, "period");
- return this;
- }
- public Builder period(long millis) {
- return period(millis, TimeUnit.MILLISECONDS);
- }
- public Builder period(long val, TimeUnit units) {
- return period(Duration.of(val, units));
- }
- public Builder uniqueTag(String uniqueTag) {
- this.uniqueTag = uniqueTag;
- return this;
- }
- public WindowsPerformanceCounterFeed build() {
- built = true;
- WindowsPerformanceCounterFeed result = new WindowsPerformanceCounterFeed(this);
- result.setEntity(checkNotNull(entity, "entity"));
- result.start();
- return result;
- }
- @Override
- protected void finalize() {
- if (!built) log.warn("WindowsPerformanceCounterFeed.Builder created, but build() never called");
- }
- }
-
- /**
- * For rebind; do not call directly; use builder
- */
- public WindowsPerformanceCounterFeed() {
- }
-
- protected WindowsPerformanceCounterFeed(Builder builder) {
- List<WindowsPerformanceCounterPollConfig<?>> polls = Lists.newArrayList();
- for (WindowsPerformanceCounterPollConfig<?> config : builder.polls) {
- if (!config.isEnabled()) continue;
- @SuppressWarnings({ "unchecked", "rawtypes" })
- WindowsPerformanceCounterPollConfig<?> configCopy = new WindowsPerformanceCounterPollConfig(config);
- if (configCopy.getPeriod() < 0) configCopy.period(builder.period);
- polls.add(configCopy);
- }
- config().set(POLLS, polls);
- initUniqueTag(builder.uniqueTag, polls);
- }
-
- @Override
- protected void preStart() {
- Collection<WindowsPerformanceCounterPollConfig<?>> polls = getConfig(POLLS);
-
- long minPeriod = Integer.MAX_VALUE;
- List<String> performanceCounterNames = Lists.newArrayList();
- for (WindowsPerformanceCounterPollConfig<?> config : polls) {
- minPeriod = Math.min(minPeriod, config.getPeriod());
- performanceCounterNames.add(config.getPerformanceCounterName());
- }
-
- Iterable<String> allParams = ImmutableList.<String>builder()
- .add("(Get-Counter")
- .add("-Counter")
- .add(JOINER_ON_COMMA.join(Iterables.transform(performanceCounterNames, QuoteStringFunction.INSTANCE)))
- .add("-SampleInterval")
- .add("2") // TODO: extract SampleInterval as a config key
- .add(").CounterSamples")
- .add("|")
- .add("Format-Table")
- .add(String.format("@{Expression={$_.Path};width=%d},@{Expression={$_.CookedValue};width=%<d}", OUTPUT_COLUMN_WIDTH))
- .add("-HideTableHeaders")
- .add("|")
- .add("Out-String")
- .add("-Width")
- .add(String.valueOf(OUTPUT_COLUMN_WIDTH * 2))
- .build();
- String command = JOINER_ON_SPACE.join(allParams);
- log.debug("Windows performance counter poll command for {} will be: {}", entity, command);
-
- GetPerformanceCountersJob<WinRmToolResponse> job = new GetPerformanceCountersJob(getEntity(), command);
- getPoller().scheduleAtFixedRate(
- new CallInEntityExecutionContext(entity, job),
- new SendPerfCountersToSensors(getEntity(), polls),
- minPeriod);
- }
-
- private static class GetPerformanceCountersJob<T> implements Callable<T> {
-
- private final Entity entity;
- private final String command;
-
- GetPerformanceCountersJob(Entity entity, String command) {
- this.entity = entity;
- this.command = command;
- }
-
- @Override
- public T call() throws Exception {
- WinRmMachineLocation machine = EffectorTasks.getWinRmMachine(entity);
- WinRmToolResponse response = machine.executePsScript(command);
- return (T)response;
- }
- }
-
- @SuppressWarnings("unchecked")
- protected Poller<WinRmToolResponse> getPoller() {
- return (Poller<WinRmToolResponse>) super.getPoller();
- }
-
- /**
- * A {@link java.util.concurrent.Callable} that wraps another {@link java.util.concurrent.Callable}, where the
- * inner {@link java.util.concurrent.Callable} is executed in the context of a
- * specific entity.
- *
- * @param <T> The type of the {@link java.util.concurrent.Callable}.
- */
- private static class CallInEntityExecutionContext<T> implements Callable<T> {
- private final Callable<T> job;
- private EntityLocal entity;
-
- private CallInEntityExecutionContext(EntityLocal entity, Callable<T> job) {
- this.job = job;
- this.entity = entity;
- }
-
- @Override
- public T call() throws Exception {
- ExecutionContext executionContext = ((EntityInternal) entity).getManagementSupport().getExecutionContext();
- return executionContext.submit(Maps.newHashMap(), job).get();
- }
- }
-
- @VisibleForTesting
- static class SendPerfCountersToSensors implements PollHandler<WinRmToolResponse> {
- private final EntityLocal entity;
- private final List<WindowsPerformanceCounterPollConfig<?>> polls;
- private final Set<AttributeSensor<?>> failedAttributes = Sets.newLinkedHashSet();
- private static final Pattern MACHINE_NAME_LOOKBACK_PATTERN = Pattern.compile(String.format("(?<=\\\\\\\\.{0,%d})\\\\.*", OUTPUT_COLUMN_WIDTH));
-
- public SendPerfCountersToSensors(EntityLocal entity, Collection<WindowsPerformanceCounterPollConfig<?>> polls) {
- this.entity = entity;
- this.polls = ImmutableList.copyOf(polls);
- }
-
- @Override
- public boolean checkSuccess(WinRmToolResponse val) {
- // TODO not just using statusCode; also looking at absence of stderr.
- // Status code is (empirically) unreliable: it returns 0 sometimes even when failed
- // (but never returns non-zero on success).
- if (val.getStatusCode() != 0) return false;
- String stderr = val.getStdErr();
- if (stderr == null || stderr.length() != 0) return false;
- String out = val.getStdOut();
- if (out == null || out.length() == 0) return false;
- return true;
- }
-
- @Override
- public void onSuccess(WinRmToolResponse val) {
- for (String pollResponse : val.getStdOut().split("\r\n")) {
- if (Strings.isNullOrEmpty(pollResponse)) {
- continue;
- }
- String path = pollResponse.substring(0, OUTPUT_COLUMN_WIDTH - 1);
- // The performance counter output prepends the sensor name with "\\<machinename>" so we need to remove it
- Matcher machineNameLookbackMatcher = MACHINE_NAME_LOOKBACK_PATTERN.matcher(path);
- if (!machineNameLookbackMatcher.find()) {
- continue;
- }
- String name = machineNameLookbackMatcher.group(0).trim();
- String rawValue = pollResponse.substring(OUTPUT_COLUMN_WIDTH).replaceAll("^\\s+", "");
- WindowsPerformanceCounterPollConfig<?> config = getPollConfig(name);
- Class<?> clazz = config.getSensor().getType();
- AttributeSensor<Object> attribute = (AttributeSensor<Object>) Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
- try {
- Object value = TypeCoercions.coerce(rawValue, TypeToken.of(clazz));
- entity.sensors().set(attribute, value);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (failedAttributes.add(attribute)) {
- log.warn("Failed to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
- } else {
- if (log.isTraceEnabled()) log.trace("Failed (repeatedly) to coerce value '{}' to {} for {} -> {}", new Object[] {rawValue, clazz, entity, attribute});
- }
- }
- }
- }
-
- @Override
- public void onFailure(WinRmToolResponse val) {
- log.error("Windows Performance Counter query did not respond as expected. exitcode={} stdout={} stderr={}",
- new Object[]{val.getStatusCode(), val.getStdOut(), val.getStdErr()});
- for (WindowsPerformanceCounterPollConfig<?> config : polls) {
- Class<?> clazz = config.getSensor().getType();
- AttributeSensor<?> attribute = Sensors.newSensor(clazz, config.getSensor().getName(), config.getDescription());
- entity.sensors().set(attribute, null);
- }
- }
-
- @Override
- public void onException(Exception exception) {
- log.error("Detected exception while retrieving Windows Performance Counters from entity " +
- entity.getDisplayName(), exception);
- for (WindowsPerformanceCounterPollConfig<?> config : polls) {
- entity.sensors().set(Sensors.newSensor(config.getSensor().getClass(), config.getPerformanceCounterName(), config.getDescription()), null);
- }
- }
-
- @Override
- public String getDescription() {
- return "" + polls;
- }
-
- @Override
- public String toString() {
- return super.toString()+"["+getDescription()+"]";
- }
-
- private WindowsPerformanceCounterPollConfig<?> getPollConfig(String sensorName) {
- for (WindowsPerformanceCounterPollConfig<?> poll : polls) {
- if (poll.getPerformanceCounterName().equalsIgnoreCase(sensorName)) {
- return poll;
- }
- }
- throw new IllegalStateException(String.format("%s not found in configured polls: %s", sensorName, polls));
- }
- }
-
- static class PerfCounterValueIterator implements Iterator<String> {
-
- // This pattern matches the contents of the first field, and optionally matches the rest of the line as
- // further fields. Feed the second match back into the pattern again to get the next field, and repeat until
- // all fields are discovered.
- protected static final Pattern splitPerfData = Pattern.compile("^\"([^\\\"]*)\"((,\"[^\\\"]*\")*)$");
-
- private Matcher matcher;
-
- public PerfCounterValueIterator(String input) {
- matcher = splitPerfData.matcher(input);
- // Throw away the first element (the timestamp) (and also confirm that we have a pattern match)
- checkArgument(hasNext(), "input "+input+" does not match expected pattern "+splitPerfData.pattern());
- next();
- }
-
- @Override
- public boolean hasNext() {
- return matcher != null && matcher.find();
- }
-
- @Override
- public String next() {
- String next = matcher.group(1);
-
- String remainder = matcher.group(2);
- if (!Strings.isNullOrEmpty(remainder)) {
- assert remainder.startsWith(",");
- remainder = remainder.substring(1);
- matcher = splitPerfData.matcher(remainder);
- } else {
- matcher = null;
- }
-
- return next;
- }
-
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- }
-
- private static enum QuoteStringFunction implements Function<String, String> {
- INSTANCE;
-
- @Nullable
- @Override
- public String apply(@Nullable String input) {
- return input != null ? "\"" + input + "\"" : null;
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java b/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
deleted file mode 100644
index 5d3a0c8..0000000
--- a/core/src/main/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicy.java
+++ /dev/null
@@ -1,80 +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.location.winrm;
-
-import org.apache.brooklyn.api.entity.Entity;
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.api.sensor.SensorEvent;
-import org.apache.brooklyn.api.sensor.SensorEventListener;
-import org.apache.brooklyn.core.entity.AbstractEntity;
-import org.apache.brooklyn.core.policy.AbstractPolicy;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.annotations.Beta;
-
-/**
- * When attached to an entity, this will monitor for when an {@link WinRmMachineLocation} is added to that entity
- * (e.g. when a VM has been provisioned for it).
- *
- * The policy will then add a sensor that advertises the Administrator login details.
- *
- * A preferred mechanism would be for an external key-management tool to provide access to the credentials.
- */
-@Beta
-public class AdvertiseWinrmLoginPolicy extends AbstractPolicy implements SensorEventListener<Location> {
-
- // TODO Would like support user-creation over WinRM
-
- private static final Logger LOG = LoggerFactory.getLogger(AdvertiseWinrmLoginPolicy.class);
-
- public static final AttributeSensor<String> VM_USER_CREDENTIALS = Sensors.newStringSensor(
- "vm.user.credentials",
- "The \"<user> : <password> @ <hostname>:<port>\"");
-
- public void setEntity(EntityLocal entity) {
- super.setEntity(entity);
- subscriptions().subscribe(entity, AbstractEntity.LOCATION_ADDED, this);
- }
-
- @Override
- public void onEvent(SensorEvent<Location> event) {
- final Entity entity = event.getSource();
- final Location loc = event.getValue();
- if (loc instanceof WinRmMachineLocation) {
- advertiseUserAsync(entity, (WinRmMachineLocation)loc);
- }
- }
-
- protected void advertiseUserAsync(final Entity entity, final WinRmMachineLocation machine) {
- String user = machine.getUser();
- String hostname = machine.getHostname();
- int port = machine.config().get(WinRmMachineLocation.WINRM_PORT);
- String password = machine.config().get(WinRmMachineLocation.PASSWORD);
-
- String creds = user + " : " + password + " @ " +hostname + ":" + port;
-
- LOG.info("Advertising user "+user+" @ "+hostname+":"+port);
-
- ((EntityLocal)entity).sensors().set(VM_USER_CREDENTIALS, creds);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java b/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
deleted file mode 100644
index 3a7dbd5..0000000
--- a/core/src/main/java/org/apache/brooklyn/location/winrm/WinRmMachineLocation.java
+++ /dev/null
@@ -1,362 +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.location.winrm;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.InputStream;
-import java.net.InetAddress;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.annotation.Nullable;
-
-import org.apache.brooklyn.api.location.MachineDetails;
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.api.location.OsDetails;
-import org.apache.brooklyn.config.ConfigKey;
-import org.apache.brooklyn.core.config.ConfigKeys;
-import org.apache.brooklyn.core.location.AbstractLocation;
-import org.apache.brooklyn.core.location.access.PortForwardManager;
-import org.apache.commons.codec.binary.Base64;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Charsets;
-import com.google.common.base.Joiner;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Lists;
-import com.google.common.net.HostAndPort;
-import com.google.common.reflect.TypeToken;
-
-import org.apache.brooklyn.util.exceptions.Exceptions;
-import org.apache.brooklyn.util.stream.Streams;
-import org.apache.brooklyn.util.time.Duration;
-import org.apache.brooklyn.util.time.Time;
-
-import io.cloudsoft.winrm4j.winrm.WinRmTool;
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-public class WinRmMachineLocation extends AbstractLocation implements MachineLocation {
-
- private static final Logger LOG = LoggerFactory.getLogger(WinRmMachineLocation.class);
-
- // FIXME Respect `port` config when using {@link WinRmTool}
- public static final ConfigKey<Integer> WINRM_PORT = ConfigKeys.newIntegerConfigKey(
- "port",
- "WinRM port to use when connecting to the remote machine",
- 5985);
-
- // TODO merge with {link SshTool#PROP_USER} and {@link SshMachineLocation#user}
- public static final ConfigKey<String> USER = ConfigKeys.newStringConfigKey("user",
- "Username to use when connecting to the remote machine");
-
- // TODO merge with {link SshTool#PROP_PASSWORD}
- public static final ConfigKey<String> PASSWORD = ConfigKeys.newStringConfigKey("password",
- "Password to use when connecting to the remote machine");
-
- public static final ConfigKey<Integer> COPY_FILE_CHUNK_SIZE_BYTES = ConfigKeys.newIntegerConfigKey("windows.copy.file.size.bytes",
- "Size of file chunks (in bytes) to be used when copying a file to the remote server", 1024);
-
- public static final ConfigKey<InetAddress> ADDRESS = ConfigKeys.newConfigKey(
- InetAddress.class,
- "address",
- "Address of the remote machine");
-
- public static final ConfigKey<Integer> EXECUTION_ATTEMPTS = ConfigKeys.newIntegerConfigKey(
- "windows.exec.attempts",
- "Number of attempts to execute a remote command",
- 1);
-
- // TODO See SshTool#PROP_SSH_TRIES, where it was called "sshTries"; remove duplication? Merge into one well-named thing?
- public static final ConfigKey<Integer> EXEC_TRIES = ConfigKeys.newIntegerConfigKey(
- "execTries",
- "Max number of times to attempt WinRM operations",
- 10);
-
- public static final ConfigKey<Iterable<String>> PRIVATE_ADDRESSES = ConfigKeys.newConfigKey(
- new TypeToken<Iterable<String>>() {},
- "privateAddresses",
- "Private addresses of this machine, e.g. those within the private network",
- null);
-
- public static final ConfigKey<Map<Integer, String>> TCP_PORT_MAPPINGS = ConfigKeys.newConfigKey(
- new TypeToken<Map<Integer, String>>() {},
- "tcpPortMappings",
- "NAT'ed ports, giving the mapping from private TCP port to a public host:port",
- null);
-
- @Override
- public InetAddress getAddress() {
- return getConfig(ADDRESS);
- }
-
- @Override
- public OsDetails getOsDetails() {
- return null;
- }
-
- @Override
- public MachineDetails getMachineDetails() {
- return null;
- }
-
- @Nullable
- @Override
- public String getHostname() {
- InetAddress address = getAddress();
- return (address != null) ? address.getHostAddress() : null;
- }
-
- @Nullable
- protected String getHostAndPort() {
- String host = getHostname();
- return (host == null) ? null : host + ":" + config().get(WINRM_PORT);
- }
-
- @Override
- public Set<String> getPublicAddresses() {
- InetAddress address = getAddress();
- return (address == null) ? ImmutableSet.<String>of() : ImmutableSet.of(address.getHostAddress());
- }
-
- @Override
- public Set<String> getPrivateAddresses() {
- Iterable<String> result = getConfig(PRIVATE_ADDRESSES);
- return (result == null) ? ImmutableSet.<String>of() : ImmutableSet.copyOf(result);
- }
-
- public WinRmToolResponse executeScript(String script) {
- return executeScript(ImmutableList.of(script));
- }
-
- public WinRmToolResponse executeScript(List<String> script) {
- int execTries = getRequiredConfig(EXEC_TRIES);
- Collection<Throwable> exceptions = Lists.newArrayList();
- for (int i = 0; i < execTries; i++) {
- try {
- return executeScriptNoRetry(script);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (i == (execTries+1)) {
- LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
- } else if (i == 0) {
- LOG.warn("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
- } else {
- LOG.debug("Ignoring WinRM exception and retrying (attempt "+(i+1)+" of "+execTries+")", e);
- }
- exceptions.add(e);
- }
- }
- throw Exceptions.propagate("failed to execute shell script", exceptions);
- }
-
- protected WinRmToolResponse executeScriptNoRetry(List<String> script) {
- WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
- WinRmToolResponse response = winRmTool.executeScript(script);
- return response;
- }
-
- public WinRmToolResponse executePsScript(String psScript) {
- return executePsScript(ImmutableList.of(psScript));
- }
-
- public WinRmToolResponse executePsScript(List<String> psScript) {
- int execTries = getRequiredConfig(EXEC_TRIES);
- Collection<Throwable> exceptions = Lists.newArrayList();
- for (int i = 0; i < execTries; i++) {
- try {
- return executePsScriptNoRetry(psScript);
- } catch (Exception e) {
- Exceptions.propagateIfFatal(e);
- if (i == (execTries+1)) {
- LOG.info("Propagating WinRM exception (attempt "+(i+1)+" of "+execTries+")", e);
- } else if (i == 0) {
- LOG.warn("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
- Time.sleep(Duration.FIVE_SECONDS);
- } else {
- LOG.debug("Ignoring WinRM exception and retrying after 5 seconds (attempt "+(i+1)+" of "+execTries+")", e);
- Time.sleep(Duration.FIVE_SECONDS);
- }
- exceptions.add(e);
- }
- }
- throw Exceptions.propagate("failed to execute powershell script", exceptions);
- }
-
- public WinRmToolResponse executePsScriptNoRetry(List<String> psScript) {
- WinRmTool winRmTool = WinRmTool.connect(getHostAndPort(), getUser(), getPassword());
- WinRmToolResponse response = winRmTool.executePs(psScript);
- return response;
- }
-
- public int copyTo(File source, String destination) {
- FileInputStream sourceStream = null;
- try {
- sourceStream = new FileInputStream(source);
- return copyTo(sourceStream, destination);
- } catch (FileNotFoundException e) {
- throw Exceptions.propagate(e);
- } finally {
- if (sourceStream != null) {
- Streams.closeQuietly(sourceStream);
- }
- }
- }
-
- public int copyTo(InputStream source, String destination) {
- executePsScript(ImmutableList.of("rm -ErrorAction SilentlyContinue " + destination));
- try {
- int chunkSize = getConfig(COPY_FILE_CHUNK_SIZE_BYTES);
- byte[] inputData = new byte[chunkSize];
- int bytesRead;
- int expectedFileSize = 0;
- while ((bytesRead = source.read(inputData)) > 0) {
- byte[] chunk;
- if (bytesRead == chunkSize) {
- chunk = inputData;
- } else {
- chunk = Arrays.copyOf(inputData, bytesRead);
- }
- executePsScript(ImmutableList.of("If ((!(Test-Path " + destination + ")) -or ((Get-Item '" + destination + "').length -eq " +
- expectedFileSize + ")) {Add-Content -Encoding Byte -path " + destination +
- " -value ([System.Convert]::FromBase64String(\"" + new String(Base64.encodeBase64(chunk)) + "\"))}"));
- expectedFileSize += bytesRead;
- }
-
- return 0;
- } catch (java.io.IOException e) {
- throw Exceptions.propagate(e);
- }
- }
-
- @Override
- public void init() {
- super.init();
-
- // Register any pre-existing port-mappings with the PortForwardManager
- Map<Integer, String> tcpPortMappings = getConfig(TCP_PORT_MAPPINGS);
- if (tcpPortMappings != null) {
- PortForwardManager pfm = (PortForwardManager) getManagementContext().getLocationRegistry().resolve("portForwardManager(scope=global)");
- for (Map.Entry<Integer, String> entry : tcpPortMappings.entrySet()) {
- int targetPort = entry.getKey();
- HostAndPort publicEndpoint = HostAndPort.fromString(entry.getValue());
- if (!publicEndpoint.hasPort()) {
- throw new IllegalArgumentException("Invalid portMapping ('"+entry.getValue()+"') for port "+targetPort+" in machine "+this);
- }
- pfm.associate(publicEndpoint.getHostText(), publicEndpoint, this, targetPort);
- }
- }
- }
- public String getUser() {
- return config().get(USER);
- }
-
- private String getPassword() {
- return config().get(PASSWORD);
- }
-
- private <T> T getRequiredConfig(ConfigKey<T> key) {
- return checkNotNull(getConfig(key), "key %s must be set", key);
- }
-
- public static String getDefaultUserMetadataString() {
- // Using an encoded command obviates the need to escape
- String unencodePowershell = Joiner.on("\r\n").join(ImmutableList.of(
- // Allow TS connections
- "$RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\\CIMV2\\TerminalServices -Authentication PacketPrivacy",
- "$RDP.SetAllowTSConnections(1,1)",
- "Set-ExecutionPolicy Unrestricted -Force",
- // Set unlimited values for remote execution limits
- "Set-Item WSMan:\\localhost\\Shell\\MaxConcurrentUsers 100",
- "Set-Item WSMan:\\localhost\\Shell\\MaxMemoryPerShellMB 0",
- "Set-Item WSMan:\\localhost\\Shell\\MaxProcessesPerShell 0",
- "Set-Item WSMan:\\localhost\\Shell\\MaxShellsPerUser 0",
- "New-ItemProperty \"HKLM:\\System\\CurrentControlSet\\Control\\LSA\" -Name \"SuppressExtendedProtection\" -Value 1 -PropertyType \"DWord\"",
- // The following allows scripts to re-authenticate with local credential - this is required
- // as certain operations cannot be performed with remote credentials
- "$allowed = @('WSMAN/*')",
- "$key = 'hklm:\\SOFTWARE\\Policies\\Microsoft\\Windows\\CredentialsDelegation'",
- "if (!(Test-Path $key)) {",
- " md $key",
- "}",
- "New-ItemProperty -Path $key -Name AllowFreshCredentials -Value 1 -PropertyType Dword -Force",
- "New-ItemProperty -Path $key -Name AllowFreshCredentialsWhenNTLMOnly -Value 1 -PropertyType Dword -Force",
- "$credKey = Join-Path $key 'AllowFreshCredentials'",
- "if (!(Test-Path $credKey)) {",
- " md $credkey",
- "}",
- "$ntlmKey = Join-Path $key 'AllowFreshCredentialsWhenNTLMOnly'",
- "if (!(Test-Path $ntlmKey)) {",
- " md $ntlmKey",
- "}",
- "$i = 1",
- "$allowed |% {",
- " # Script does not take into account existing entries in this key",
- " New-ItemProperty -Path $credKey -Name $i -Value $_ -PropertyType String -Force",
- " New-ItemProperty -Path $ntlmKey -Name $i -Value $_ -PropertyType String -Force",
- " $i++",
- "}"
- ));
-
- String encoded = new String(Base64.encodeBase64(unencodePowershell.getBytes(Charsets.UTF_16LE)));
- return "winrm quickconfig -q & " +
- "winrm set winrm/config/service/auth @{Basic=\"true\"} & " +
- "winrm set winrm/config/service/auth @{CredSSP=\"true\"} & " +
- "winrm set winrm/config/client/auth @{CredSSP=\"true\"} & " +
- "winrm set winrm/config/client @{AllowUnencrypted=\"true\"} & " +
- "winrm set winrm/config/service @{AllowUnencrypted=\"true\"} & " +
- "winrm set winrm/config/winrs @{MaxConcurrentUsers=\"100\"} & " +
- "winrm set winrm/config/winrs @{MaxMemoryPerShellMB=\"0\"} & " +
- "winrm set winrm/config/winrs @{MaxProcessesPerShell=\"0\"} & " +
- "winrm set winrm/config/winrs @{MaxShellsPerUser=\"0\"} & " +
- "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any & " +
- "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any & " +
- "powershell -EncodedCommand " + encoded;
- /* TODO: Find out why scripts with new line characters aren't working on AWS. The following appears as if it *should*
- work but doesn't - the script simply isn't run. By connecting to the machine via RDP, you can get the script
- from 'http://169.254.169.254/latest/user-data', and running it at the command prompt works, but for some
- reason the script isn't run when the VM is provisioned
- */
-// return Joiner.on("\r\n").join(ImmutableList.of(
-// "winrm quickconfig -q",
-// "winrm set winrm/config/service/auth @{Basic=\"true\"}",
-// "winrm set winrm/config/client @{AllowUnencrypted=\"true\"}",
-// "winrm set winrm/config/service @{AllowUnencrypted=\"true\"}",
-// "netsh advfirewall firewall add rule name=RDP dir=in protocol=tcp localport=3389 action=allow profile=any",
-// "netsh advfirewall firewall add rule name=WinRM dir=in protocol=tcp localport=5985 action=allow profile=any",
-// // Using an encoded command necessitates the need to escape. The unencoded command is as follows:
-// // $RDP = Get-WmiObject -Class Win32_TerminalServiceSetting -ComputerName $env:computername -Namespace root\CIMV2\TerminalServices -Authentication PacketPrivacy
-// // $Result = $RDP.SetAllowTSConnections(1,1)
-// "powershell -EncodedCommand JABSAEQAUAAgAD0AIABHAGUAdAAtAFcAbQBpAE8AYgBqAGUAYwB0ACAALQBDAGwAYQBzAHMAI" +
-// "ABXAGkAbgAzADIAXwBUAGUAcgBtAGkAbgBhAGwAUwBlAHIAdgBpAGMAZQBTAGUAdAB0AGkAbgBnACAALQBDAG8AbQBwA" +
-// "HUAdABlAHIATgBhAG0AZQAgACQAZQBuAHYAOgBjAG8AbQBwAHUAdABlAHIAbgBhAG0AZQAgAC0ATgBhAG0AZQBzAHAAY" +
-// "QBjAGUAIAByAG8AbwB0AFwAQwBJAE0AVgAyAFwAVABlAHIAbQBpAG4AYQBsAFMAZQByAHYAaQBjAGUAcwAgAC0AQQB1A" +
-// "HQAaABlAG4AdABpAGMAYQB0AGkAbwBuACAAUABhAGMAawBlAHQAUAByAGkAdgBhAGMAeQANAAoAJABSAGUAcwB1AGwAd" +
-// "AAgAD0AIAAkAFIARABQAC4AUwBlAHQAQQBsAGwAbwB3AFQAUwBDAG8AbgBuAGUAYwB0AGkAbwBuAHMAKAAxACwAMQApAA=="
-// ));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformerTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformerTest.java b/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformerTest.java
index d6528df..19a6ba4 100644
--- a/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformerTest.java
+++ b/core/src/test/java/org/apache/brooklyn/core/plan/XmlPlanToSpecTransformerTest.java
@@ -26,7 +26,7 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.entity.Entities;
import org.apache.brooklyn.core.mgmt.EntityManagementUtils;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.python.google.common.collect.Iterables;
+import com.google.common.collect.Iterables;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
deleted file mode 100644
index 9ef9ade..0000000
--- a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedLiveTest.java
+++ /dev/null
@@ -1,104 +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.feed.windows;
-
-import java.util.Map;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.location.MachineLocation;
-import org.apache.brooklyn.api.location.MachineProvisioningLocation;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppLiveTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.collections.MutableMap;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
-
-/**
- * WindowsPerformanceCounterFeed Live Test.
- * <p>
- * This test is currently disabled. To run, you must configure a location named {@code WindowsLiveTest}
- * or adapt the {@link #LOCATION_SPEC} below.
- * <p>
- * The location must provide Windows nodes that are running an SSH server on port 22. The login credentials must
- * be either be auto-detectable or configured in brooklyn.properties in the usual fashion.
- * <p>
- * Here is an example configuration from brooklyn.properties for a pre-configured Windows VM
- * running an SSH server with public key authentication:
- * <pre>
- * {@code brooklyn.location.named.WindowsLiveTest=byon:(hosts="ec2-xx-xxx-xxx-xx.eu-west-1.compute.amazonaws.com")
- * brooklyn.location.named.WindowsLiveTest.user=Administrator
- * brooklyn.location.named.WindowsLiveTest.privateKeyFile = ~/.ssh/id_rsa
- * brooklyn.location.named.WindowsLiveTest.publicKeyFile = ~/.ssh/id_rsa.pub
- * }</pre>
- * The location must by {@code byon} or another primitive type. Unfortunately, it's not possible to
- * use a jclouds location, as adding a dependency on brooklyn-locations-jclouds would cause a
- * cyclic dependency.
- */
-public class WindowsPerformanceCounterFeedLiveTest extends BrooklynAppLiveTestSupport {
-
- final static AttributeSensor<Double> CPU_IDLE_TIME = Sensors.newDoubleSensor("cpu.idleTime", "");
- final static AttributeSensor<Integer> TELEPHONE_LINES = Sensors.newIntegerSensor("telephone.lines", "");
-
- private static final String LOCATION_SPEC = "named:WindowsLiveTest";
-
- private Location loc;
- private EntityLocal entity;
-
- @BeforeMethod(alwaysRun=true)
- public void setUp() throws Exception {
- super.setUp();
-
- Map<String,?> allFlags = MutableMap.<String,Object>builder()
- .put("tags", ImmutableList.of(getClass().getName()))
- .build();
- MachineProvisioningLocation<? extends MachineLocation> provisioningLocation =
- (MachineProvisioningLocation<? extends MachineLocation>)
- mgmt.getLocationRegistry().resolve(LOCATION_SPEC, allFlags);
- loc = provisioningLocation.obtain(ImmutableMap.of());
-
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @Test(groups={"Live","Disabled"}, enabled=false)
- public void testRetrievesPerformanceCounters() throws Exception {
- // We can be pretty sure that a Windows instance in the cloud will have zero telephone lines...
- entity.sensors().set(TELEPHONE_LINES, 42);
- WindowsPerformanceCounterFeed feed = WindowsPerformanceCounterFeed.builder()
- .entity(entity)
- .addSensor("\\Processor(_total)\\% Idle Time", CPU_IDLE_TIME)
- .addSensor("\\Telephony\\Lines", TELEPHONE_LINES)
- .build();
- try {
- EntityTestUtils.assertAttributeEqualsEventually(entity, TELEPHONE_LINES, 0);
- } finally {
- feed.stop();
- }
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java b/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
deleted file mode 100644
index 3f4862b..0000000
--- a/core/src/test/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeedTest.java
+++ /dev/null
@@ -1,132 +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.feed.windows;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.brooklyn.api.entity.EntityLocal;
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.Location;
-import org.apache.brooklyn.api.sensor.AttributeSensor;
-import org.apache.brooklyn.core.sensor.Sensors;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
-import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterPollConfig;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.apache.brooklyn.util.text.Strings;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.testng.annotations.AfterMethod;
-import org.testng.annotations.BeforeMethod;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
-
-import io.cloudsoft.winrm4j.winrm.WinRmToolResponse;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class WindowsPerformanceCounterFeedTest extends BrooklynAppUnitTestSupport {
-
- private Location loc;
- private EntityLocal entity;
-
- @BeforeMethod(alwaysRun=true)
- @Override
- public void setUp() throws Exception {
- super.setUp();
- loc = new LocalhostMachineProvisioningLocation();
- entity = app.createAndManageChild(EntitySpec.create(TestEntity.class));
- app.start(ImmutableList.of(loc));
- }
-
- @AfterMethod(alwaysRun=true)
- @Override
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- private static final Logger log = LoggerFactory.getLogger(WindowsPerformanceCounterFeedTest.class);
-
- @Test
- public void testIteratorWithSingleValue() {
- Iterator<?> iterator = new WindowsPerformanceCounterFeed
- .PerfCounterValueIterator("\"10/14/2013 15:28:24.406\",\"0.000000\"");
- assertTrue(iterator.hasNext());
- assertEquals(iterator.next(), "0.000000");
- assertFalse(iterator.hasNext());
- }
-
- @Test
- public void testIteratorWithMultipleValues() {
- Iterator<?> iterator = new WindowsPerformanceCounterFeed
- .PerfCounterValueIterator("\"10/14/2013 15:35:50.582\",\"8803.000000\",\"405622.000000\"");
- assertTrue(iterator.hasNext());
- assertEquals(iterator.next(), "8803.000000");
- assertTrue(iterator.hasNext());
- assertEquals(iterator.next(), "405622.000000");
- assertFalse(iterator.hasNext());
- }
-
- @Test
- public void testSendPerfCountersToSensors() {
- AttributeSensor<String> stringSensor = Sensors.newStringSensor("foo.bar");
- AttributeSensor<Integer> integerSensor = Sensors.newIntegerSensor("bar.baz");
- AttributeSensor<Double> doubleSensor = Sensors.newDoubleSensor("baz.quux");
-
- Collection<WindowsPerformanceCounterPollConfig<?>> polls = ImmutableSet.<WindowsPerformanceCounterPollConfig<?>>of(
- new WindowsPerformanceCounterPollConfig(stringSensor).performanceCounterName("\\processor information(_total)\\% processor time"),
- new WindowsPerformanceCounterPollConfig(integerSensor).performanceCounterName("\\integer.sensor"),
- new WindowsPerformanceCounterPollConfig(doubleSensor).performanceCounterName("\\double\\sensor\\with\\multiple\\sub\\paths")
- );
-
- WindowsPerformanceCounterFeed.SendPerfCountersToSensors sendPerfCountersToSensors = new WindowsPerformanceCounterFeed.SendPerfCountersToSensors(entity, polls);
-
- assertNull(entity.getAttribute(stringSensor));
-
- StringBuilder responseBuilder = new StringBuilder();
- // NOTE: This builds the response in a different order to which they are passed to the SendPerfCountersToSensors constructor
- // this tests that the values are applied correctly even if the (possibly non-deterministic) order in which
- // they are returned by the Get-Counter scriptlet is different
- addMockResponse(responseBuilder, "\\\\machine.name\\double\\sensor\\with\\multiple\\sub\\paths", "3.1415926");
- addMockResponse(responseBuilder, "\\\\win-lge7uj2blau\\processor information(_total)\\% processor time", "99.9");
- addMockResponse(responseBuilder, "\\\\machine.name\\integer.sensor", "15");
-
- sendPerfCountersToSensors.onSuccess(new WinRmToolResponse(responseBuilder.toString(), "", 0));
-
- EntityTestUtils.assertAttributeEquals(entity, stringSensor, "99.9");
- EntityTestUtils.assertAttributeEquals(entity, integerSensor, 15);
- EntityTestUtils.assertAttributeEquals(entity, doubleSensor, 3.1415926);
- }
-
- private void addMockResponse(StringBuilder responseBuilder, String path, String value) {
- responseBuilder.append(path);
- responseBuilder.append(Strings.repeat(" ", 200 - (path.length() + value.length())));
- responseBuilder.append(value);
- responseBuilder.append("\r\n");
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java b/core/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java
deleted file mode 100644
index 65ac92e..0000000
--- a/core/src/test/java/org/apache/brooklyn/location/winrm/AdvertiseWinrmLoginPolicyTest.java
+++ /dev/null
@@ -1,51 +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.location.winrm;
-
-import org.apache.brooklyn.api.entity.EntitySpec;
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.api.policy.PolicySpec;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.core.test.entity.TestEntity;
-import org.apache.brooklyn.test.EntityTestUtils;
-import org.testng.annotations.Test;
-import org.apache.brooklyn.location.winrm.AdvertiseWinrmLoginPolicy;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-
-import com.google.common.collect.ImmutableList;
-
-public class AdvertiseWinrmLoginPolicyTest extends BrooklynAppUnitTestSupport {
-
- @Test
- public void testAdvertisesMachineLoginDetails() throws Exception {
- TestEntity entity = app.createAndManageChild(EntitySpec.create(TestEntity.class)
- .policy(PolicySpec.create(AdvertiseWinrmLoginPolicy.class)));
-
- WinRmMachineLocation machine = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
- .configure("address", "1.2.3.4")
- .configure("user", "myuser")
- .configure("port", 5678)
- .configure("password", "mypassword"));
- app.start(ImmutableList.of(machine));
-
- String expected = "myuser : mypassword @ 1.2.3.4:5678";
-
- EntityTestUtils.assertAttributeEqualsEventually(entity, AdvertiseWinrmLoginPolicy.VM_USER_CREDENTIALS, expected);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/core/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java b/core/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java
deleted file mode 100644
index f7f7fc1..0000000
--- a/core/src/test/java/org/apache/brooklyn/location/winrm/WinRmMachineLocationTest.java
+++ /dev/null
@@ -1,44 +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.location.winrm;
-
-import static org.testng.Assert.assertEquals;
-
-import org.apache.brooklyn.api.location.LocationSpec;
-import org.apache.brooklyn.core.entity.BrooklynConfigKeys;
-import org.apache.brooklyn.core.test.BrooklynAppUnitTestSupport;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
-import org.apache.brooklyn.util.net.Networking;
-import org.testng.annotations.Test;
-
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
-
-public class WinRmMachineLocationTest extends BrooklynAppUnitTestSupport {
-
- @Test
- public void testConfigurePrivateAddresses() throws Exception {
- WinRmMachineLocation host = mgmt.getLocationManager().createLocation(LocationSpec.create(WinRmMachineLocation.class)
- .configure("address", Networking.getLocalHost())
- .configure(WinRmMachineLocation.PRIVATE_ADDRESSES, ImmutableList.of("1.2.3.4"))
- .configure(BrooklynConfigKeys.SKIP_ON_BOX_BASE_DIR_RESOLUTION, true));
-
- assertEquals(host.getPrivateAddresses(), ImmutableSet.of("1.2.3.4"));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 560dcd8..8e4c265 100644
--- a/pom.xml
+++ b/pom.xml
@@ -108,6 +108,7 @@
<module>software/nosql</module>
<module>software/database</module>
<module>software/monitoring</module>
+ <module>software/winrm</module>
<module>storage/hazelcast</module>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/pom.xml
----------------------------------------------------------------------
diff --git a/software/winrm/pom.xml b/software/winrm/pom.xml
new file mode 100644
index 0000000..77d2fa6
--- /dev/null
+++ b/software/winrm/pom.xml
@@ -0,0 +1,45 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-parent</artifactId>
+ <version>0.9.0-SNAPSHOT</version> <!-- BROOKLYN_VERSION -->
+ <relativePath>../../parent/pom.xml</relativePath>
+ </parent>
+
+ <groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-software-winrm</artifactId>
+
+ <name>Brooklyn WinRM Software Entities</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.cloudsoft.windows</groupId>
+ <artifactId>winrm4j</artifactId>
+ <version>${winrm4j.version}</version>
+ </dependency>
+
+ <!-- test -->
+ <dependency>
+ <groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-core</artifactId>
+ <version>${project.version}</version>
+ <classifier>tests</classifier>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-test-support</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/8fa4df7d/software/winrm/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java b/software/winrm/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java
new file mode 100644
index 0000000..f5c2271
--- /dev/null
+++ b/software/winrm/src/main/java/org/apache/brooklyn/core/sensor/windows/WindowsPerformanceCounterSensors.java
@@ -0,0 +1,73 @@
+/*
+ * 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.core.sensor.windows;
+
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.brooklyn.api.entity.EntityInitializer;
+import org.apache.brooklyn.api.entity.EntityLocal;
+import org.apache.brooklyn.config.ConfigKey;
+import org.apache.brooklyn.core.config.ConfigKeys;
+import org.apache.brooklyn.core.entity.EntityInternal;
+import org.apache.brooklyn.core.sensor.Sensors;
+import org.apache.brooklyn.feed.windows.WindowsPerformanceCounterFeed;
+import org.apache.brooklyn.util.core.config.ConfigBag;
+import org.apache.brooklyn.util.text.Strings;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.reflect.TypeToken;
+
+public class WindowsPerformanceCounterSensors implements EntityInitializer {
+
+ private static final Logger LOG = LoggerFactory.getLogger(WindowsPerformanceCounterSensors.class);
+
+ public final static ConfigKey<Set<Map<String, String>>> PERFORMANCE_COUNTERS = ConfigKeys.newConfigKey(new TypeToken<Set<Map<String, String>>>(){}, "performance.counters");
+
+ protected final Set<Map<String, String>> sensors;
+
+ public WindowsPerformanceCounterSensors(ConfigBag params) {
+ sensors = params.get(PERFORMANCE_COUNTERS);
+ }
+
+ public WindowsPerformanceCounterSensors(Map<String, String> params) {
+ this(ConfigBag.newInstance(params));
+ }
+
+ @Override
+ public void apply(EntityLocal entity) {
+ WindowsPerformanceCounterFeed.Builder builder = WindowsPerformanceCounterFeed.builder()
+ .entity(entity);
+ for (Map<String, String> sensorConfig : sensors) {
+ String name = sensorConfig.get("name");
+ String sensorType = sensorConfig.get("sensorType");
+ Class<?> clazz;
+ try {
+ clazz = Strings.isNonEmpty(sensorType)
+ ? ((EntityInternal)entity).getManagementContext().getCatalog().getRootClassLoader().loadClass(sensorType)
+ : String.class;
+ } catch (ClassNotFoundException e) {
+ throw new IllegalStateException("Could not load type "+sensorType+" for sensor "+name, e);
+ }
+ builder.addSensor(sensorConfig.get("counter"), Sensors.newSensor(clazz, name, sensorConfig.get("description")));
+ }
+ builder.build();
+ }
+}
[5/7] incubator-brooklyn git commit: [BROOKLYN-182] Decouple
ReflectiveEntityDriverFactory from WinRmMachineLocation
Posted by ha...@apache.org.
[BROOKLYN-182] Decouple ReflectiveEntityDriverFactory from WinRmMachineLocation
Remove compile-time dependency towards WinRmMachineLocation, with the
later purpose of allowing the driver factory to be initialized from
higher-level code.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/0ded95c0
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/0ded95c0
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/0ded95c0
Branch: refs/heads/master
Commit: 0ded95c049f4f41356b3fa8e7f47c7feeff86402
Parents: 2cb87d3
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Oct 14 18:58:41 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Oct 14 23:36:38 2015 +0300
----------------------------------------------------------------------
.../core/entity/drivers/ReflectiveEntityDriverFactory.java | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/0ded95c0/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java b/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
index 19973f2..f9cf5a7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/drivers/ReflectiveEntityDriverFactory.java
@@ -30,7 +30,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.paas.PaasLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
import org.apache.brooklyn.util.collections.MutableList;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.exceptions.Exceptions;
@@ -192,7 +191,12 @@ public class ReflectiveEntityDriverFactory {
@Override
public <D extends EntityDriver> String inferDriverClassName(DriverDependentEntity<D> entity, Class<D> driverInterface, Location location) {
String driverInterfaceName = driverInterface.getName();
- if (!(location instanceof WinRmMachineLocation)) return null;
+ // TODO: use a proper registry later on
+ try {
+ if (!Class.forName("org.apache.brooklyn.location.winrm.WinRmMachineLocation").isInstance(location)) return null;
+ } catch (ClassNotFoundException ex) {
+ return null;
+ }
if (!driverInterfaceName.endsWith("Driver")) {
throw new IllegalArgumentException(String.format("Driver name [%s] doesn't end with 'Driver'; cannot auto-detect WinRmDriver class name", driverInterfaceName));
}
[7/7] incubator-brooklyn git commit: This closes #957
Posted by ha...@apache.org.
This closes #957
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/f380b583
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/f380b583
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/f380b583
Branch: refs/heads/master
Commit: f380b583688e182007c50c8681d6668ae88ed660
Parents: d53bd18 a3ff3d6
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Thu Oct 15 11:49:58 2015 -0400
Committer: Hadrian Zbarcea <ha...@apache.org>
Committed: Thu Oct 15 11:49:58 2015 -0400
----------------------------------------------------------------------
core/pom.xml | 5 -
.../brooklyn/core/effector/EffectorTasks.java | 35 +-
.../brooklyn/core/entity/EntitySuppliers.java | 2 +-
.../drivers/ReflectiveEntityDriverFactory.java | 8 +-
.../brooklyn/core/location/Locations.java | 2 +-
.../apache/brooklyn/core/location/Machines.java | 12 +-
.../location/access/BrooklynAccessUtils.java | 3 +-
.../WindowsPerformanceCounterSensors.java | 73 ----
.../org/apache/brooklyn/feed/ssh/SshFeed.java | 2 +-
.../windows/WindowsPerformanceCounterFeed.java | 412 ------------------
.../location/byon/ByonLocationResolver.java | 20 +-
.../winrm/AdvertiseWinrmLoginPolicy.java | 80 ----
.../location/winrm/WinRmMachineLocation.java | 362 ----------------
.../core/plan/XmlPlanToSpecTransformerTest.java | 2 +-
.../WindowsPerformanceCounterFeedLiveTest.java | 104 -----
.../WindowsPerformanceCounterFeedTest.java | 132 ------
.../location/byon/ByonLocationResolverTest.java | 26 +-
.../winrm/AdvertiseWinrmLoginPolicyTest.java | 51 ---
.../winrm/WinRmMachineLocationTest.java | 44 --
locations/jclouds/pom.xml | 5 +
.../policy/ha/SshMachineFailureDetector.java | 2 +-
pom.xml | 1 +
software/base/pom.xml | 10 +
.../entity/chef/ChefLifecycleEffectorTasks.java | 3 +-
.../entity/machine/MachineEntityImpl.java | 2 +-
.../entity/network/bind/BindDnsServerImpl.java | 4 +-
.../entity/dns/AbstractGeoDnsServiceTest.java | 2 +-
software/winrm/pom.xml | 65 +++
.../WindowsPerformanceCounterSensors.java | 73 ++++
.../windows/WindowsPerformanceCounterFeed.java | 414 +++++++++++++++++++
.../winrm/AdvertiseWinrmLoginPolicy.java | 80 ++++
.../location/winrm/WinRmMachineLocation.java | 362 ++++++++++++++++
.../WindowsPerformanceCounterFeedLiveTest.java | 103 +++++
.../WindowsPerformanceCounterFeedTest.java | 130 ++++++
.../winrm/AdvertiseWinrmLoginPolicyTest.java | 49 +++
.../winrm/ByonLocationResolverTest.java | 95 +++++
.../winrm/WinRmMachineLocationTest.java | 43 ++
.../camp/brooklyn/ByonLocationsYamlTest.java | 2 +-
38 files changed, 1487 insertions(+), 1333 deletions(-)
----------------------------------------------------------------------
[6/7] incubator-brooklyn git commit: [BROOKLYN-182] Fix dependencies
post winrm separation
Posted by ha...@apache.org.
[BROOKLYN-182] Fix dependencies post winrm separation
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/a3ff3d6b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/a3ff3d6b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/a3ff3d6b
Branch: refs/heads/master
Commit: a3ff3d6bfe3b717893067861679d5f37626b9194
Parents: 0ded95c
Author: Hadrian Zbarcea <ha...@apache.org>
Authored: Wed Oct 14 16:13:22 2015 -0400
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Oct 14 23:36:41 2015 +0300
----------------------------------------------------------------------
.../location/byon/ByonLocationResolverTest.java | 2 +-
locations/jclouds/pom.xml | 5 +++++
software/base/pom.xml | 10 ++++++++++
.../entity/chef/ChefLifecycleEffectorTasks.java | 1 +
software/winrm/pom.xml | 20 ++++++++++++++++++++
.../windows/WindowsPerformanceCounterFeed.java | 4 ++--
6 files changed, 39 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a3ff3d6b/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
index 8a46a64..edc374d 100644
--- a/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
@@ -294,7 +294,7 @@ public class ByonLocationResolverTest {
Assert.assertEquals("/tmp/x", l.config().getBag().get(LocationConfigKeys.PRIVATE_KEY_FILE));
}
- @Test
+ // FIXME: move @Test to the brooklyn-software-winrm module
public void testResolvesLocalTempDir() throws Exception {
String localTempDir = Os.mergePaths(Os.tmp(), "testResolvesUsernameAtHost");
brooklynProperties.put("brooklyn.location.byon.localTempDir", localTempDir);
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a3ff3d6b/locations/jclouds/pom.xml
----------------------------------------------------------------------
diff --git a/locations/jclouds/pom.xml b/locations/jclouds/pom.xml
index 6582079..ed10132 100644
--- a/locations/jclouds/pom.xml
+++ b/locations/jclouds/pom.xml
@@ -41,6 +41,11 @@
</dependency>
<dependency>
<groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-software-winrm</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.brooklyn</groupId>
<artifactId>brooklyn-api</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a3ff3d6b/software/base/pom.xml
----------------------------------------------------------------------
diff --git a/software/base/pom.xml b/software/base/pom.xml
index f79d777..32bb09b 100644
--- a/software/base/pom.xml
+++ b/software/base/pom.xml
@@ -42,6 +42,16 @@
</dependency>
<dependency>
<groupId>org.apache.brooklyn</groupId>
+ <artifactId>brooklyn-software-winrm</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>io.cloudsoft.windows</groupId>
+ <artifactId>winrm4j</artifactId>
+ <version>${winrm4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.brooklyn</groupId>
<artifactId>brooklyn-jmxmp-agent</artifactId>
<version>${project.version}</version>
</dependency>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a3ff3d6b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index e58c4ab..304648c 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -29,6 +29,7 @@ import org.apache.brooklyn.core.entity.lifecycle.Lifecycle;
import org.apache.brooklyn.core.location.Machines;
import org.apache.brooklyn.entity.software.base.SoftwareProcess;
import org.apache.brooklyn.entity.software.base.lifecycle.MachineLifecycleEffectorTasks;
+import org.apache.brooklyn.location.ssh.SshMachineLocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.util.collections.Jsonya;
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a3ff3d6b/software/winrm/pom.xml
----------------------------------------------------------------------
diff --git a/software/winrm/pom.xml b/software/winrm/pom.xml
index 77d2fa6..5bde35e 100644
--- a/software/winrm/pom.xml
+++ b/software/winrm/pom.xml
@@ -1,5 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
<modelVersion>4.0.0</modelVersion>
<parent>
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/a3ff3d6b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
index ff659b1..73a76cb 100644
--- a/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
+++ b/software/winrm/src/main/java/org/apache/brooklyn/feed/windows/WindowsPerformanceCounterFeed.java
@@ -51,7 +51,6 @@ import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.time.Duration;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -228,8 +227,9 @@ public class WindowsPerformanceCounterFeed extends AbstractFeed {
}
@Override
+ @SuppressWarnings("unchecked")
public T call() throws Exception {
- WinRmMachineLocation machine = EffectorTasks.getWinRmMachine(entity);
+ WinRmMachineLocation machine = EffectorTasks.getMachine(entity, WinRmMachineLocation.class);
WinRmToolResponse response = machine.executePsScript(command);
return (T)response;
}
[4/7] incubator-brooklyn git commit: [BROOKLYN-182] Decouple
ByonLocationResolver from MachineLocation subtypes
Posted by ha...@apache.org.
[BROOKLYN-182] Decouple ByonLocationResolver from MachineLocation subtypes
The ByonLocationResolver acts as a registry for windows/linux machine
types. For now we eliminate the compile-time dependency towards
SshMachineLocation and WinRmMachineLocation, while maintaining the
runtmie dependency.
Further on we'll reverse the dependency towards a more consistent
location type registry.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/2cb87d34
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/2cb87d34
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/2cb87d34
Branch: refs/heads/master
Commit: 2cb87d34021a299e9a569ea7cdb72598ecef8086
Parents: 676b48e
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Oct 14 18:41:30 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Oct 14 23:36:34 2015 +0300
----------------------------------------------------------------------
.../location/byon/ByonLocationResolver.java | 20 +++--
.../location/byon/ByonLocationResolverTest.java | 24 -----
.../winrm/ByonLocationResolverTest.java | 95 ++++++++++++++++++++
3 files changed, 109 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2cb87d34/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java b/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
index 7245faf..c747c35 100644
--- a/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
+++ b/core/src/main/java/org/apache/brooklyn/location/byon/ByonLocationResolver.java
@@ -34,8 +34,6 @@ import org.apache.brooklyn.core.config.ConfigKeys;
import org.apache.brooklyn.core.config.Sanitizer;
import org.apache.brooklyn.core.location.AbstractLocationResolver;
import org.apache.brooklyn.core.mgmt.internal.LocalLocationManager;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.flags.TypeCoercions;
@@ -72,9 +70,14 @@ public class ByonLocationResolver extends AbstractLocationResolver {
public static final ConfigKey<String> OS_FAMILY = ConfigKeys.newStringConfigKey("osFamily", "OS Family of the machine, either windows or linux", "linux");
- public static final Map<String, Class<? extends MachineLocation>> OS_TO_MACHINE_LOCATION_TYPE = ImmutableMap.<String, Class<? extends MachineLocation>>of(
- "windows", WinRmMachineLocation.class,
- "linux", SshMachineLocation.class);
+ /**
+ * @todo Reimplement via a registry:
+ * {@link org.apache.brooklyn.location.winrm.WinRmMachineLocation}
+ * {@link org.apache.brooklyn.location.ssh.SshMachineLocation}
+ */
+ public static final Map<String, String> OS_TO_MACHINE_LOCATION_TYPE = ImmutableMap.of(
+ "windows", "org.apache.brooklyn.location.winrm.WinRmMachineLocation",
+ "linux", "org.apache.brooklyn.location.ssh.SshMachineLocation");
@Override
public String getPrefix() {
@@ -207,7 +210,12 @@ public class ByonLocationResolver extends AbstractLocationResolver {
}
private Class<? extends MachineLocation> getLocationClass(String osFamily) {
- return osFamily == null ? null : OS_TO_MACHINE_LOCATION_TYPE.get(osFamily.toLowerCase(Locale.ENGLISH));
+ try {
+ if (osFamily != null) {
+ return Class.forName(OS_TO_MACHINE_LOCATION_TYPE.get(osFamily.toLowerCase(Locale.ENGLISH))).asSubclass(MachineLocation.class);
+ }
+ } catch (ClassNotFoundException ex) {}
+ return null;
}
protected LocationSpec<? extends MachineLocation> parseMachine(String val, Class<? extends MachineLocation> locationClass, Map<String, ?> defaults, String specForErrMsg) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2cb87d34/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java b/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
index 05102a5..8a46a64 100644
--- a/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
+++ b/core/src/test/java/org/apache/brooklyn/location/byon/ByonLocationResolverTest.java
@@ -42,9 +42,7 @@ import org.apache.brooklyn.core.location.NamedLocationResolver;
import org.apache.brooklyn.core.location.internal.LocationInternal;
import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
-import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
import org.apache.brooklyn.test.Asserts;
import org.apache.brooklyn.util.collections.MutableMap;
import org.apache.brooklyn.util.net.Networking;
@@ -333,28 +331,6 @@ public class ByonLocationResolverTest {
Assert.assertEquals("1.1.1.1", location1.getAddress().getHostAddress());
}
- @DataProvider(name = "windowsOsFamilies")
- public Object[][] getWindowsOsFamilies() {
- return new Object[][]{{"windows"}, {"WINDOWS"}, {"wInDoWs"}};
- }
-
- @Test(dataProvider = "windowsOsFamilies")
- public void testWindowsMachines(String osFamily) throws Exception {
- brooklynProperties.put("brooklyn.location.byon.user", "myuser");
- brooklynProperties.put("brooklyn.location.byon.password", "mypassword");
- String spec = "byon";
- Map<String, ?> flags = ImmutableMap.of(
- "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
- "osFamily", osFamily
- );
- MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
- WinRmMachineLocation location = (WinRmMachineLocation) provisioner.obtain(ImmutableMap.of());
-
- assertEquals(location.config().get(WinRmMachineLocation.USER), "myuser");
- assertEquals(location.config().get(WinRmMachineLocation.PASSWORD), "mypassword");
- assertEquals(location.config().get(WinRmMachineLocation.ADDRESS).getHostAddress(), "1.1.1.1");
- }
-
@Test
public void testNonWindowsMachines() throws Exception {
String spec = "byon";
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/2cb87d34/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/ByonLocationResolverTest.java
----------------------------------------------------------------------
diff --git a/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/ByonLocationResolverTest.java b/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/ByonLocationResolverTest.java
new file mode 100644
index 0000000..62aa66d
--- /dev/null
+++ b/software/winrm/src/test/java/org/apache/brooklyn/location/winrm/ByonLocationResolverTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.location.winrm;
+
+import static org.testng.Assert.assertEquals;
+import java.util.Map;
+
+import org.apache.brooklyn.api.location.MachineLocation;
+import org.apache.brooklyn.api.location.MachineProvisioningLocation;
+import org.apache.brooklyn.core.entity.Entities;
+import org.apache.brooklyn.core.internal.BrooklynProperties;
+import org.apache.brooklyn.core.mgmt.internal.LocalManagementContext;
+import org.apache.brooklyn.core.test.entity.LocalManagementContextForTests;
+import org.apache.brooklyn.util.text.StringPredicates;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.apache.brooklyn.location.byon.FixedListMachineProvisioningLocation;
+
+public class ByonLocationResolverTest {
+
+ private static final Logger log = LoggerFactory.getLogger(ByonLocationResolverTest.class);
+
+ private BrooklynProperties brooklynProperties;
+ private LocalManagementContext managementContext;
+ private Predicate<CharSequence> defaultNamePredicate;
+
+ @BeforeMethod(alwaysRun=true)
+ public void setUp() throws Exception {
+ managementContext = LocalManagementContextForTests.newInstance();
+ brooklynProperties = managementContext.getBrooklynProperties();
+ defaultNamePredicate = StringPredicates.startsWith(FixedListMachineProvisioningLocation.class.getSimpleName());
+ }
+
+ @AfterMethod(alwaysRun=true)
+ public void tearDown() throws Exception {
+ if (managementContext != null) Entities.destroyAll(managementContext);
+ }
+
+ @DataProvider(name = "windowsOsFamilies")
+ public Object[][] getWindowsOsFamilies() {
+ return new Object[][]{{"windows"}, {"WINDOWS"}, {"wInDoWs"}};
+ }
+
+ @Test(dataProvider = "windowsOsFamilies")
+ public void testWindowsMachines(String osFamily) throws Exception {
+ brooklynProperties.put("brooklyn.location.byon.user", "myuser");
+ brooklynProperties.put("brooklyn.location.byon.password", "mypassword");
+ String spec = "byon";
+ Map<String, ?> flags = ImmutableMap.of(
+ "hosts", ImmutableList.of("1.1.1.1", "2.2.2.2"),
+ "osFamily", osFamily
+ );
+ MachineProvisioningLocation<MachineLocation> provisioner = resolve(spec, flags);
+ WinRmMachineLocation location = (WinRmMachineLocation) provisioner.obtain(ImmutableMap.of());
+
+ assertEquals(location.config().get(WinRmMachineLocation.USER), "myuser");
+ assertEquals(location.config().get(WinRmMachineLocation.PASSWORD), "mypassword");
+ assertEquals(location.config().get(WinRmMachineLocation.ADDRESS).getHostAddress(), "1.1.1.1");
+ }
+
+ @SuppressWarnings("unchecked")
+ private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val) {
+ return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val);
+ }
+
+ @SuppressWarnings("unchecked")
+ private FixedListMachineProvisioningLocation<MachineLocation> resolve(String val, Map<?, ?> locationFlags) {
+ return (FixedListMachineProvisioningLocation<MachineLocation>) managementContext.getLocationRegistry().resolve(val, locationFlags);
+ }
+
+}
[3/7] incubator-brooklyn git commit: [BROOKLYN-182] Don't type-switch
amongst location types
Posted by ha...@apache.org.
[BROOKLYN-182] Don't type-switch amongst location types
Duplicating functions like getSsh* with getWinrm* counterparts should be
avoided. Replace with a global get*(Class) instead.
Project: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/commit/676b48e3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/tree/676b48e3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/diff/676b48e3
Branch: refs/heads/master
Commit: 676b48e35866c264a1f21dcfdbabed7f4297b993
Parents: 8fa4df7
Author: Ciprian Ciubotariu <ch...@gmx.net>
Authored: Wed Oct 14 17:38:49 2015 +0300
Committer: Ciprian Ciubotariu <ch...@gmx.net>
Committed: Wed Oct 14 23:36:29 2015 +0300
----------------------------------------------------------------------
.../brooklyn/core/effector/EffectorTasks.java | 35 +++++++++++---------
.../brooklyn/core/entity/EntitySuppliers.java | 2 +-
.../brooklyn/core/location/Locations.java | 2 +-
.../apache/brooklyn/core/location/Machines.java | 12 ++-----
.../org/apache/brooklyn/feed/ssh/SshFeed.java | 2 +-
.../policy/ha/SshMachineFailureDetector.java | 2 +-
.../entity/chef/ChefLifecycleEffectorTasks.java | 2 +-
.../entity/machine/MachineEntityImpl.java | 2 +-
.../entity/network/bind/BindDnsServerImpl.java | 4 +--
.../entity/dns/AbstractGeoDnsServiceTest.java | 2 +-
.../camp/brooklyn/ByonLocationsYamlTest.java | 2 +-
11 files changed, 33 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
index e990bac..68d45a5 100644
--- a/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
+++ b/core/src/main/java/org/apache/brooklyn/core/effector/EffectorTasks.java
@@ -35,7 +35,7 @@ import org.apache.brooklyn.core.mgmt.internal.EffectorUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
+import org.apache.brooklyn.api.location.MachineLocation;
import org.apache.brooklyn.util.core.config.ConfigBag;
import org.apache.brooklyn.util.core.task.DynamicSequentialTask;
import org.apache.brooklyn.util.core.task.DynamicTasks;
@@ -199,6 +199,24 @@ public class EffectorTasks {
return Reflections.cast(t, type);
}
+ /** Finds a unique {@link MachineLocation} attached to the entity
+ * where this task is running
+ * @throws NullPointerException if {@link #findEntity()} fails
+ * @throws IllegalStateException if call to {@link #getSshMachine(Entity)} fails */
+ public static <T extends MachineLocation> T findMachine(Class<T> clazz) {
+ return getMachine(findEntity(), clazz);
+ }
+
+ /** Finds a unique {@link MachineLocation} attached to the supplied entity
+ * @throws IllegalStateException if there is not a unique such {@link SshMachineLocation} */
+ public static <T extends MachineLocation> T getMachine(Entity entity, Class<T> clazz) {
+ try {
+ return Machines.findUniqueMachineLocation(entity.getLocations(), clazz).get();
+ } catch (Exception e) {
+ throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single " + clazz.getName() + ", but has "+entity.getLocations(), e);
+ }
+ }
+
/** Finds a unique {@link SshMachineLocation} attached to the entity
* where this task is running
* @throws NullPointerException if {@link #findEntity()} fails
@@ -210,20 +228,7 @@ public class EffectorTasks {
/** Finds a unique {@link SshMachineLocation} attached to the supplied entity
* @throws IllegalStateException if there is not a unique such {@link SshMachineLocation} */
public static SshMachineLocation getSshMachine(Entity entity) {
- try {
- return Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
- } catch (Exception e) {
- throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single SshMachineLocation, but has "+entity.getLocations(), e);
- }
+ return getMachine(entity, SshMachineLocation.class);
}
- /** Finds a unique {@link WinRmMachineLocation} attached to the supplied entity
- * @throws IllegalStateException if there is not a unique such {@link WinRmMachineLocation} */
- public static WinRmMachineLocation getWinRmMachine(Entity entity) {
- try {
- return Machines.findUniqueWinRmMachineLocation(entity.getLocations()).get();
- } catch (Exception e) {
- throw new IllegalStateException("Entity "+entity+" (in "+Tasks.current()+") requires a single WinRmMachineLocation, but has "+entity.getLocations(), e);
- }
- }
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/core/src/main/java/org/apache/brooklyn/core/entity/EntitySuppliers.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/entity/EntitySuppliers.java b/core/src/main/java/org/apache/brooklyn/core/entity/EntitySuppliers.java
index 4469d24..406485a 100644
--- a/core/src/main/java/org/apache/brooklyn/core/entity/EntitySuppliers.java
+++ b/core/src/main/java/org/apache/brooklyn/core/entity/EntitySuppliers.java
@@ -41,7 +41,7 @@ public class EntitySuppliers {
}
@Override public SshMachineLocation get() {
- return Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
+ return Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class).get();
}
}
}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/Locations.java b/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
index 2cae5d7..0b8a060 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/Locations.java
@@ -66,7 +66,7 @@ public class Locations {
/** as {@link Machines#findUniqueSshMachineLocation(Iterable)} */
public static Maybe<SshMachineLocation> findUniqueSshMachineLocation(Iterable<? extends Location> locations) {
- return Machines.findUniqueSshMachineLocation(locations);
+ return Machines.findUniqueMachineLocation(locations, SshMachineLocation.class);
}
/** if no locations are supplied, returns locations on the entity, or in the ancestors, until it finds a non-empty set,
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/core/src/main/java/org/apache/brooklyn/core/location/Machines.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/core/location/Machines.java b/core/src/main/java/org/apache/brooklyn/core/location/Machines.java
index b95d42f..9ec97e7 100644
--- a/core/src/main/java/org/apache/brooklyn/core/location/Machines.java
+++ b/core/src/main/java/org/apache/brooklyn/core/location/Machines.java
@@ -34,8 +34,6 @@ import com.google.common.collect.Iterables;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation;
import org.apache.brooklyn.location.localhost.LocalhostMachineProvisioningLocation.LocalhostMachine;
-import org.apache.brooklyn.location.ssh.SshMachineLocation;
-import org.apache.brooklyn.location.winrm.WinRmMachineLocation;
import org.apache.brooklyn.util.guava.Maybe;
import org.apache.brooklyn.util.net.HasNetworkAddresses;
@@ -102,15 +100,11 @@ public class Machines {
}
public static Maybe<MachineLocation> findUniqueMachineLocation(Iterable<? extends Location> locations) {
- return findUniqueElement(locations, MachineLocation.class);
+ return findUniqueMachineLocation(locations, MachineLocation.class);
}
- public static Maybe<SshMachineLocation> findUniqueSshMachineLocation(Iterable<? extends Location> locations) {
- return findUniqueElement(locations, SshMachineLocation.class);
- }
-
- public static Maybe<WinRmMachineLocation> findUniqueWinRmMachineLocation(Iterable<? extends Location> locations) {
- return findUniqueElement(locations, WinRmMachineLocation.class);
+ public static <T extends MachineLocation> Maybe<T> findUniqueMachineLocation(Iterable<? extends Location> locations, Class<T> clazz) {
+ return findUniqueElement(locations, clazz);
}
public static Maybe<String> findSubnetHostname(Iterable<? extends Location> ll) {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
index 8663137..6a13528 100644
--- a/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
+++ b/core/src/main/java/org/apache/brooklyn/feed/ssh/SshFeed.java
@@ -202,7 +202,7 @@ public class SshFeed extends AbstractFeed {
/** @deprecated since 0.7.0, use static convenience on {@link Locations} */
@Deprecated
public static SshMachineLocation getMachineOfEntity(Entity entity) {
- return Machines.findUniqueSshMachineLocation(entity.getLocations()).orNull();
+ return Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class).orNull();
}
/**
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
----------------------------------------------------------------------
diff --git a/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java b/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
index e5da346..bd5738b 100644
--- a/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
+++ b/policy/src/main/java/org/apache/brooklyn/policy/ha/SshMachineFailureDetector.java
@@ -67,7 +67,7 @@ public class SshMachineFailureDetector extends AbstractFailureDetector {
@Override
protected CalculatedStatus calculateStatus() {
- Maybe<SshMachineLocation> sshMachineOption = Machines.findUniqueSshMachineLocation(entity.getLocations());
+ Maybe<SshMachineLocation> sshMachineOption = Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class);
if (sshMachineOption.isPresent()) {
SshMachineLocation sshMachine = sshMachineOption.get();
try {
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
index 57c54bf..e58c4ab 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/chef/ChefLifecycleEffectorTasks.java
@@ -159,7 +159,7 @@ public class ChefLifecycleEffectorTasks extends MachineLifecycleEffectorTasks im
@SuppressWarnings({ "unchecked", "deprecation" })
protected void startWithChefSoloAsync() {
- String baseDir = MachineLifecycleEffectorTasks.resolveOnBoxDir(entity(), Machines.findUniqueSshMachineLocation(entity().getLocations()).get());
+ String baseDir = MachineLifecycleEffectorTasks.resolveOnBoxDir(entity(), Machines.findUniqueMachineLocation(entity().getLocations(), SshMachineLocation.class).get());
String installDir = Urls.mergePaths(baseDir, "installs/chef");
@SuppressWarnings("rawtypes")
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
----------------------------------------------------------------------
diff --git a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
index 58c64fd..881dd7b 100644
--- a/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
+++ b/software/base/src/main/java/org/apache/brooklyn/entity/machine/MachineEntityImpl.java
@@ -146,7 +146,7 @@ public class MachineEntityImpl extends EmptySoftwareProcessImpl implements Machi
}
public SshMachineLocation getMachine() {
- return Machines.findUniqueSshMachineLocation(getLocations()).get();
+ return Machines.findUniqueMachineLocation(getLocations(), SshMachineLocation.class).get();
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
----------------------------------------------------------------------
diff --git a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
index 120486a..2ee89e2 100644
--- a/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
+++ b/software/network/src/main/java/org/apache/brooklyn/entity/network/bind/BindDnsServerImpl.java
@@ -224,7 +224,7 @@ public class BindDnsServerImpl extends SoftwareProcessImpl implements BindDnsSer
for (Map.Entry<String, Entity> e : hostnameToEntity.entries()) {
String domainName = e.getKey();
- Maybe<SshMachineLocation> location = Machines.findUniqueSshMachineLocation(e.getValue().getLocations());
+ Maybe<SshMachineLocation> location = Machines.findUniqueMachineLocation(e.getValue().getLocations(), SshMachineLocation.class);
if (!location.isPresent()) {
LOG.debug("Member {} of {} does not have an SSH location so will not be configured", e.getValue(), this);
continue;
@@ -255,7 +255,7 @@ public class BindDnsServerImpl extends SoftwareProcessImpl implements BindDnsSer
}
protected void configureResolver(Entity entity) {
- Maybe<SshMachineLocation> machine = Machines.findUniqueSshMachineLocation(entity.getLocations());
+ Maybe<SshMachineLocation> machine = Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class);
if (machine.isPresent()) {
if (getConfig(REPLACE_RESOLV_CONF)) {
machine.get().copyTo(new StringReader(getConfig(RESOLV_CONF_TEMPLATE)), "/etc/resolv.conf");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
----------------------------------------------------------------------
diff --git a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
index e8aa73f..5ce2c1b 100644
--- a/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
+++ b/software/webapp/src/test/java/org/apache/brooklyn/entity/dns/AbstractGeoDnsServiceTest.java
@@ -220,7 +220,7 @@ public class AbstractGeoDnsServiceTest {
if (includeServiceUp)
((EntityInternal)e).sensors().set(Attributes.SERVICE_UP, true);
- SshMachineLocation l = Machines.findUniqueSshMachineLocation(e.getLocations()).get();
+ SshMachineLocation l = Machines.findUniqueMachineLocation(e.getLocations(), SshMachineLocation.class).get();
if (includeAddress)
((EntityInternal)e).sensors().set(Attributes.ADDRESS, l.getAddress().getHostAddress());
String h = (String) l.config().getBag().getStringKey("hostname");
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/676b48e3/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
----------------------------------------------------------------------
diff --git a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
index 42db9ec..ff89c25 100644
--- a/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
+++ b/usage/camp/src/test/java/org/apache/brooklyn/camp/brooklyn/ByonLocationsYamlTest.java
@@ -244,7 +244,7 @@ public class ByonLocationsYamlTest extends AbstractYamlTest {
FixedListMachineProvisioningLocation<MachineLocation> loc = (FixedListMachineProvisioningLocation<MachineLocation>) Iterables.get(app.getLocations(), 0);
// Machine should have been given the inbound-ports
- SshMachineLocation machine = Machines.findUniqueSshMachineLocation(entity.getLocations()).get();
+ SshMachineLocation machine = Machines.findUniqueMachineLocation(entity.getLocations(), SshMachineLocation.class).get();
Asserts.assertEqualsIgnoringOrder((Iterable<?>)machine.config().get(CloudLocationConfig.INBOUND_PORTS), ImmutableList.of(22, 1024));
// Stop the entity; should release the machine