in brooklyn-server/locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java [2459:2559]
protected void releasePortForwarding(final JcloudsMachineLocation machine) {
// TODO Implementation needs revisisted. It relies on deprecated PortForwardManager methods.
boolean usePortForwarding = Boolean.TRUE.equals(machine.getConfig(USE_PORT_FORWARDING));
final JcloudsPortForwarderExtension portForwarder = machine.getConfig(PORT_FORWARDER);
PortForwardManager portForwardManager = machine.getConfig(PORT_FORWARDING_MANAGER);
final String nodeId = machine.getJcloudsId();
final Map<String, Runnable> subtasks = Maps.newLinkedHashMap();
if (portForwarder == null) {
LOG.debug("No port-forwarding to close (because portForwarder null) on release of " + machine);
} else {
final Optional<NodeMetadata> node = machine.getOptionalNode();
// Release the port-forwarding for the login-port, which was explicitly created by JcloudsLocation
if (usePortForwarding && node.isPresent()) {
final HostAndPort hostAndPortOverride;
if (machine instanceof SshMachineLocation) {
hostAndPortOverride = ((SshMachineLocation)machine).getSshHostAndPort();
} else if (machine instanceof WinRmMachineLocation) {
String host = ((WinRmMachineLocation)machine).getAddress().getHostAddress();
int port = ((WinRmMachineLocation)machine).config().get(WinRmMachineLocation.WINRM_PORT);
hostAndPortOverride = HostAndPort.fromParts(host, port);
} else {
LOG.warn("Unexpected machine {} of type {}; expected SSH or WinRM", machine, (machine != null ? machine.getClass() : null));
hostAndPortOverride = null;
}
if (hostAndPortOverride != null) {
final int loginPort = node.get().getLoginPort();
subtasks.put(
"Close port-forward "+hostAndPortOverride+"->"+loginPort,
new Runnable() {
public void run() {
LOG.debug("Closing port-forwarding at {} for machine {}: {}->{}", new Object[] {this, machine, hostAndPortOverride, loginPort});
portForwarder.closePortForwarding(node.get(), loginPort, hostAndPortOverride, Protocol.TCP);
}
});
}
}
// Get all the other port-forwarding mappings for this VM, and release all of those
Set<PortMapping> mappings;
if (portForwardManager != null) {
mappings = Sets.newLinkedHashSet();
mappings.addAll(portForwardManager.getLocationPublicIpIds(machine));
if (nodeId != null) {
mappings.addAll(portForwardManager.getPortMappingWithPublicIpId(nodeId));
}
} else {
mappings = ImmutableSet.of();
}
for (final PortMapping mapping : mappings) {
final HostAndPort publicEndpoint = mapping.getPublicEndpoint();
final int targetPort = mapping.getPrivatePort();
final Protocol protocol = Protocol.TCP;
if (publicEndpoint != null && node.isPresent()) {
subtasks.put(
"Close port-forward "+publicEndpoint+"->"+targetPort,
new Runnable() {
public void run() {
LOG.debug("Closing port-forwarding at {} for machine {}: {}->{}", new Object[] {this, machine, publicEndpoint, targetPort});
portForwarder.closePortForwarding(node.get(), targetPort, publicEndpoint, protocol);
}
});
}
}
if (subtasks.size() > 0) {
final TaskBuilder<Void> builder = TaskBuilder.<Void>builder()
.parallel(true)
.displayName("close port-forwarding at "+machine);
for (Map.Entry<String, Runnable> entry : subtasks.entrySet()) {
builder.add(TaskBuilder.builder().displayName(entry.getKey()).body(entry.getValue()).build());
}
final Task<Void> task = builder.build();
final DynamicTasks.TaskQueueingResult<Void> queueResult = DynamicTasks.queueIfPossible(task);
if(queueResult.isQueuedOrSubmitted()){
final String origDetails = Tasks.setBlockingDetails("waiting for closing port-forwarding of "+machine);
try {
task.blockUntilEnded();
} finally {
Tasks.setBlockingDetails(origDetails);
}
} else {
LOG.warn("Releasing port-forwarding of "+machine+" not executing in execution-context "
+ "(e.g. not invoked inside effector); falling back to executing sequentially");
for (Runnable subtask : subtasks.values()) {
subtask.run();
}
}
}
}
// Forget all port mappings associated with this VM
if (portForwardManager != null) {
portForwardManager.forgetPortMappings(machine);
if (nodeId != null) {
portForwardManager.forgetPortMappings(nodeId);
}
}
}