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]));
}
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);
});
}
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;
}
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;
}
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;
});
}
Aggregations