/*
* Copyright MapR Technologies, $year
*
* 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 com.mapr.franz.server;
import java.io.PrintWriter;
import java.io.StringWriter;
import com.google.protobuf.ByteString;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
import com.mapr.franz.catcher.Client;
import com.mapr.franz.catcher.wire.Catcher;
/**
* The kinda broken server.
*/
public class CatcherServiceImpl implements
Catcher.CatcherService.BlockingInterface {
// private Properties props;
// private final String BASE_DIRECTORY = "/tmp/mapr-storm";
// TODO: replace with TopicObserver
private final GhettoTopicLogger logger;
private final long serverId;
private ClusterState state;
// TODO implement some sort of statistics that records (a) number of
// clients, (b) transactions per topic, (c) bytes per topic
public CatcherServiceImpl(long serverId, ClusterState state) {
this.serverId = serverId;
this.state = state;
// this.props = Server.loadProperties();
// String basePath = props.getProperty("franz.server.base.directory",
// BASE_DIRECTORY);
String basePath = Server.getBasePath();
logger = new GhettoTopicLogger(basePath);
}
@Override
public Catcher.HelloResponse hello(RpcController controller,
Catcher.Hello request) throws ServiceException {
Catcher.HelloResponse.Builder r = Catcher.HelloResponse.newBuilder()
.setServerId(serverId);
for (Client.HostPort address : state.getLocalInfo().getAddresses()) {
Catcher.Host.Builder host = r.addHostBuilder();
host.setHostName(address.getHost());
host.setPort(address.getPort());
host.build();
}
for (Catcher.Server server : state.getCluster()) {
Catcher.Server.Builder c = r.addClusterBuilder();
c.mergeFrom(server);
c.build();
}
return r.build();
}
@Override
public Catcher.LogMessageResponse log(RpcController controller,
Catcher.LogMessage request) throws ServiceException {
String topic = request.getTopic();
ByteString payload = request.getPayload();
Catcher.LogMessageResponse.Builder r = Catcher.LogMessageResponse
.newBuilder().setServerId(serverId).setSuccessful(true);
ClusterState.Target directTo = state.directTo(topic);
if (directTo.getStatus() == ClusterState.Status.LIVE) {
if (directTo.isRedirect()) {
// TODO actually forward request to other server
r.getRedirectBuilder().setTopic(topic)
.setServer(directTo.getServer()).build();
}
} else {
ClusterStateException e = new ClusterStateException(
"Can't handle request ... can't see rest of cluster");
StringWriter s = new StringWriter();
PrintWriter pw = new PrintWriter(s);
e.printStackTrace(pw);
pw.close();
r.setSuccessful(false).setBackTrace(s.toString());
}
logger.write(topic, payload);
return r.build();
}
@Override
public Catcher.CloseResponse close(RpcController controller,
Catcher.Close request) throws ServiceException {
return Catcher.CloseResponse.newBuilder().build();
}
private class ClusterStateException extends Exception {
private static final long serialVersionUID = -1473457816312999824L;
public ClusterStateException(String msg) {
super(msg);
}
}
}