/**
* Copyright 2013-2014 David Rusek <dave dot rusek at gmail dot com>
*
* 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.
*/
package org.robotninjas.barge.jaxrs;
import com.google.common.base.Throwables;
import org.robotninjas.barge.ClusterConfig;
import org.robotninjas.barge.NotLeaderException;
import org.robotninjas.barge.api.AppendEntries;
import org.robotninjas.barge.api.AppendEntriesResponse;
import org.robotninjas.barge.api.RequestVote;
import org.robotninjas.barge.api.RequestVoteResponse;
import org.robotninjas.barge.state.Raft;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* Exposes a Raft instance as a REST endpoint.
* <p>
* This is the server part of a Barge REST instance, exposing RPCs as endpoints. All messages are serialized through
* JSON.
* </p>
*/
@Path("/")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
@SuppressWarnings("UnusedDeclaration")
public class BargeResource {
private final Raft raft;
private final ClusterConfig clusterConfig;
@Inject
public BargeResource(Raft raft, ClusterConfig clusterConfig) {
this.raft = raft;
this.clusterConfig = clusterConfig;
}
@Path("/init")
@POST
public Raft.StateType init() {
try {
return raft.init().get();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
@Path("/config")
@GET
public ClusterConfig config(){
return clusterConfig;
}
@Path("/state")
@GET
public Raft.StateType state() {
return raft.type();
}
@Path("/vote")
@POST
public RequestVoteResponse requestVote(RequestVote vote) {
return raft.requestVote(vote);
}
@Path("/entries")
@POST
public AppendEntriesResponse appendEntries(AppendEntries appendEntries) {
return raft.appendEntries(appendEntries);
}
@Path("/commit")
@POST
@Consumes(MediaType.APPLICATION_OCTET_STREAM)
public Response commit(byte[] operation) {
try {
raft.commitOperation(operation).get();
return Response.noContent().build();
} catch (NotLeaderException e) {
return Response.status(Response.Status.FOUND).location(((HttpReplica) e.getLeader()).getUri()).build();
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
}