package com.linkedin.databus.bootstrap.server;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* 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.
*
*/
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import org.apache.log4j.Logger;
import com.linkedin.databus.client.pub.ServerInfo;
import com.linkedin.databus.core.Checkpoint;
import com.linkedin.databus.core.DbusConstants;
import com.linkedin.databus2.core.container.request.DatabusRequest;
import com.linkedin.databus2.core.container.request.RequestProcessingException;
import com.linkedin.databus2.core.container.request.RequestProcessor;
public abstract class BootstrapRequestProcessorBase
implements RequestProcessor
{
public static final String MODULE = BootstrapRequestProcessorBase.class.getName();
public static final Logger LOG = Logger.getLogger(MODULE);
public final static String CHECKPOINT_PARAM = "checkPoint";
/**
* We do lazy initializing of bootstrap-server as this class instantiation happens before we decide on
* which port the service will be up
*/
//Flag to indicate if bootstrap server info is initialized.
private boolean _isServerInfoInitialized;
// Bootstrap Server HostPort String
protected String _serverHostPort;
// Bootstrap Server Info for comparison with incoming request
protected ServerInfo _serverInfo;
protected final ExecutorService _executorService;
protected final BootstrapServerStaticConfig _config;
protected final BootstrapHttpServer _bootstrapServer;
public BootstrapRequestProcessorBase(ExecutorService executorService,
BootstrapServerStaticConfig config,
BootstrapHttpServer bootstrapServer)
throws InstantiationException, IllegalAccessException, ClassNotFoundException, SQLException
{
_config = config;
_executorService = executorService;
_bootstrapServer = bootstrapServer;
_isServerInfoInitialized = false;
}
@Override
public final DatabusRequest process(DatabusRequest request) throws IOException,
RequestProcessingException
{
initBootstrapServerInfo();
String ckptStr = request.getParams().getProperty(CHECKPOINT_PARAM);
Checkpoint ckpt = null;
if ( null != ckptStr)
{
ckpt = new Checkpoint(ckptStr);
String bsServerInfo = ckpt.getBootstrapServerInfo();
if ((null != bsServerInfo) && (null != _serverInfo))
{
ServerInfo expServerInfo = null;
try
{
expServerInfo = ServerInfo.buildServerInfoFromHostPort(bsServerInfo.trim(),DbusConstants.HOSTPORT_DELIMITER);
} catch (Exception ex) {
LOG.error("Unable to fetch ServerInfo from ckpt. Passed ServerInfo was :" + bsServerInfo.trim());
}
if ((null != expServerInfo) && (! _serverInfo.equals(expServerInfo)))
{
String msg = "Bootstrap Server Request should be served by different host : " + bsServerInfo + ", This instance is :" + _serverHostPort;
LOG.error(msg);
throw new RequestProcessingException(msg);
}
}
}
DatabusRequest req = doProcess(request);
if ( null != _serverHostPort)
{
req.getResponseContent().setMetadata(DbusConstants.SERVER_INFO_HOSTPORT_HEADER_PARAM, _serverHostPort);
}
return req;
}
protected abstract DatabusRequest doProcess(DatabusRequest request)
throws IOException, RequestProcessingException;
@Override
public ExecutorService getExecutorService()
{
return _executorService;
}
private void initBootstrapServerInfo()
{
if ( !_isServerInfoInitialized )
{
String host = null;
try {
host = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
LOG.error("Unable to fetch the local hostname !! Trying to fetch IP Address !!", e);
try
{
host = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e1) {
LOG.error("Unable to fetch the local IP Address too !! Giving up", e1);
host = null;
}
}
if ( null != host )
{
int port = _bootstrapServer.getHttpPort();
_serverHostPort = host + DbusConstants.HOSTPORT_DELIMITER + port;
ServerInfo serverInfo = null;
try {
serverInfo = ServerInfo.buildServerInfoFromHostPort(_serverHostPort, DbusConstants.HOSTPORT_DELIMITER);
} catch (Exception e) {
LOG.error("Unable to build serverInfo from string (" + _serverHostPort +")", e);
}
_serverInfo = serverInfo;
} else {
_serverHostPort = null;
_serverInfo = null;
LOG.error("Unable to fetch local address !! Clients connecting to this bootstrap server will restart bootstrap on failures !!");
}
_isServerInfoInitialized = true;
}
}
}