use of org.eclipse.californium.scandium.DtlsClusterConnector in project californium by eclipse.
the class ExtendedTestServer method main.
public static void main(String[] args) {
CommandLine cmd = new CommandLine(config);
config.register(cmd);
try {
ParseResult result = cmd.parseArgs(args);
if (result.isVersionHelpRequested()) {
System.out.println("\nCalifornium (Cf) " + cmd.getCommandName() + " " + PlugtestServer.CALIFORNIUM_BUILD_VERSION);
cmd.printVersionHelp(System.out);
System.out.println();
}
if (result.isUsageHelpRequested()) {
cmd.usage(System.out);
return;
}
} catch (ParameterException ex) {
System.err.println(ex.getMessage());
System.err.println();
cmd.usage(System.err);
System.exit(-1);
}
STATISTIC_LOGGER.error("start!");
ManagementStatistic management = new ManagementStatistic(STATISTIC_LOGGER);
try {
K8sManagementClient k8sClient = null;
K8sDiscoverClient k8sGroup = null;
DtlsClusterConnectorConfig.Builder clusterConfigBuilder = DtlsClusterConnectorConfig.builder();
Configuration configuration = Configuration.createWithFile(CONFIG_FILE, CONFIG_HEADER, DEFAULTS);
if (config.cluster != null) {
int nodeId = -1;
clusterConfigBuilder.setBackwardMessage(config.cluster.backwardClusterMessages);
if (config.cluster.clusterType.k8sCluster != null) {
clusterConfigBuilder.setAddress(config.cluster.clusterType.k8sCluster.cluster);
clusterConfigBuilder.setClusterMac(config.cluster.dtlsClusterMac);
K8sDiscoverClient.setConfiguration(clusterConfigBuilder);
k8sClient = new K8sManagementJdkClient();
k8sGroup = new K8sDiscoverClient(k8sClient, config.cluster.clusterType.k8sCluster.externalPort);
nodeId = k8sGroup.getNodeID();
LOGGER.info("dynamic k8s-cluster!");
} else if (config.cluster.clusterType.simpleCluster != null) {
for (ClusterNode cluster : config.cluster.clusterType.simpleCluster.dtlsClusterNodes) {
if (cluster.dtls != null) {
nodeId = cluster.nodeId;
break;
}
}
if (nodeId < 0) {
throw new IllegalArgumentException("at least one cluster node must have a dtls interface!");
}
if (config.cluster.clusterType.simpleCluster.dtlsClusterGroup != null) {
LOGGER.info("dynamic dtls-cluster!");
String secret = config.cluster.clusterType.simpleCluster.dtlsClusterGroupSecurity;
if (secret != null) {
SecretKey key = SecretUtil.create(secret.getBytes(), "PSK");
clusterConfigBuilder.setSecure("dtls-mgmt", key);
SecretUtil.destroy(key);
clusterConfigBuilder.setClusterMac(config.cluster.dtlsClusterMac);
}
} else {
LOGGER.info("static dtls-cluster!");
}
}
configuration.set(DtlsConfig.DTLS_CONNECTION_ID_NODE_ID, nodeId);
} else if (config.plugtest) {
// start standard plugtest server
PlugtestServer.init(config);
}
Configuration udpConfiguration = new Configuration(configuration).set(CoapConfig.MAX_MESSAGE_SIZE, configuration.get(EXTERNAL_UDP_MAX_MESSAGE_SIZE)).set(CoapConfig.PREFERRED_BLOCK_SIZE, configuration.get(EXTERNAL_UDP_PREFERRED_BLOCK_SIZE));
Map<Select, Configuration> protocolConfig = new HashMap<>();
protocolConfig.put(new Select(Protocol.UDP, InterfaceType.EXTERNAL), udpConfiguration);
// create server
List<Protocol> protocols = config.getProtocols();
List<InterfaceType> types = config.getInterfaceTypes();
ScheduledExecutorService executor = //
ExecutorsUtil.newScheduledThreadPool(//
configuration.get(CoapConfig.PROTOCOL_STAGE_THREAD_COUNT), // $NON-NLS-1$
new NamedThreadFactory("ExtCoapServer(main)#"));
ScheduledExecutorService secondaryExecutor = ExecutorsUtil.newDefaultSecondaryScheduler("ExtCoapServer(secondary)#");
long notifyIntervalMillis = config.getNotifyIntervalMillis();
final ExtendedTestServer server = new ExtendedTestServer(configuration, protocolConfig, config.benchmark, notifyIntervalMillis);
server.setVersion(PlugtestServer.CALIFORNIUM_BUILD_VERSION);
server.setTag("EXTENDED-TEST");
server.setExecutors(executor, secondaryExecutor, false);
server.add(new Echo(configuration.get(CoapConfig.MAX_RESOURCE_BODY_SIZE), config.echoDelay ? executor : null));
if (config.diagnose) {
server.add(new Diagnose(server));
}
server.add(new ReverseRequest(configuration, executor));
ReverseObserve reverseObserver = new ReverseObserve(configuration, executor);
server.add(reverseObserver);
if (k8sGroup != null) {
DtlsClusterConnectorConfig clusterConfig = clusterConfigBuilder.build();
server.addClusterEndpoint(secondaryExecutor, config.cluster.clusterType.k8sCluster.dtls, k8sGroup.getNodeID(), clusterConfig, null, k8sGroup, config);
} else if (config.cluster != null && config.cluster.clusterType.simpleCluster != null) {
ClusterGroup group = null;
DtlsClusterConnector.ClusterNodesProvider nodes = null;
if (config.cluster.clusterType.simpleCluster.dtlsClusterGroup == null) {
nodes = new DtlsClusterConnector.ClusterNodesProvider() {
@Override
public InetSocketAddress getClusterNode(int nodeId) {
for (ClusterNode node : config.cluster.clusterType.simpleCluster.dtlsClusterNodes) {
if (node.nodeId == nodeId) {
return node.cluster;
}
}
return null;
}
@Override
public boolean available(InetSocketAddress destinationConnector) {
return true;
}
};
}
for (ClusterNode cluster : config.cluster.clusterType.simpleCluster.dtlsClusterNodes) {
if (cluster.dtls != null) {
DtlsClusterConnectorConfig clusterConfig = DtlsClusterConnectorConfig.builder(clusterConfigBuilder.getIncompleteConfig()).setAddress(cluster.cluster).build();
if (config.cluster.clusterType.simpleCluster.dtlsClusterGroup != null) {
group = new ClusterGroup(config.cluster.clusterType.simpleCluster.dtlsClusterGroup);
}
server.addClusterEndpoint(secondaryExecutor, cluster.dtls, cluster.nodeId, clusterConfig, nodes, group, config);
}
}
} else if (config.restore != null) {
// restore the dtls state from an other host with different
// local network addresses,
// requires to use the wildcard address for the connector.
int port = configuration.get(CoapConfig.COAP_SECURE_PORT);
server.addEndpoint(new InetSocketAddress(port), config);
}
// Statistic for dropped udp messages
final NetSocketHealthLogger socketLogger = new NetSocketHealthLogger("udp");
EndpointNetSocketObserver socketObserver = null;
long interval = configuration.get(SystemConfig.HEALTH_STATUS_INTERVAL, TimeUnit.MILLISECONDS);
if (interval > 0 && socketLogger.isEnabled()) {
server.add(socketLogger);
long readInterval = configuration.get(UDP_DROPS_READ_INTERVAL, TimeUnit.MILLISECONDS);
if (interval > readInterval) {
secondaryExecutor.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
socketLogger.read();
}
}, readInterval, readInterval, TimeUnit.MILLISECONDS);
}
socketObserver = new EndpointNetSocketObserver(socketLogger);
server.addDefaultEndpointObserver(socketObserver);
EndpointNetSocketObserver internalSocketObserver = new EndpointNetSocketObserver(socketLogger) {
protected SimpleCounterStatistic getExternalStatistic(Endpoint endpoint) {
CounterStatisticManager dtlsStatisticManager = getDtlsStatisticManager(endpoint);
return dtlsStatisticManager != null ? dtlsStatisticManager.getByKey(DtlsClusterHealthLogger.DROPPED_INTERNAL_UDP_MESSAGES) : null;
}
@Override
protected InetSocketAddress getAddress(Endpoint endpoint) {
if (endpoint instanceof CoapEndpoint) {
Connector connector = ((CoapEndpoint) endpoint).getConnector();
if (connector instanceof DtlsClusterConnector) {
return ((DtlsClusterConnector) connector).getClusterInternalAddress();
}
}
return null;
}
};
server.addDefaultEndpointObserver(internalSocketObserver);
}
// using cluster removes dtls from protocols
server.addEndpoints(config.interfacePatterns, types, protocols, config);
if (server.getEndpoints().isEmpty()) {
System.err.println("no endpoint available!");
System.exit(PlugtestServer.ERR_INIT_FAILED);
}
for (Endpoint ep : server.getEndpoints()) {
ep.addNotificationListener(reverseObserver);
}
InetSocketAddress httpLocal = config.k8sMonitor;
InetSocketAddress httpsRestoreLocal = null;
InetSocketAddress httpsRestoreOther = null;
SSLContext context = null;
K8sRestoreJdkHttpClient client = null;
SSLContext clientContext = null;
if (config.restore != null) {
if (config.restore.restoreSource.restoreK8s != null) {
httpsRestoreLocal = config.restore.restoreSource.restoreK8s;
httpsRestoreOther = new InetSocketAddress(httpsRestoreLocal.getPort());
} else if (config.restore.restoreSource.restorePair != null) {
httpsRestoreLocal = config.restore.restoreSource.restorePair.restoreLocal;
httpsRestoreOther = config.restore.restoreSource.restorePair.restoreOther;
}
context = CredentialsUtil.getClusterInternalHttpsServerContext();
}
if (httpLocal != null || httpsRestoreLocal != null) {
long maxAgeSeconds = config.restore != null ? TimeUnit.HOURS.toSeconds(config.restore.maxAge) : 0;
final JdkMonitorService monitor = new JdkMonitorService(httpLocal, httpsRestoreLocal, maxAgeSeconds, context);
monitor.addServer(server);
if (context != null) {
clientContext = CredentialsUtil.getClusterInternalHttpsClientContext();
if (clientContext != null) {
client = new K8sRestoreJdkHttpClient();
monitor.addComponent(client);
}
}
monitor.start();
}
PlugtestServer.add(server);
PlugtestServer.load(config);
// start standard plugtest server and shutdown
PlugtestServer.start(executor, secondaryExecutor, config, configuration, socketObserver, null);
server.start();
server.addLogger(!config.benchmark);
List<CounterStatisticManager> statistics = new ArrayList<>();
ObserveStatisticLogger obsStatLogger = new ObserveStatisticLogger(server.getTag());
if (obsStatLogger.isEnabled()) {
statistics.add(obsStatLogger);
server.add(obsStatLogger);
server.setObserveHealth(obsStatLogger);
}
Resource child = server.getRoot().getChild(Diagnose.RESOURCE_NAME);
if (child instanceof Diagnose) {
((Diagnose) child).update(statistics);
}
PlugtestServer.ActiveInputReader reader = new PlugtestServer.ActiveInputReader();
if (interval > 0) {
if (config.ipv4) {
NetStatLogger netStatLogger = new NetStatLogger("udp", false);
if (netStatLogger.isEnabled()) {
server.add(netStatLogger);
LOGGER.info("udp health enabled.");
} else {
LOGGER.warn("udp health not enabled!");
}
}
if (config.ipv6) {
NetStatLogger netStatLogger = new NetStatLogger("udp6", true);
if (netStatLogger.isEnabled()) {
server.add(netStatLogger);
LOGGER.info("udp6 health enabled.");
} else {
LOGGER.warn("udp6 health not enabled!");
}
}
} else {
interval = 30000;
}
Runtime runtime = Runtime.getRuntime();
long max = runtime.maxMemory();
StringBuilder builder = new StringBuilder(ExtendedTestServer.class.getSimpleName());
if (!PlugtestServer.CALIFORNIUM_BUILD_VERSION.isEmpty()) {
builder.append(", version ").append(PlugtestServer.CALIFORNIUM_BUILD_VERSION);
}
builder.append(", ").append(max / (1024 * 1024)).append("MB heap, started ...");
LOGGER.info("{}", builder);
while (!server.isReady()) {
Thread.sleep(500);
}
if (httpsRestoreOther != null && client != null) {
if (config.restore.restoreSource.restoreK8s != null) {
if (k8sClient == null) {
k8sClient = new K8sManagementJdkClient();
}
if (k8sGroup != null) {
client.restoreCluster(k8sClient, httpsRestoreOther.getPort(), clientContext, server);
} else {
client.restoreSingle(k8sClient, httpsRestoreOther.getPort(), clientContext, server);
}
} else {
String host = StringUtil.toHostString(httpsRestoreOther);
client.restore(InetAddress.getLocalHost().getHostName(), host, httpsRestoreOther.getPort(), clientContext, server);
}
}
if (!config.benchmark) {
LOGGER.info("{} without benchmark started ...", ExtendedTestServer.class.getSimpleName());
for (; ; ) {
if (PlugtestServer.console(reader, interval)) {
break;
}
server.dump();
}
} else {
long inputTimeout = interval < 15000 ? interval : 15000;
long lastGcCount = 0;
long lastDumpNanos = ClockUtil.nanoRealtime();
for (; ; ) {
if (PlugtestServer.console(reader, inputTimeout)) {
break;
}
if (management.useWarningMemoryUsage()) {
long used = runtime.totalMemory() - runtime.freeMemory();
int fill = (int) ((used * 100L) / max);
if (fill > 80) {
LOGGER.info("Maxium heap size: {}M {}% used.", max / MEGA, fill);
LOGGER.info("Heap may exceed! Enlarge the maxium heap size.");
LOGGER.info("Or consider to reduce the value of " + CoapConfig.EXCHANGE_LIFETIME);
LOGGER.info("in \"{}\" or set", CONFIG_FILE);
LOGGER.info("{} to {} or", CoapConfig.DEDUPLICATOR, CoapConfig.NO_DEDUPLICATOR);
LOGGER.info("{} in that file.", CoapConfig.PEERS_MARK_AND_SWEEP_MESSAGES);
}
}
long gcCount = management.getCollectionCount();
if (lastGcCount < gcCount) {
management.printManagementStatistic();
lastGcCount = gcCount;
long clones = DatagramWriter.COPIES.get();
long takes = DatagramWriter.TAKES.get();
if (clones + takes > 0) {
STATISTIC_LOGGER.info("DatagramWriter {} clones, {} takes, {}%", clones, takes, (takes * 100L) / (takes + clones));
}
}
long now = ClockUtil.nanoRealtime();
if ((now - lastDumpNanos - TimeUnit.MILLISECONDS.toNanos(interval)) > 0) {
lastDumpNanos = now;
server.dump();
}
}
}
PlugtestServer.shutdown();
server.stop();
LOGGER.info("Executor shutdown ...");
ExecutorsUtil.shutdownExecutorGracefully(500, executor, secondaryExecutor);
PlugtestServer.exit();
LOGGER.info("Exit ...");
} catch (Exception e) {
System.err.printf("Failed to create " + ExtendedTestServer.class.getSimpleName() + ": %s\n", e.getMessage());
e.printStackTrace(System.err);
System.err.println("Exiting");
System.exit(PlugtestServer.ERR_INIT_FAILED);
}
}
use of org.eclipse.californium.scandium.DtlsClusterConnector in project californium by eclipse.
the class ExtendedTestServer method addClusterEndpoint.
private void addClusterEndpoint(ScheduledExecutorService secondaryExecutor, InetSocketAddress dtlsInterface, int nodeId, DtlsClusterConnectorConfig clusterConfiguration, ClusterNodesProvider nodesProvider, ClusterNodesDiscover nodesDiscoverer, BaseConfig cliConfig) {
if (nodesDiscoverer == null ^ nodesProvider != null) {
throw new IllegalArgumentException("either nodes-provider or -dicoverer is required!");
}
InterfaceType interfaceType = dtlsInterface.getAddress().isLoopbackAddress() ? InterfaceType.LOCAL : InterfaceType.EXTERNAL;
Configuration configuration = getConfig(Protocol.DTLS, interfaceType);
String tag = "dtls:node-" + nodeId + ":" + StringUtil.toString(dtlsInterface);
int handshakeResultDelayMillis = configuration.getTimeAsInt(DTLS_HANDSHAKE_RESULT_DELAY, TimeUnit.MILLISECONDS);
long healthStatusIntervalMillis = configuration.get(SystemConfig.HEALTH_STATUS_INTERVAL, TimeUnit.MILLISECONDS);
Integer cidLength = configuration.get(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
if (cidLength == null || cidLength < 6) {
throw new IllegalArgumentException("cid length must be at least 6 for cluster!");
}
initCredentials();
DtlsConnectorConfig.Builder dtlsConfigBuilder = DtlsConnectorConfig.builder(configuration);
if (cliConfig.clientAuth != null) {
dtlsConfigBuilder.set(DtlsConfig.DTLS_CLIENT_AUTHENTICATION_MODE, cliConfig.clientAuth);
}
// set node-id in dtls-config-builder's Configuration clone
dtlsConfigBuilder.set(DtlsConfig.DTLS_CONNECTION_ID_NODE_ID, nodeId);
AsyncAdvancedPskStore asyncPskStore = new AsyncAdvancedPskStore(new PlugPskStore());
asyncPskStore.setDelay(handshakeResultDelayMillis);
dtlsConfigBuilder.setAdvancedPskStore(asyncPskStore);
dtlsConfigBuilder.setAddress(dtlsInterface);
X509KeyManager keyManager = SslContextUtil.getX509KeyManager(serverCredentials);
AsyncKeyManagerCertificateProvider certificateProvider = new AsyncKeyManagerCertificateProvider(keyManager, CertificateType.RAW_PUBLIC_KEY, CertificateType.X_509);
certificateProvider.setDelay(handshakeResultDelayMillis);
dtlsConfigBuilder.setCertificateIdentityProvider(certificateProvider);
AsyncNewAdvancedCertificateVerifier.Builder verifierBuilder = AsyncNewAdvancedCertificateVerifier.builder();
if (cliConfig.trustall) {
verifierBuilder.setTrustAllCertificates();
} else {
verifierBuilder.setTrustedCertificates(trustedCertificates);
}
verifierBuilder.setTrustAllRPKs();
AsyncNewAdvancedCertificateVerifier verifier = verifierBuilder.build();
verifier.setDelay(handshakeResultDelayMillis);
dtlsConfigBuilder.setAdvancedCertificateVerifier(verifier);
dtlsConfigBuilder.setConnectionListener(new MdcConnectionListener());
dtlsConfigBuilder.setLoggingTag(tag);
if (healthStatusIntervalMillis > 0) {
DtlsClusterHealthLogger health = new DtlsClusterHealthLogger(tag);
dtlsConfigBuilder.setHealthHandler(health);
add(health);
// reset to prevent active logger
dtlsConfigBuilder.set(SystemConfig.HEALTH_STATUS_INTERVAL, 0, TimeUnit.MILLISECONDS);
}
DtlsConnectorConfig dtlsConnectorConfig = dtlsConfigBuilder.build();
CoapEndpoint.Builder builder = new CoapEndpoint.Builder();
EndpointObserver endpointObserver = null;
if (nodesDiscoverer != null) {
DtlsManagedClusterConnector connector = new DtlsManagedClusterConnector(dtlsConnectorConfig, clusterConfiguration);
final DtlsClusterManager manager = new DtlsClusterManager(connector, dtlsConnectorConfig.getConfiguration(), nodesDiscoverer, secondaryExecutor);
builder.setConnector(connector);
endpointObserver = new EndpointObserver() {
@Override
public void stopped(Endpoint endpoint) {
manager.stop();
}
@Override
public void started(Endpoint endpoint) {
manager.start();
}
@Override
public void destroyed(Endpoint endpoint) {
manager.stop();
}
};
components.add(manager);
} else if (nodesProvider != null) {
builder.setConnector(new DtlsClusterConnector(dtlsConnectorConfig, clusterConfiguration, nodesProvider));
}
// use dtls-config-builder's Configuration clone with the set node-id
builder.setConfiguration(dtlsConnectorConfig.getConfiguration());
CoapEndpoint endpoint = builder.build();
if (healthStatusIntervalMillis > 0) {
HealthStatisticLogger healthLogger = new HealthStatisticLogger(CoAP.COAP_SECURE_URI_SCHEME + "-" + nodeId, true);
if (healthLogger.isEnabled()) {
endpoint.addPostProcessInterceptor(healthLogger);
add(healthLogger);
}
}
if (endpointObserver != null) {
endpoint.addObserver(endpointObserver);
}
addEndpoint(endpoint);
print(endpoint, interfaceType);
}
Aggregations