package org.xbib.elasticsearch.action.deploy;
import org.elasticsearch.ElasticSearchException;
import org.elasticsearch.action.support.nodes.TransportNodesOperationAction;
import org.elasticsearch.cluster.ClusterName;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.env.Environment;
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportService;
import org.xbib.elasticsearch.plugin.gatherer.GathererPlugin;
import org.xbib.io.StreamUtil;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicReferenceArray;
public class TransportDeployAction extends TransportNodesOperationAction<DeployRequest, DeployResponse, DeployNodeRequest, DeployNodeResponse> {
private final Environment environment;
private final DeployService deployService;
@Inject
public TransportDeployAction(Settings settings, ClusterName clusterName, ThreadPool threadPool,
ClusterService clusterService, TransportService transportService,
Environment environment, DeployService deployService) {
super(settings, clusterName, threadPool, clusterService, transportService);
this.environment = environment;
this.deployService = deployService;
}
@Override
protected String transportAction() {
return DeployAction.NAME;
}
@Override
protected String executor() {
return ThreadPool.Names.MANAGEMENT;
}
@Override
protected DeployRequest newRequest() {
return new DeployRequest();
}
@Override
protected DeployResponse newResponse(DeployRequest request, AtomicReferenceArray nodesResponses) {
return new DeployResponse();
}
@Override
protected DeployNodeRequest newNodeRequest() {
return new DeployNodeRequest();
}
@Override
protected DeployNodeRequest newNodeRequest(String nodeId, DeployRequest request) {
return new DeployNodeRequest(nodeId, request);
}
@Override
protected DeployNodeResponse newNodeResponse() {
return new DeployNodeResponse();
}
@Override
protected DeployNodeResponse nodeOperation(DeployNodeRequest request) throws ElasticSearchException {
String name = request.getRequest().getName();
if (name == null) {
throw new ElasticSearchException("no name given");
}
String path = request.getRequest().getPath();
if (path == null) {
throw new ElasticSearchException("no path given");
}
BytesReference ref = request.getRequest().getBytes();
if (ref == null || ref.length() == 0) {
throw new ElasticSearchException("no bytes in request");
}
// place all deployments under gatherer to avoid overwriting of other plugins
File dir = new File(environment.pluginsFile(), GathererPlugin.NAME + "/" + name);
if (dir.exists()) {
throw new ElasticSearchException("refusing cowardly to overwrite existing path: " + dir.getAbsolutePath());
}
try {
dir.mkdirs();
File f = new File(path); // just to get file name
File target = new File(dir, f.getName());
logger.info("deploying to {}", target.getAbsolutePath());
FileOutputStream out = new FileOutputStream(target);
InputStream in = new ByteArrayInputStream(ref.array());
StreamUtil.copy(in, out);
in.close();
out.close();
// deploy service knows how to unpack archive and add jars to class path
deployService.add(name, target.getAbsolutePath());
// TODO set success result in DeployNodeResponse
} catch (IOException e) {
throw new ElasticSearchException(e.getMessage());
}
DeployNodeResponse response = new DeployNodeResponse();
return response;
}
@Override
protected boolean accumulateExceptions() {
return true;
}
}