From beb6fdd35340740b17639fb8aa5e52d3483ce850 Mon Sep 17 00:00:00 2001 From: Meutel Date: Sun, 11 Jun 2017 20:16:32 +0200 Subject: [PATCH] Init Advertise, not parsing response --- .gitignore | 5 ++ module.conf | 5 ++ pom.xml | 89 +++++++++++++++++++ .../swarm/etcd/EtcdTopologyFraction.java | 47 ++++++++++ .../meutel/swarm/etcd/runtime/EtcdClient.java | 74 +++++++++++++++ .../etcd/runtime/EtcdClientActivator.java | 32 +++++++ .../etcd/runtime/EtcdTopologyConnector.java | 64 +++++++++++++ .../EtcdTopologyConnectorActivator.java | 26 ++++++ .../modules/io/vertx/main/module.xml | 11 +++ 9 files changed, 353 insertions(+) create mode 100644 .gitignore create mode 100644 module.conf create mode 100644 pom.xml create mode 100644 src/main/java/net/meutel/swarm/etcd/EtcdTopologyFraction.java create mode 100644 src/main/java/net/meutel/swarm/etcd/runtime/EtcdClient.java create mode 100644 src/main/java/net/meutel/swarm/etcd/runtime/EtcdClientActivator.java create mode 100644 src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnector.java create mode 100644 src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnectorActivator.java create mode 100644 src/main/resources/modules/io/vertx/main/module.xml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..31992a5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +target +*.iml +*.swp +*~ +.idea diff --git a/module.conf b/module.conf new file mode 100644 index 0000000..aa896e4 --- /dev/null +++ b/module.conf @@ -0,0 +1,5 @@ +org.jboss.msc +org.wildfly.swarm.topology:runtime +org.wildfly.swarm.topology +org.jboss.as.network +io.vertx diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..3732192 --- /dev/null +++ b/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + net.meutel.swarm + topology-etcd + 1.0-SNAPSHOT + Topology etcd + Wildfly Swarm topology implementation with etcd + + 2017.6.0 + 55 + 3.3.3 + 1.8 + 1.8 + UTF-8 + + + + + org.wildfly.swarm + bom-all + ${version.swarm} + pom + import + + + io.vertx + vertx-core + ${version.vertx} + + + + + + javax.inject + javax.inject + provided + + + javax.enterprise + cdi-api + provided + + + org.wildfly.swarm + topology + provided + + + org.wildfly.swarm + msc + provided + + + org.wildfly.core + wildfly-network + provided + + + io.vertx + vertx-core + + + + + + src/main/resources + true + + + + + org.wildfly.swarm + wildfly-swarm-fraction-plugin + ${version.swarm.fraction-plugin} + + + process-classes + + process + + + + + + + diff --git a/src/main/java/net/meutel/swarm/etcd/EtcdTopologyFraction.java b/src/main/java/net/meutel/swarm/etcd/EtcdTopologyFraction.java new file mode 100644 index 0000000..9aace6d --- /dev/null +++ b/src/main/java/net/meutel/swarm/etcd/EtcdTopologyFraction.java @@ -0,0 +1,47 @@ +package net.meutel.swarm.etcd; + +import org.wildfly.swarm.config.runtime.AttributeDocumentation; +import org.wildfly.swarm.spi.api.Defaultable; +import org.wildfly.swarm.spi.api.Fraction; +import org.wildfly.swarm.spi.api.annotations.Configurable; + +import java.net.MalformedURLException; +import java.net.URL; + +/** + * Fraction Etcd Topology. + */ +@Configurable("net.meutel.etcd") +public class EtcdTopologyFraction implements Fraction { + + private static final URL DEFAULT_URL; + + @AttributeDocumentation("Etcd URL") + private Defaultable url = Defaultable.url(DEFAULT_URL); + + static { + URL tmp = null; + try { + tmp = new URL("http://localhost:2379"); + } catch (MalformedURLException e) { + throw new RuntimeException(e); + } + DEFAULT_URL = tmp; + } + + public EtcdTopologyFraction() { + this(DEFAULT_URL); + } + + public EtcdTopologyFraction(URL url) { + this.url.set(url); + } + + public EtcdTopologyFraction(String url) throws MalformedURLException { + this.url.set(new URL(url)); + } + + public URL url() { + return this.url.get(); + } +} diff --git a/src/main/java/net/meutel/swarm/etcd/runtime/EtcdClient.java b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdClient.java new file mode 100644 index 0000000..69f3e70 --- /dev/null +++ b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdClient.java @@ -0,0 +1,74 @@ +package net.meutel.swarm.etcd.runtime; + +import io.vertx.core.Vertx; +import io.vertx.core.http.HttpClient; +import io.vertx.core.http.HttpClientOptions; +import io.vertx.core.http.HttpClientResponse; +import org.jboss.msc.service.*; +import java.net.URL; + +/** + * Etcd Client. + */ +public class EtcdClient implements Service { + + public static final ServiceName SERVICE_NAME = ServiceName.of("net", "meutel", "swarm","topology", "etcd", "client"); + + HttpClient httpClient; + + URL url; + + public EtcdClient(URL url) { + this.url = url; + } + + public void createInDir(String dir, String value) { + String body = "value=" + value; +// String body = "nimp"; + System.out.println(" - createInDir: " + body); + this.httpClient.post("/v2/keys/" + dir, this::parseResponse) + .exceptionHandler(throwable -> { + System.err.println("EtcdClient error"); + throwable.printStackTrace(); + }) +// .setChunked(true) + .putHeader("Content-Length", String.valueOf(body.length())) + .putHeader("Content-Type", "application/x-www-form-urlencoded") + .write(body) + .end(); + } + + private void parseResponse(HttpClientResponse resp) { + int st = resp.statusCode(); + if (st < 200 || (st >= 300 && st < 400)) { + System.err.println("Unexpected status: " + st); + } else if (st >= 400 && st < 500) { + System.err.println("Request error: " + st+ " (" + resp.statusMessage() + ")"); + } else if (st >= 500) { + System.err.println("Etcd error: " + st+ " (" + resp.statusMessage() + ")"); + } + resp.handler(buffer -> System.out.print(" = " + buffer)); + } + + @Override + public void start(StartContext startContext) throws StartException { + System.out.println("Starting EtcdClient for " + this.url); + this.httpClient = Vertx.vertx() + .createHttpClient(new HttpClientOptions() + .setLogActivity(true) + .setDefaultHost(this.url.getHost()) + .setDefaultPort(this.url.getPort()) + .setConnectTimeout(1000) + .setMaxPoolSize(10)); + } + + @Override + public void stop(StopContext stopContext) { + + } + + @Override + public EtcdClient getValue() throws IllegalStateException, IllegalArgumentException { + return this; + } +} diff --git a/src/main/java/net/meutel/swarm/etcd/runtime/EtcdClientActivator.java b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdClientActivator.java new file mode 100644 index 0000000..dd6a955 --- /dev/null +++ b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdClientActivator.java @@ -0,0 +1,32 @@ +package net.meutel.swarm.etcd.runtime; + +import net.meutel.swarm.etcd.EtcdTopologyFraction; +import org.jboss.msc.service.ServiceActivator; +import org.jboss.msc.service.ServiceActivatorContext; +import org.jboss.msc.service.ServiceRegistryException; +import org.jboss.msc.service.ServiceTarget; +import org.wildfly.swarm.topology.runtime.TopologyManager; +import org.wildfly.swarm.topology.runtime.TopologyManagerActivator; + +import javax.enterprise.context.ApplicationScoped; +import javax.enterprise.inject.Any; +import javax.inject.Inject; + +/** + * EtcdClient MSC activator. + */ +@ApplicationScoped +public class EtcdClientActivator implements ServiceActivator { + + @Inject + @Any + EtcdTopologyFraction fraction; + + public void activate(ServiceActivatorContext context) throws ServiceRegistryException { + System.out.println("Activate Etcd client"); + ServiceTarget target = context.getServiceTarget(); + EtcdClient client = new EtcdClient(fraction.url()); + target.addService(EtcdClient.SERVICE_NAME, client) + .install(); + } +} diff --git a/src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnector.java b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnector.java new file mode 100644 index 0000000..1551126 --- /dev/null +++ b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnector.java @@ -0,0 +1,64 @@ +package net.meutel.swarm.etcd.runtime; + +import org.jboss.as.network.SocketBinding; +import org.jboss.msc.inject.Injector; +import org.jboss.msc.service.Service; +import org.jboss.msc.service.StartContext; +import org.jboss.msc.service.StartException; +import org.jboss.msc.service.StopContext; +import org.jboss.msc.value.InjectedValue; +import org.wildfly.swarm.topology.TopologyConnector; +import org.wildfly.swarm.topology.runtime.Registration; +import org.wildfly.swarm.topology.runtime.TopologyManager; + +import java.net.URL; + +/** + * Topology connector for etcd. + */ +public class EtcdTopologyConnector implements Service, TopologyConnector { + + private static String TOPOLOGY_SOURCE_KEY = "etcd"; + + private EtcdClient client; + + private InjectedValue topologyManagerInjector = new InjectedValue<>(); + + private InjectedValue clientInjector = new InjectedValue<>(); + + public Injector getClientInjector() { + return this.clientInjector; + } + + public EtcdTopologyConnector getValue() throws IllegalStateException, IllegalArgumentException { + return this; + } + + public Injector getTopologyManagerInjector() { + return this.topologyManagerInjector; + } + + public void start(StartContext startContext) throws StartException { + System.out.println("Starting EtcdTopology"); + this.client = this.clientInjector.getValue(); + } + + public void stop(StopContext stopContext) { + this.client = null; + } + + public synchronized void advertise(String name, SocketBinding binding, String... tags) throws Exception { + Registration registration = new Registration(TOPOLOGY_SOURCE_KEY, name, binding.getAddress().getHostAddress(), binding.getAbsolutePort(), tags); + System.out.println("registration: " + registration); + + this.topologyManagerInjector.getValue().register(registration); + + URL url = new URL("http", registration.getAddress(), registration.getPort(),""); + System.out.println("URL for service " + name + ": " + url); + client.createInDir(name, url.toExternalForm()); + } + + public synchronized void unadvertise(String name, SocketBinding binding) throws Exception { + + } +} diff --git a/src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnectorActivator.java b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnectorActivator.java new file mode 100644 index 0000000..ea3b84e --- /dev/null +++ b/src/main/java/net/meutel/swarm/etcd/runtime/EtcdTopologyConnectorActivator.java @@ -0,0 +1,26 @@ +package net.meutel.swarm.etcd.runtime; + +import org.jboss.msc.service.*; +import org.wildfly.swarm.topology.runtime.TopologyManager; +import org.wildfly.swarm.topology.runtime.TopologyManagerActivator; + +import javax.enterprise.context.ApplicationScoped; + +/** + * Etcd Topology MSC activator. + */ +@ApplicationScoped +public class EtcdTopologyConnectorActivator implements ServiceActivator { + + public void activate(ServiceActivatorContext context) throws ServiceRegistryException { + System.out.println("Activate Etcd topology"); + ServiceTarget target = context.getServiceTarget(); + + EtcdTopologyConnector connector = new EtcdTopologyConnector(); + + target.addService(TopologyManagerActivator.CONNECTOR_SERVICE_NAME, connector) + .addDependency(TopologyManagerActivator.SERVICE_NAME, TopologyManager.class, connector.getTopologyManagerInjector()) + .addDependency(EtcdClient.SERVICE_NAME, EtcdClient.class, connector.getClientInjector()) + .install(); + } +} diff --git a/src/main/resources/modules/io/vertx/main/module.xml b/src/main/resources/modules/io/vertx/main/module.xml new file mode 100644 index 0000000..c2cf6db --- /dev/null +++ b/src/main/resources/modules/io/vertx/main/module.xml @@ -0,0 +1,11 @@ + + + + + + + + + + +