blob: 0c272f306e84ec0d48c6c1f5f254750835447f98 [file] [log] [blame]
/**
*
*/
package org.eclipse.smila.solr.admin;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.xml.stream.XMLStreamException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.solr.client.solrj.SolrServerException;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.smila.datamodel.Any;
import org.eclipse.smila.datamodel.Record;
import org.eclipse.smila.datamodel.impl.DefaultDataFactoryImpl;
import org.eclipse.smila.datamodel.util.AnyUtil;
import org.eclipse.smila.datamodel.xml.XmlSerializationUtils;
import org.eclipse.smila.http.server.HttpExchange;
import org.eclipse.smila.http.server.util.ARequestHandler;
import org.eclipse.smila.http.server.util.UnsupportedMethodException;
import org.eclipse.smila.processing.parameters.MissingParameterException;
import org.eclipse.smila.solr.Activator;
/**
* @author pwissel
*
*/
public class SolrAdministrationHandler extends ARequestHandler {
/**
* @see org.eclipse.smila.http.server.HttpHandler#handle(org.eclipse.smila.http.server.HttpExchange)
*/
@Override
public void handle(HttpExchange exchange) throws IOException {
try {
final String method = exchange.getRequestMethod();
Any result = null;
if (StringUtils.equalsIgnoreCase("GET", method)) {
result = doGet(exchange);
} else if (StringUtils.equalsIgnoreCase("POST", method)) {
result = doPost(exchange);
} else {
final String msg =
String.format("HttpMethod must be GET . HttpMethod '%s' is unsupported by SolrAdministrationHandler",
method);
throw new UnsupportedMethodException(msg);
}
sendResponse(exchange, result);
} catch (Exception exception) {
sendError(exchange, exception);
}
}
private Any doGet(HttpExchange exchange) throws Exception {
final GetCommand command = getGetCommand(exchange.getRequestURI());
final SolrAdministration administration = getSolrAdministration();
final Map<String, String[]> parameter = exchange.getParameterMap();
Any response = null;
switch (command) {
case CORENAMES:
final List<String> coreNames = administration.getCoreNames();
response = AnyUtil.objectToAny(coreNames);
break;
case FIELDNAMES:
final String core = getParameter(SolrAdministration.CORE, parameter);
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
final List<String> fieldNames = administration.getFieldNames(core);
response = AnyUtil.objectToAny(fieldNames);
break;
default:
throw new NotImplementedException("Command: " + command);
}
return response;
}
private Any doPost(HttpExchange exchange) throws MissingParameterException, SolrAdministrationException,
SolrServerException, IOException {
final PostCommand command = getPostCommand(exchange.getRequestURI());
final SolrAdministration administration = getSolrAdministration();
final Map<String, String[]> parameter = exchange.getParameterMap();
final String core = getParameter(SolrAdministration.CORE, parameter);
final String other = getParameter(SolrAdministration.OTHER, parameter);
Any response = null;
switch (command) {
case STATUS:
if (core != null) {
response = administration.status(core);
break;
}
response = administration.status();
break;
case CREATE:
final String name = getParameter(SolrAdministration.NAME, parameter);
assertRequiredParameterNotNull(name, SolrAdministration.NAME);
final String instanceDir = getParameter(SolrAdministration.INSTANCE_DIR, parameter);
assertRequiredParameterNotNull(instanceDir, SolrAdministration.INSTANCE_DIR);
response = administration.create(name, instanceDir, parameter);
break;
case RELOAD:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
response = administration.reload(core);
break;
case RENAME:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
assertRequiredParameterNotNull(other, SolrAdministration.OTHER);
response = administration.rename(core, other);
break;
case SWAP:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
assertRequiredParameterNotNull(other, SolrAdministration.OTHER);
response = administration.swap(core, other);
break;
case UNLOAD:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
final String deleteIndexString = getParameter(SolrAdministration.DELETE_INDEX, parameter);
final boolean deleteIndex = BooleanUtils.toBoolean(deleteIndexString);
response = administration.unload(core, deleteIndex);
break;
case LOAD:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
response = administration.load(core);
break;
case MERGE:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
final String[] sourceCore = parameter.get(SolrAdministration.SRC_CORE);
assertRequiredParametersNotNull(sourceCore, SolrAdministration.SRC_CORE);
response = administration.mergeIndexes(core, sourceCore);
break;
case CLEARCORECACHE:
if (core != null) {
administration.clearCoreCache(core);
break;
}
administration.clearCoreCaches();
break;
case OPTIMIZE:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
response = administration.optimize(core);
break;
case PING:
assertRequiredParameterNotNull(core, SolrAdministration.CORE);
response = administration.ping(core);
break;
default:
throw new NotImplementedException("Command: " + command);
}
return response;
}
private GetCommand getGetCommand(String requestUri) throws MalformedURLException {
final List<String> dynamicUriParts = getDynamicUriParts(requestUri);
final String command = CollectionUtils.isEmpty(dynamicUriParts) ? null : dynamicUriParts.get(0);
if (StringUtils.isBlank(command)) {
throw new MalformedURLException("RequestUri must contain command.");
}
try {
return GetCommand.valueOf(command.toUpperCase());
} catch (Exception exception) {
final String allowed = StringUtils.join(GetCommand.values(), " ");
final String msg =
MessageFormat.format("Invalid get command: {0}. Valid commands are: {1}", command, allowed);
throw new IllegalArgumentException(msg, exception);
}
}
private PostCommand getPostCommand(final String requestUri) throws MalformedURLException {
final List<String> dynamicUriParts = getDynamicUriParts(requestUri);
final String command = CollectionUtils.isEmpty(dynamicUriParts) ? null : dynamicUriParts.get(0);
if (StringUtils.isBlank(command)) {
throw new MalformedURLException("RequestUri must contain command.");
}
try {
return PostCommand.valueOf(command.toUpperCase());
} catch (Exception exception) {
final String allowed = StringUtils.join(PostCommand.values(), " ");
final String msg =
MessageFormat.format("Invalid post command: {0}. Valid commands are: {1}.", command, allowed);
throw new IllegalArgumentException(msg, exception);
}
}
private void assertRequiredParameterNotNull(String parameter, String name) throws MissingParameterException {
if (parameter == null) {
final String msg = MessageFormat.format("Required paramter {0} must not be null", name);
throw new MissingParameterException(msg);
}
}
private void assertRequiredParametersNotNull(String[] parameters, String name) throws MissingParameterException {
if (ArrayUtils.isEmpty(parameters)) {
final String msg = MessageFormat.format("Required paramter array {0} must not be null", name);
throw new MissingParameterException(msg);
}
}
private String getParameter(String name, Map<String, String[]> parameter) {
final String[] values = parameter.get(name);
if (ArrayUtils.isEmpty(values)) {
return null;
}
return values[0];
}
private void sendResponse(HttpExchange exchange, Any result) throws IOException {
final OutputStream responseStream = exchange.getResponseStream();
final Record record = new DefaultDataFactoryImpl().createRecord();
record.getMetadata().put("administration", result);
final String xml = XmlSerializationUtils.serialize2string(record);
responseStream.write(xml.getBytes("UTF-8"));
// Didn't work for whatever reason.
// XmlSerializationUtils.serialize2stream(record, responseStream);
exchange.setResponseHeader("Content-Type", MimeTypes.TEXT_XML_UTF_8);
exchange.setResponseStatus(HttpServletResponse.SC_OK);
responseStream.flush();
}
/**
* Send an error response.
*
* @param exchange
* the {@link HttpExchange}.
* @param exception
* the {@link Throwable} to send.
* @throws IOException
* if {@link HttpExchange#getResponseStream()} or {@link OutputStream#write(byte[])} or
* {@link OutputStream#flush()} throws {@link IOException}.
* @throws XMLStreamException
*/
private void sendError(HttpExchange exchange, Throwable exception) throws IOException {
final String fullStackTrace = ExceptionUtils.getFullStackTrace(exception);
final OutputStream errorStream = exchange.getResponseStream();
errorStream.write(fullStackTrace.getBytes());
exchange.setResponseHeader("Content-Type", "text");
if (exception instanceof UnsupportedMethodException || exception instanceof MissingParameterException) {
exchange.setResponseStatus(HttpServletResponse.SC_BAD_REQUEST);
} else {
exchange.setResponseStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
errorStream.flush();
}
enum PostCommand {
STATUS, CREATE, RELOAD, RENAME, SWAP, UNLOAD, LOAD, MERGE, OPTIMIZE, PING, CLEARCORECACHE;
}
enum GetCommand {
CORENAMES, FIELDNAMES;
}
private SolrAdministration getSolrAdministration() {
return Activator.getInstance().getSolrManager().getSolrAdministration();
}
}