Search in sources :

Example 1 with ActionInvocation

use of org.jupnp.model.action.ActionInvocation in project besu by hyperledger.

the class UpnpNatManager method releaseAllPortForwards.

/**
 * Attempts to release any forwarded ports.
 *
 * <p>Note that this is not synchronized, as it is expected to be called within an
 * already-synchronized context ({@link #stop()}).
 *
 * @return A CompletableFuture that will complete when all port forward requests have been made
 */
private CompletableFuture<Void> releaseAllPortForwards() {
    // if we haven't observed the WANIPConnection service yet, we should have no port forwards to
    // release
    CompletableFuture<RemoteService> wanIPConnectionServiceFuture = getService(SERVICE_TYPE_WAN_IP_CONNECTION);
    if (!wanIPConnectionServiceFuture.isDone()) {
        return CompletableFuture.completedFuture(null);
    }
    RemoteService service = wanIPConnectionServiceFuture.join();
    List<CompletableFuture<Void>> futures = new ArrayList<>();
    boolean done = false;
    while (!done) {
        NatPortMapping portMapping;
        synchronized (forwardedPorts) {
            if (forwardedPorts.isEmpty()) {
                done = true;
                continue;
            }
            portMapping = forwardedPorts.get(0);
            forwardedPorts.remove(0);
        }
        LOG.info("Releasing port forward for {} {} -> {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
        CompletableFuture<Void> future = new CompletableFuture<>();
        PortMappingDelete callback = new PortMappingDelete(service, toJupnpPortMapping(portMapping)) {

            /**
             * Because the underlying jupnp library omits generics info in this method signature, we
             * must too when we override it.
             */
            @Override
            @SuppressWarnings("rawtypes")
            public void success(final ActionInvocation invocation) {
                LOG.info("Port forward {} {} -> {} removed successfully.", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
                future.complete(null);
            }

            /**
             * Because the underlying jupnp library omits generics info in this method signature, we
             * must too when we override it.
             */
            @Override
            @SuppressWarnings("rawtypes")
            public void failure(final ActionInvocation invocation, final UpnpResponse operation, final String msg) {
                LOG.warn("Port forward removal request for {} {} -> {} failed (ignoring): {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort(), msg);
                // ignore exceptions; we did our best
                future.complete(null);
            }
        };
        upnpService.getControlPoint().execute(callback);
        futures.add(future);
    }
    // complete
    return CompletableFuture.allOf(futures.toArray(new CompletableFuture<?>[0]));
}
Also used : NatPortMapping(org.hyperledger.besu.nat.core.domain.NatPortMapping) UpnpResponse(org.jupnp.model.message.UpnpResponse) ActionInvocation(org.jupnp.model.action.ActionInvocation) ArrayList(java.util.ArrayList) PortMappingDelete(org.jupnp.support.igd.callback.PortMappingDelete) CompletableFuture(java.util.concurrent.CompletableFuture) RemoteService(org.jupnp.model.meta.RemoteService)

Example 2 with ActionInvocation

use of org.jupnp.model.action.ActionInvocation in project besu by hyperledger.

the class UpnpNatManager method initiateExternalIpQuery.

/**
 * Sends a UPnP request to the discovered IGD for the external ip address.
 *
 * <p>Note that this is not synchronized, as it is expected to be called within an
 * already-synchronized context ({@link #start()}).
 */
private void initiateExternalIpQuery() {
    discoverService(SERVICE_TYPE_WAN_IP_CONNECTION).thenAccept(service -> {
        // our query, which will be handled asynchronously by the jupnp library
        GetExternalIP callback = new GetExternalIP(service) {

            /**
             * Override the success(ActionInvocation) version of success so that we can take
             * a peek at the network interface that we discovered this on.
             *
             * <p>Because the underlying jupnp library omits generics info in this method
             * signature, we must too when we override it.
             */
            @Override
            @SuppressWarnings("rawtypes")
            public void success(final ActionInvocation invocation) {
                RemoteService service = (RemoteService) invocation.getAction().getService();
                RemoteDevice device = service.getDevice();
                RemoteDeviceIdentity identity = device.getIdentity();
                discoveredOnLocalAddress = Optional.of(identity.getDiscoveredOnLocalAddress().getHostAddress());
                super.success(invocation);
            }

            @Override
            protected void success(final String result) {
                LOG.info("External IP address {} detected for internal address {}", result, discoveredOnLocalAddress.get());
                externalIpQueryFuture.complete(result);
            }

            /**
             * Because the underlying jupnp library omits generics info in this method
             * signature, we must too when we override it.
             */
            @Override
            @SuppressWarnings("rawtypes")
            public void failure(final ActionInvocation invocation, final UpnpResponse operation, final String msg) {
                externalIpQueryFuture.completeExceptionally(new Exception(msg));
            }
        };
        upnpService.getControlPoint().execute(callback);
    });
}
Also used : RemoteService(org.jupnp.model.meta.RemoteService) UpnpResponse(org.jupnp.model.message.UpnpResponse) ActionInvocation(org.jupnp.model.action.ActionInvocation) GetExternalIP(org.jupnp.support.igd.callback.GetExternalIP) RemoteDeviceIdentity(org.jupnp.model.meta.RemoteDeviceIdentity) RemoteDevice(org.jupnp.model.meta.RemoteDevice) NatInitializationException(org.hyperledger.besu.nat.core.exception.NatInitializationException)

Example 3 with ActionInvocation

use of org.jupnp.model.action.ActionInvocation in project smarthome by eclipse.

the class UpnpIOServiceImpl method invokeAction.

@SuppressWarnings("unchecked")
@Override
public Map<String, String> invokeAction(UpnpIOParticipant participant, String serviceID, String actionID, Map<String, String> inputs) {
    HashMap<String, String> resultMap = new HashMap<>();
    if (serviceID != null && actionID != null && participant != null) {
        registerParticipant(participant);
        Device device = getDevice(participant);
        if (device != null) {
            Service service = findService(device, serviceID);
            if (service != null) {
                Action action = service.getAction(actionID);
                if (action != null) {
                    ActionInvocation invocation = new ActionInvocation(action);
                    if (inputs != null) {
                        for (String variable : inputs.keySet()) {
                            invocation.setInput(variable, inputs.get(variable));
                        }
                    }
                    logger.trace("Invoking Action '{}' of service '{}' for participant '{}'", actionID, serviceID, participant.getUDN());
                    new ActionCallback.Default(invocation, upnpService.getControlPoint()).run();
                    ActionException anException = invocation.getFailure();
                    if (anException != null && anException.getMessage() != null) {
                        logger.debug("{}", anException.getMessage());
                    }
                    Map<String, ActionArgumentValue> result = invocation.getOutputMap();
                    if (result != null) {
                        for (String variable : result.keySet()) {
                            final ActionArgumentValue newArgument;
                            try {
                                newArgument = result.get(variable);
                            } catch (final Exception ex) {
                                logger.debug("An exception '{}' occurred, cannot get argument for variable '{}'", ex.getMessage(), variable);
                                continue;
                            }
                            try {
                                if (newArgument.getValue() != null) {
                                    resultMap.put(variable, newArgument.getValue().toString());
                                }
                            } catch (final Exception ex) {
                                logger.debug("An exception '{}' occurred processing ActionArgumentValue '{}' with value '{}'", ex.getMessage(), newArgument.getArgument().getName(), newArgument.getValue());
                            }
                        }
                    }
                } else {
                    logger.debug("Could not find action '{}' for participant '{}'", actionID, participant.getUDN());
                }
            } else {
                logger.debug("Could not find service '{}' for participant '{}'", serviceID, participant.getUDN());
            }
        } else {
            logger.debug("Could not find an upnp device for participant '{}'", participant.getUDN());
        }
    }
    return resultMap;
}
Also used : Action(org.jupnp.model.meta.Action) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ActionCallback(org.jupnp.controlpoint.ActionCallback) Device(org.jupnp.model.meta.Device) LocalDevice(org.jupnp.model.meta.LocalDevice) RemoteDevice(org.jupnp.model.meta.RemoteDevice) ActionInvocation(org.jupnp.model.action.ActionInvocation) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) UpnpIOService(org.eclipse.smarthome.io.transport.upnp.UpnpIOService) Service(org.jupnp.model.meta.Service) UpnpService(org.jupnp.UpnpService) ActionException(org.jupnp.model.action.ActionException) ActionException(org.jupnp.model.action.ActionException) ActionArgumentValue(org.jupnp.model.action.ActionArgumentValue)

Example 4 with ActionInvocation

use of org.jupnp.model.action.ActionInvocation in project openhab-core by openhab.

the class UpnpIOServiceImpl method invokeAction.

@SuppressWarnings("unchecked")
@Override
public Map<String, String> invokeAction(UpnpIOParticipant participant, String serviceID, String actionID, Map<String, String> inputs) {
    Map<String, String> resultMap = new HashMap<>();
    if (serviceID != null && actionID != null && participant != null) {
        registerParticipant(participant);
        Device device = getDevice(participant);
        if (device != null) {
            Service service = findService(device, serviceID);
            if (service != null) {
                Action action = service.getAction(actionID);
                if (action != null) {
                    ActionInvocation invocation = new ActionInvocation(action);
                    if (inputs != null) {
                        for (String variable : inputs.keySet()) {
                            invocation.setInput(variable, inputs.get(variable));
                        }
                    }
                    logger.trace("Invoking Action '{}' of service '{}' for participant '{}'", actionID, serviceID, participant.getUDN());
                    new ActionCallback.Default(invocation, upnpService.getControlPoint()).run();
                    ActionException anException = invocation.getFailure();
                    if (anException != null && anException.getMessage() != null) {
                        logger.debug("{}", anException.getMessage());
                    }
                    Map<String, ActionArgumentValue> result = invocation.getOutputMap();
                    if (result != null) {
                        for (String variable : result.keySet()) {
                            final ActionArgumentValue newArgument;
                            try {
                                newArgument = result.get(variable);
                            } catch (final Exception ex) {
                                logger.debug("An exception '{}' occurred, cannot get argument for variable '{}'", ex.getMessage(), variable);
                                continue;
                            }
                            try {
                                if (newArgument.getValue() != null) {
                                    resultMap.put(variable, newArgument.getValue().toString());
                                }
                            } catch (final Exception ex) {
                                logger.debug("An exception '{}' occurred processing ActionArgumentValue '{}' with value '{}'", ex.getMessage(), newArgument.getArgument().getName(), newArgument.getValue());
                            }
                        }
                    }
                } else {
                    logger.debug("Could not find action '{}' for participant '{}'", actionID, participant.getUDN());
                }
            } else {
                logger.debug("Could not find service '{}' for participant '{}'", serviceID, participant.getUDN());
            }
        } else {
            logger.debug("Could not find an upnp device for participant '{}'", participant.getUDN());
        }
    }
    return resultMap;
}
Also used : Action(org.jupnp.model.meta.Action) HashMap(java.util.HashMap) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ActionCallback(org.jupnp.controlpoint.ActionCallback) Device(org.jupnp.model.meta.Device) LocalDevice(org.jupnp.model.meta.LocalDevice) RemoteDevice(org.jupnp.model.meta.RemoteDevice) ActionInvocation(org.jupnp.model.action.ActionInvocation) UpnpIOService(org.openhab.core.io.transport.upnp.UpnpIOService) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Service(org.jupnp.model.meta.Service) UpnpService(org.jupnp.UpnpService) ActionException(org.jupnp.model.action.ActionException) ActionException(org.jupnp.model.action.ActionException) ActionArgumentValue(org.jupnp.model.action.ActionArgumentValue)

Example 5 with ActionInvocation

use of org.jupnp.model.action.ActionInvocation in project besu by hyperledger.

the class UpnpNatManager method requestPortForward.

/**
 * Sends a UPnP request to the discovered IGD to request a port forward.
 *
 * @param portMapping is a portMapping object describing the desired port mapping parameters.
 * @return A CompletableFuture that can be used to query the result (or error).
 */
private CompletableFuture<Void> requestPortForward(final PortMapping portMapping) {
    CompletableFuture<Void> upnpQueryFuture = new CompletableFuture<>();
    return externalIpQueryFuture.thenCompose(address -> {
        // note that this future is a dependency of externalIpQueryFuture, so it must be completed
        // by now
        RemoteService service = getService(SERVICE_TYPE_WAN_IP_CONNECTION).join();
        // so we can prime the NewInternalClient field if it was omitted
        if (null == portMapping.getInternalClient()) {
            portMapping.setInternalClient(discoveredOnLocalAddress.get());
        }
        // our query, which will be handled asynchronously by the jupnp library
        PortMappingAdd callback = new PortMappingAdd(service, portMapping) {

            /**
             * Because the underlying jupnp library omits generics info in this method
             * signature, we must too when we override it.
             */
            @Override
            @SuppressWarnings("rawtypes")
            public void success(final ActionInvocation invocation) {
                LOG.info("Port forward request for {} {} -> {} succeeded.", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
                synchronized (forwardedPorts) {
                    final NatServiceType natServiceType = NatServiceType.fromString(portMapping.getDescription());
                    final NatPortMapping natPortMapping = new NatPortMapping(natServiceType, NetworkProtocol.valueOf(portMapping.getProtocol().name()), portMapping.getInternalClient(), portMapping.getRemoteHost(), portMapping.getExternalPort().getValue().intValue(), portMapping.getInternalPort().getValue().intValue());
                    forwardedPorts.add(natPortMapping);
                }
                upnpQueryFuture.complete(null);
            }

            /**
             * Because the underlying jupnp library omits generics info in this method
             * signature, we must too when we override it.
             */
            @Override
            @SuppressWarnings("rawtypes")
            public void failure(final ActionInvocation invocation, final UpnpResponse operation, final String msg) {
                LOG.warn("Port forward request for {} {} -> {} failed: {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort(), msg);
                upnpQueryFuture.completeExceptionally(new Exception(msg));
            }
        };
        LOG.info("Requesting port forward for {} {} -> {}", portMapping.getProtocol(), portMapping.getInternalPort(), portMapping.getExternalPort());
        upnpService.getControlPoint().execute(callback);
        return upnpQueryFuture;
    });
}
Also used : CompletableFuture(java.util.concurrent.CompletableFuture) NatPortMapping(org.hyperledger.besu.nat.core.domain.NatPortMapping) RemoteService(org.jupnp.model.meta.RemoteService) UpnpResponse(org.jupnp.model.message.UpnpResponse) ActionInvocation(org.jupnp.model.action.ActionInvocation) PortMappingAdd(org.jupnp.support.igd.callback.PortMappingAdd) NatServiceType(org.hyperledger.besu.nat.core.domain.NatServiceType) NatInitializationException(org.hyperledger.besu.nat.core.exception.NatInitializationException)

Aggregations

ActionInvocation (org.jupnp.model.action.ActionInvocation)5 UpnpResponse (org.jupnp.model.message.UpnpResponse)3 RemoteDevice (org.jupnp.model.meta.RemoteDevice)3 RemoteService (org.jupnp.model.meta.RemoteService)3 HashMap (java.util.HashMap)2 CompletableFuture (java.util.concurrent.CompletableFuture)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)2 NatPortMapping (org.hyperledger.besu.nat.core.domain.NatPortMapping)2 NatInitializationException (org.hyperledger.besu.nat.core.exception.NatInitializationException)2 UpnpService (org.jupnp.UpnpService)2 ActionCallback (org.jupnp.controlpoint.ActionCallback)2 ActionArgumentValue (org.jupnp.model.action.ActionArgumentValue)2 ActionException (org.jupnp.model.action.ActionException)2 Action (org.jupnp.model.meta.Action)2 Device (org.jupnp.model.meta.Device)2 LocalDevice (org.jupnp.model.meta.LocalDevice)2 Service (org.jupnp.model.meta.Service)2 ArrayList (java.util.ArrayList)1 UpnpIOService (org.eclipse.smarthome.io.transport.upnp.UpnpIOService)1