BesuUpnpServiceConfiguration.java
/*
* Copyright ConsenSys AG.
*
* Licensed 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.nat.upnp;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import org.jupnp.DefaultUpnpServiceConfiguration;
import org.jupnp.UpnpServiceConfiguration;
import org.jupnp.binding.xml.DeviceDescriptorBinder;
import org.jupnp.binding.xml.ServiceDescriptorBinder;
import org.jupnp.binding.xml.UDA10DeviceDescriptorBinderImpl;
import org.jupnp.binding.xml.UDA10ServiceDescriptorBinderImpl;
import org.jupnp.model.Namespace;
import org.jupnp.model.message.UpnpHeaders;
import org.jupnp.model.meta.RemoteDeviceIdentity;
import org.jupnp.model.meta.RemoteService;
import org.jupnp.model.types.ServiceType;
import org.jupnp.transport.impl.DatagramIOConfigurationImpl;
import org.jupnp.transport.impl.DatagramIOImpl;
import org.jupnp.transport.impl.DatagramProcessorImpl;
import org.jupnp.transport.impl.GENAEventProcessorImpl;
import org.jupnp.transport.impl.MulticastReceiverConfigurationImpl;
import org.jupnp.transport.impl.MulticastReceiverImpl;
import org.jupnp.transport.impl.NetworkAddressFactoryImpl;
import org.jupnp.transport.impl.SOAPActionProcessorImpl;
import org.jupnp.transport.impl.jetty.StreamClientConfigurationImpl;
import org.jupnp.transport.spi.DatagramIO;
import org.jupnp.transport.spi.DatagramProcessor;
import org.jupnp.transport.spi.GENAEventProcessor;
import org.jupnp.transport.spi.MulticastReceiver;
import org.jupnp.transport.spi.NetworkAddressFactory;
import org.jupnp.transport.spi.SOAPActionProcessor;
import org.jupnp.transport.spi.StreamClient;
import org.jupnp.transport.spi.StreamServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class BesuUpnpServiceConfiguration implements UpnpServiceConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(BesuUpnpServiceConfiguration.class);
private final ThreadPoolExecutor executorService;
private final DeviceDescriptorBinder deviceDescriptorBinderUDA10;
private final ServiceDescriptorBinder serviceDescriptorBinderUDA10;
private final int streamListenPort;
private final int multicastResponsePort;
private final Namespace namespace;
BesuUpnpServiceConfiguration() {
this(
NetworkAddressFactoryImpl.DEFAULT_TCP_HTTP_LISTEN_PORT,
NetworkAddressFactoryImpl.DEFAULT_MULTICAST_RESPONSE_LISTEN_PORT);
}
private BesuUpnpServiceConfiguration(
final int streamListenPort, final int multicastResponsePort) {
executorService =
new ThreadPoolExecutor(
16,
200,
10,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(2000),
new DefaultUpnpServiceConfiguration.JUPnPThreadFactory(),
new ThreadPoolExecutor.DiscardPolicy() {
// The pool is bounded and rejections will happen during shutdown
@Override
public void rejectedExecution(
final Runnable runnable, final ThreadPoolExecutor threadPoolExecutor) {
// Log and discard
LOG.warn("Thread pool rejected execution of " + runnable.getClass());
super.rejectedExecution(runnable, threadPoolExecutor);
}
});
executorService.allowCoreThreadTimeOut(true);
deviceDescriptorBinderUDA10 = new UDA10DeviceDescriptorBinderImpl();
serviceDescriptorBinderUDA10 = new UDA10ServiceDescriptorBinderImpl();
namespace = new Namespace();
this.streamListenPort = streamListenPort;
this.multicastResponsePort = multicastResponsePort;
}
@Override
public NetworkAddressFactory createNetworkAddressFactory() {
return new NetworkAddressFactoryImpl(streamListenPort, multicastResponsePort);
}
@Override
public DatagramProcessor getDatagramProcessor() {
return new DatagramProcessorImpl();
}
@Override
public SOAPActionProcessor getSoapActionProcessor() {
return new SOAPActionProcessorImpl();
}
@Override
public GENAEventProcessor getGenaEventProcessor() {
return new GENAEventProcessorImpl();
}
@SuppressWarnings("rawtypes") // superclass uses raw types
@Override
public StreamClient createStreamClient() {
return new OkHttpStreamClient(new StreamClientConfigurationImpl(executorService));
}
@SuppressWarnings("rawtypes") // superclass uses raw types
@Override
public MulticastReceiver createMulticastReceiver(
final NetworkAddressFactory networkAddressFactory) {
return new MulticastReceiverImpl(
new MulticastReceiverConfigurationImpl(
networkAddressFactory.getMulticastGroup(), networkAddressFactory.getMulticastPort()));
}
@SuppressWarnings("rawtypes") // superclass uses raw types
@Override
public DatagramIO createDatagramIO(final NetworkAddressFactory networkAddressFactory) {
return new DatagramIOImpl(new DatagramIOConfigurationImpl());
}
@SuppressWarnings("rawtypes") // superclass uses raw types
@Override
public StreamServer createStreamServer(final NetworkAddressFactory networkAddressFactory) {
return null;
}
@Override
public Executor getMulticastReceiverExecutor() {
return executorService;
}
@Override
public Executor getDatagramIOExecutor() {
return executorService;
}
@Override
public ExecutorService getStreamServerExecutorService() {
return executorService;
}
@Override
public DeviceDescriptorBinder getDeviceDescriptorBinderUDA10() {
return deviceDescriptorBinderUDA10;
}
@Override
public ServiceDescriptorBinder getServiceDescriptorBinderUDA10() {
return serviceDescriptorBinderUDA10;
}
@Override
public ServiceType[] getExclusiveServiceTypes() {
return new ServiceType[0];
}
@Override
public int getRegistryMaintenanceIntervalMillis() {
return 1000;
}
@Override
public int getAliveIntervalMillis() {
return 0;
}
@Override
public boolean isReceivedSubscriptionTimeoutIgnored() {
return false;
}
@Override
public Integer getRemoteDeviceMaxAgeSeconds() {
return null;
}
@Override
public UpnpHeaders getDescriptorRetrievalHeaders(final RemoteDeviceIdentity identity) {
return null;
}
@Override
public UpnpHeaders getEventSubscriptionHeaders(final RemoteService service) {
return null;
}
@Override
public Executor getAsyncProtocolExecutor() {
return executorService;
}
@Override
public ExecutorService getSyncProtocolExecutorService() {
return executorService;
}
@Override
public Namespace getNamespace() {
return namespace;
}
@Override
public Executor getRegistryMaintainerExecutor() {
return executorService;
}
@Override
public Executor getRegistryListenerExecutor() {
return executorService;
}
@Override
public Executor getRemoteListenerExecutor() {
return executorService;
}
@Override
public void shutdown() {
executorService.shutdown();
}
}