Search in sources :

Example 11 with Endpoint

use of io.atomix.messaging.Endpoint in project atomix by atomix.

the class DefaultClusterEventingServiceTest method testClusterEventService.

@Test
public void testClusterEventService() throws Exception {
    TestMessagingServiceFactory factory = new TestMessagingServiceFactory();
    ClusterMetadata clusterMetadata = buildClusterMetadata(1, 1, 2, 3);
    Node localNode1 = buildNode(1, Node.Type.CORE);
    MessagingService messagingService1 = factory.newMessagingService(localNode1.endpoint()).start().join();
    ClusterService clusterService1 = new DefaultClusterService(localNode1, new TestClusterMetadataService(clusterMetadata), messagingService1).start().join();
    ClusterEventingService eventService1 = new DefaultClusterEventingService(clusterService1, messagingService1).start().join();
    Node localNode2 = buildNode(2, Node.Type.CORE);
    MessagingService messagingService2 = factory.newMessagingService(localNode2.endpoint()).start().join();
    ClusterService clusterService2 = new DefaultClusterService(localNode2, new TestClusterMetadataService(clusterMetadata), messagingService2).start().join();
    ClusterEventingService eventService2 = new DefaultClusterEventingService(clusterService2, messagingService2).start().join();
    Node localNode3 = buildNode(3, Node.Type.CORE);
    MessagingService messagingService3 = factory.newMessagingService(localNode3.endpoint()).start().join();
    ClusterService clusterService3 = new DefaultClusterService(localNode3, new TestClusterMetadataService(clusterMetadata), messagingService3).start().join();
    ClusterEventingService eventService3 = new DefaultClusterEventingService(clusterService3, messagingService3).start().join();
    Thread.sleep(100);
    Set<Integer> events = new CopyOnWriteArraySet<>();
    eventService1.<String>subscribe("test1", SERIALIZER::decode, message -> {
        assertEquals(message, "Hello world!");
        events.add(1);
    }, MoreExecutors.directExecutor()).join();
    eventService2.<String>subscribe("test1", SERIALIZER::decode, message -> {
        assertEquals(message, "Hello world!");
        events.add(2);
    }, MoreExecutors.directExecutor()).join();
    eventService2.<String>subscribe("test1", SERIALIZER::decode, message -> {
        assertEquals(message, "Hello world!");
        events.add(3);
    }, MoreExecutors.directExecutor()).join();
    eventService3.broadcast("test1", "Hello world!", SERIALIZER::encode);
    Thread.sleep(100);
    assertEquals(3, events.size());
    events.clear();
    eventService3.unicast("test1", "Hello world!");
    Thread.sleep(100);
    assertEquals(1, events.size());
    assertTrue(events.contains(3));
    events.clear();
    eventService3.unicast("test1", "Hello world!");
    Thread.sleep(100);
    assertEquals(1, events.size());
    assertTrue(events.contains(1));
    events.clear();
    eventService3.unicast("test1", "Hello world!");
    Thread.sleep(100);
    assertEquals(1, events.size());
    assertTrue(events.contains(2));
    events.clear();
    eventService3.unicast("test1", "Hello world!");
    Thread.sleep(100);
    assertEquals(1, events.size());
    assertTrue(events.contains(3));
    events.clear();
    eventService1.<String, String>subscribe("test2", SERIALIZER::decode, message -> {
        events.add(1);
        return message;
    }, SERIALIZER::encode, MoreExecutors.directExecutor()).join();
    eventService2.<String, String>subscribe("test2", SERIALIZER::decode, message -> {
        events.add(2);
        return message;
    }, SERIALIZER::encode, MoreExecutors.directExecutor()).join();
    assertEquals("Hello world!", eventService3.send("test2", "Hello world!").join());
    assertEquals(1, events.size());
    assertTrue(events.contains(1));
    events.clear();
    assertEquals("Hello world!", eventService3.send("test2", "Hello world!").join());
    assertEquals(1, events.size());
    assertTrue(events.contains(2));
    events.clear();
    assertEquals("Hello world!", eventService3.send("test2", "Hello world!").join());
    assertEquals(1, events.size());
    assertTrue(events.contains(1));
}
Also used : ClusterMetadata(io.atomix.cluster.ClusterMetadata) Node(io.atomix.cluster.Node) MoreExecutors(com.google.common.util.concurrent.MoreExecutors) ClusterMetadata(io.atomix.cluster.ClusterMetadata) ClusterEventingService(io.atomix.cluster.messaging.ClusterEventingService) Set(java.util.Set) Assert.assertTrue(org.junit.Assert.assertTrue) Endpoint(io.atomix.messaging.Endpoint) Test(org.junit.Test) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) UnknownHostException(java.net.UnknownHostException) ArrayList(java.util.ArrayList) InetAddress(java.net.InetAddress) DefaultClusterService(io.atomix.cluster.impl.DefaultClusterService) List(java.util.List) MessagingService(io.atomix.messaging.MessagingService) KryoNamespaces(io.atomix.utils.serializer.KryoNamespaces) ClusterService(io.atomix.cluster.ClusterService) Serializer(io.atomix.utils.serializer.Serializer) TestClusterMetadataService(io.atomix.cluster.impl.TestClusterMetadataService) Assert.assertEquals(org.junit.Assert.assertEquals) Node(io.atomix.cluster.Node) CopyOnWriteArraySet(java.util.concurrent.CopyOnWriteArraySet) ClusterEventingService(io.atomix.cluster.messaging.ClusterEventingService) MessagingService(io.atomix.messaging.MessagingService) TestClusterMetadataService(io.atomix.cluster.impl.TestClusterMetadataService) DefaultClusterService(io.atomix.cluster.impl.DefaultClusterService) ClusterService(io.atomix.cluster.ClusterService) DefaultClusterService(io.atomix.cluster.impl.DefaultClusterService) Test(org.junit.Test)

