protected void releasePortForwarding()

in locations/jclouds/src/main/java/org/apache/brooklyn/location/jclouds/JcloudsLocation.java [2379:2479]


    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);
        final String nodeId = machine.getJcloudsId();
        final Map<String, Runnable> subtasks = Maps.newLinkedHashMap();

        PortForwardManager portForwardManager = machine.getConfig(PORT_FORWARDING_MANAGER);
        if (portForwardManager == null) {
            LOG.debug("No PortForwardManager, using default");
            portForwardManager = (PortForwardManager) getManagementContext().getLocationRegistry().getLocationManaged(PortForwardManagerLocationResolver.PFM_GLOBAL_SPEC);
        }

        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).getPort();
                    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() {
                                @Override
                                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 = Sets.newLinkedHashSet();
            mappings.addAll(portForwardManager.getLocationPublicIpIds(machine));
            if (nodeId != null) {
                mappings.addAll(portForwardManager.getPortMappingWithPublicIpId(nodeId));
            }

            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() {
                                @Override
                                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
        portForwardManager.forgetPortMappings(machine);
        if (nodeId != null) {
            portForwardManager.forgetPortMappings(nodeId);
        }
    }