Package org.robotninjas.barge.jaxrs

Source Code of org.robotninjas.barge.jaxrs.RaftApplication

package org.robotninjas.barge.jaxrs;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.inject.Guice;
import com.google.inject.Injector;
import org.glassfish.hk2.api.Factory;
import org.glassfish.hk2.utilities.Binder;
import org.glassfish.hk2.utilities.binding.AbstractBinder;
import org.glassfish.jersey.server.ResourceConfig;
import org.robotninjas.barge.ClusterConfig;
import org.robotninjas.barge.StateMachine;
import org.robotninjas.barge.state.Raft;
import org.robotninjas.barge.state.RaftProtocolListener;
import org.robotninjas.barge.state.StateTransitionListener;
import org.robotninjas.barge.utils.Files;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.List;


/**
*/
public class RaftApplication {

  private static final Logger logger = LoggerFactory.getLogger(RaftJdkServer.class);

  private final int serverIndex;
  private final URI[] uris;
  private final File logDir;
 
  private final List<StateTransitionListener> transitionListeners;
  private final List<RaftProtocolListener> protocolListeners;

  private Optional<Injector> injector = Optional.absent();

  public RaftApplication(int serverIndex, URI[] uris, File logDir, Iterable<StateTransitionListener> transitionListener, Iterable<RaftProtocolListener> protocolListener) {
    this.serverIndex = serverIndex;
    this.uris = uris;
    this.logDir = logDir;
    this.transitionListeners = Lists.newArrayList(transitionListener);
    this.protocolListeners = Lists.newArrayList(protocolListener);
  }

  public RaftApplication(int serverIndex, URI[] uris, File logDir) {
    this(serverIndex,uris,logDir, Collections.<StateTransitionListener>emptyList(),Collections.<RaftProtocolListener>emptyList());
  }

  public ResourceConfig makeResourceConfig() {
    ClusterConfig clusterConfig = HttpClusterConfig.from(new HttpReplica(uris[serverIndex]),
      remotes());

    if (!logDir.exists() && !logDir.mkdirs())
      logger.warn("failed to create directories for storing logs, bad things will happen");

    StateMachine stateMachine = new StateMachine() {
      int i = 0;

      @Override
      public Object applyOperation(@Nonnull ByteBuffer entry) {
        return i++;
      }
    };

    final JaxRsRaftModule raftModule = new JaxRsRaftModule(clusterConfig, logDir, stateMachine, 1500, transitionListeners, protocolListeners);

    injector = Optional.of(Guice.createInjector(raftModule));

    ResourceConfig resourceConfig = new ResourceConfig();

    Binder binder = new AbstractBinder() {
      @Override
      protected void configure() {
        bindFactory(new Factory<Raft>() {
              @Override
              public Raft provide() {
                return injector.get().getInstance(Raft.class);
              }

              @Override
              public void dispose(Raft raft) {
              }
            }).to(Raft.class);
       
        bindFactory(new Factory<ClusterConfig>() {
          @Override public ClusterConfig provide() {
            return injector.get().getInstance(ClusterConfig.class);
          }

          @Override public void dispose(ClusterConfig instance) {
          }
        }).to(ClusterConfig.class);
      }
    };

    resourceConfig.register(BargeResource.class);
    resourceConfig.register(Jackson.customJacksonProvider());
    resourceConfig.register(binder);

    return resourceConfig;
  }

  private HttpReplica[] remotes() {
    HttpReplica[] remoteReplicas = new HttpReplica[uris.length - 1];

    for (int i = 0; i < remoteReplicas.length; i++) {
      remoteReplicas[i] = new HttpReplica(uris[(serverIndex + i + 1) % uris.length]);
    }

    return remoteReplicas;
  }

  public void clean() throws IOException {
    Files.delete(logDir);
  }

  public void stop() {
    injector.transform(new Function<Injector, Object>() {
      @Nullable
      @Override
      public Object apply(@Nullable Injector input) {
        Raft instance = null;
        if (input != null) {
          instance = input.getInstance(Raft.class);
          instance.stop();
        }
        return instance;
      }
    });
  }
}
TOP

Related Classes of org.robotninjas.barge.jaxrs.RaftApplication

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.