Example 12 with Endpoint

use of io.atomix.messaging.Endpoint in project atomix by atomix.

the class DefaultClusterMetadataService method bootstrap.

/**
 * Bootstraps the cluster metadata.
 */
private CompletableFuture<Void> bootstrap() {
    Set<Endpoint> peers = nodes.values().stream().map(Node::endpoint).filter(endpoint -> !endpoint.equals(messagingService.endpoint())).collect(Collectors.toSet());
    final int totalPeers = peers.size();
    if (totalPeers == 0) {
        return CompletableFuture.completedFuture(null);
    }
    AtomicBoolean successful = new AtomicBoolean();
    AtomicInteger totalCount = new AtomicInteger();
    AtomicReference<Throwable> lastError = new AtomicReference<>();
    // Iterate through all of the peers and send a bootstrap request. On the first peer that returns
    // a successful bootstrap response, complete the future. Otherwise, if no peers respond with any
    // successful bootstrap response, the future will be completed with the last exception.
    CompletableFuture<Void> future = new CompletableFuture<>();
    peers.forEach(peer -> {
        bootstrap(peer).whenComplete((result, error) -> {
            if (error == null) {
                if (successful.compareAndSet(false, true)) {
                    future.complete(null);
                } else if (totalCount.incrementAndGet() == totalPeers) {
                    Throwable e = lastError.get();
                    if (e != null) {
                        future.completeExceptionally(e);
                    }
                }
            } else {
                if (!successful.get() && totalCount.incrementAndGet() == totalPeers) {
                    future.completeExceptionally(error);
                } else {
                    lastError.set(error);
                }
            }
        });
    });
    return future;
}
Also used : ClusterMetadataEventListener(io.atomix.cluster.ClusterMetadataEventListener) ManagedClusterMetadataService(io.atomix.cluster.ManagedClusterMetadataService) Output(com.esotericsoftware.kryo.io.Output) Node(io.atomix.cluster.Node) NodeId(io.atomix.cluster.NodeId) ScheduledFuture(java.util.concurrent.ScheduledFuture) AbstractListenerManager(io.atomix.utils.event.AbstractListenerManager) LoggerFactory(org.slf4j.LoggerFactory) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) AtomicReference(java.util.concurrent.atomic.AtomicReference) Kryo(com.esotericsoftware.kryo.Kryo) ClusterMetadataEvent(io.atomix.cluster.ClusterMetadataEvent) Threads.namedThreads(io.atomix.utils.concurrent.Threads.namedThreads) ImmutableList(com.google.common.collect.ImmutableList) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) Input(com.esotericsoftware.kryo.io.Input) KryoNamespace(io.atomix.utils.serializer.KryoNamespace) ExecutorService(java.util.concurrent.ExecutorService) LogicalClock(io.atomix.utils.time.LogicalClock) ClusterMetadata(io.atomix.cluster.ClusterMetadata) Logger(org.slf4j.Logger) Set(java.util.Set) Endpoint(io.atomix.messaging.Endpoint) ClusterMetadataService(io.atomix.cluster.ClusterMetadataService) Maps(com.google.common.collect.Maps) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) MessagingService(io.atomix.messaging.MessagingService) KryoNamespaces(io.atomix.utils.serializer.KryoNamespaces) LogicalTimestamp(io.atomix.utils.time.LogicalTimestamp) Optional(java.util.Optional) Serializer(io.atomix.utils.serializer.Serializer) Collections(java.util.Collections) Node(io.atomix.cluster.Node) AtomicReference(java.util.concurrent.atomic.AtomicReference) Endpoint(io.atomix.messaging.Endpoint) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Endpoint(io.atomix.messaging.Endpoint) AtomicInteger(java.util.concurrent.atomic.AtomicInteger)

Example 13 with Endpoint

use of io.atomix.messaging.Endpoint in project atomix by atomix.

the class AtomixAgent method parseEndpoint.

static Endpoint parseEndpoint(String[] address) {
    String host;
    int port;
    if (address.length == 3) {
        host = address[1];
        port = Integer.parseInt(address[2]);
    } else if (address.length == 2) {
        try {
            host = address[0];
            port = Integer.parseInt(address[1]);
        } catch (NumberFormatException e) {
            host = address[1];
            port = NettyMessagingService.DEFAULT_PORT;
        }
    } else {
        try {
            InetAddress.getByName(address[0]);
            host = address[0];
        } catch (UnknownHostException e) {
            host = "0.0.0.0";
        }
        port = NettyMessagingService.DEFAULT_PORT;
    }
    try {
        return new Endpoint(InetAddress.getByName(host), port);
    } catch (UnknownHostException e) {
        throw new IllegalArgumentException("Failed to resolve host", e);
    }
}
Also used : UnknownHostException(java.net.UnknownHostException) Endpoint(io.atomix.messaging.Endpoint) Endpoint(io.atomix.messaging.Endpoint)

Example 14 with Endpoint

use of io.atomix.messaging.Endpoint in project atomix by atomix.

the class AtomixAgent method main.

public static void main(String[] args) throws Exception {
    ArgumentType<Node> nodeArgumentType = (ArgumentParser argumentParser, Argument argument, String value) -> {
        String[] address = parseAddress(value);
        return Node.builder(parseNodeId(address)).withType(Node.Type.CORE).withEndpoint(parseEndpoint(address)).build();
    };
    ArgumentType<Node.Type> typeArgumentType = (ArgumentParser argumentParser, Argument argument, String value) -> Node.Type.valueOf(value.toUpperCase());
    ArgumentType<File> fileArgumentType = (ArgumentParser argumentParser, Argument argument, String value) -> new File(value);
    ArgumentParser parser = ArgumentParsers.newArgumentParser("AtomixServer").defaultHelp(true).description("Atomix server");
    parser.addArgument("node").type(nodeArgumentType).nargs("?").metavar("NAME:HOST:PORT").setDefault(Node.builder("local").withType(Node.Type.CORE).withEndpoint(new Endpoint(InetAddress.getByName("127.0.0.1"), NettyMessagingService.DEFAULT_PORT)).build()).help("The local node info");
    parser.addArgument("--type", "-t").type(typeArgumentType).metavar("TYPE").choices("core", "data", "client").setDefault(Node.Type.CORE).help("Indicates the local node type");
    parser.addArgument("--bootstrap", "-b").nargs("*").type(nodeArgumentType).metavar("NAME:HOST:PORT").required(false).help("Bootstraps a new cluster");
    parser.addArgument("--http-port", "-p").type(Integer.class).metavar("PORT").required(false).setDefault(5678).help("An optional HTTP server port");
    parser.addArgument("--data-dir", "-dd").type(fileArgumentType).metavar("FILE").required(false).setDefault(new File(System.getProperty("user.dir"), "data")).help("The server data directory");
    parser.addArgument("--core-partitions", "-cp").type(Integer.class).metavar("NUM").required(false).setDefault(7).help("The number of core partitions");
    parser.addArgument("--data-partitions", "-dp").type(Integer.class).metavar("NUM").required(false).setDefault(71).help("The number of data partitions");
    Namespace namespace = null;
    try {
        namespace = parser.parseArgs(args);
    } catch (ArgumentParserException e) {
        parser.handleError(e);
        System.exit(1);
    }
    Node localNode = namespace.get("node");
    Node.Type type = namespace.get("type");
    localNode = Node.builder(localNode.id()).withType(type).withEndpoint(localNode.endpoint()).build();
    List<Node> bootstrap = namespace.getList("bootstrap");
    if (bootstrap == null) {
        bootstrap = Collections.singletonList(localNode);
    }
    File dataDir = namespace.get("data_dir");
    Integer httpPort = namespace.getInt("http_port");
    Integer corePartitions = namespace.getInt("core_partitions");
    Integer dataPartitions = namespace.getInt("data_partitions");
    LOGGER.info("node: {}", localNode);
    LOGGER.info("bootstrap: {}", bootstrap);
    LOGGER.info("data-dir: {}", dataDir);
    Atomix atomix = Atomix.builder().withLocalNode(localNode).withBootstrapNodes(bootstrap).withDataDirectory(dataDir).withCorePartitions(corePartitions).withDataPartitions(dataPartitions).build();
    Runtime.getRuntime().addShutdownHook(new Thread(() -> {
        atomix.stop().join();
    }));
    atomix.start().join();
    LOGGER.info("Atomix listening at {}:{}", localNode.endpoint().host().getHostAddress(), localNode.endpoint().port());
    ManagedRestService rest = RestService.builder().withAtomix(atomix).withEndpoint(Endpoint.from(localNode.endpoint().host().getHostAddress(), httpPort)).build();
    rest.start().join();
    LOGGER.info("HTTP server listening at {}:{}", localNode.endpoint().host().getHostAddress(), httpPort);
    synchronized (Atomix.class) {
        while (atomix.isRunning()) {
            Atomix.class.wait();
        }
    }
}
Also used : Atomix(io.atomix.core.Atomix) Argument(net.sourceforge.argparse4j.inf.Argument) Node(io.atomix.cluster.Node) ArgumentParser(net.sourceforge.argparse4j.inf.ArgumentParser) Namespace(net.sourceforge.argparse4j.inf.Namespace) ArgumentType(net.sourceforge.argparse4j.inf.ArgumentType) Endpoint(io.atomix.messaging.Endpoint) ArgumentParserException(net.sourceforge.argparse4j.inf.ArgumentParserException) ManagedRestService(io.atomix.rest.ManagedRestService) File(java.io.File)

Aggregations

Endpoint (io.atomix.messaging.Endpoint)14 MessagingService (io.atomix.messaging.MessagingService)6 CompletableFuture (java.util.concurrent.CompletableFuture)6 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)5 Node (io.atomix.cluster.Node)4 ManagedMessagingService (io.atomix.messaging.ManagedMessagingService)4 BiFunction (java.util.function.BiFunction)4 MoreExecutors (com.google.common.util.concurrent.MoreExecutors)3 InetAddress (java.net.InetAddress)3 UnknownHostException (java.net.UnknownHostException)3 Map (java.util.Map)3 ExecutorService (java.util.concurrent.ExecutorService)3 Executors (java.util.concurrent.Executors)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 Assert.assertEquals (org.junit.Assert.assertEquals)3 Assert.assertTrue (org.junit.Assert.assertTrue)3 Before (org.junit.Before)3 Test (org.junit.Test)3 Uninterruptibles (com.google.common.util.concurrent.Uninterruptibles)2 ClusterMetadata (io.atomix.cluster.ClusterMetadata)2