package com.github.alexcojocaru.mojo.elasticsearch.v2.step; import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; import org.apache.commons.lang3.StringUtils; import org.apache.maven.plugin.logging.Log; import com.github.alexcojocaru.mojo.elasticsearch.v2.ClusterConfiguration; import com.github.alexcojocaru.mojo.elasticsearch.v2.ElasticsearchSetupException; import com.github.alexcojocaru.mojo.elasticsearch.v2.client.ElasticsearchClient; import com.github.alexcojocaru.mojo.elasticsearch.v2.client.ElasticsearchClientException; import com.github.alexcojocaru.mojo.elasticsearch.v2.client.ElasticsearchCommand; /** * Bootstrap the ES cluster with the provided initialization script, if provided. * * @author Alex Cojocaru */ public class BootstrapClusterStep implements ClusterStep { @Override public void execute(ClusterConfiguration config) { if (StringUtils.isBlank(config.getPathInitScript())) { // nothing to do; return return; } String filePath = config.getPathInitScript(); validateFile(filePath); // we'll run all commands against the first node in the cluster ElasticsearchClient client = new ElasticsearchClient( config.getLog(), "localhost", config.getInstanceConfigurationList().get(0).getHttpPort()); Stream<String> stream = null; try { stream = Files.lines(Paths.get(filePath)); stream.forEach(command -> executeInitCommand(client, config.getLog(), command)); } catch (IOException e) { throw new ElasticsearchSetupException("Cannot read the init script file", e); } finally { if (stream != null) { stream.close(); } } } /** * Verify that the given file path is a valid reference to an existing file on the disk. * @param filePath */ private void validateFile(String filePath) { if (new File(filePath).isFile() == false) { throw new ElasticsearchSetupException( "The provided init script path is not a valid file path: " + filePath); } } private void executeInitCommand(ElasticsearchClient client, Log log, String command) { log.debug(String.format("Parsing command: %s", command)); ElasticsearchCommand esCommand = parseStringCommand(command); if (esCommand.isSkip()) { return; } String url = "/" + esCommand.getRelativeUrl(); String content = esCommand.getJson(); try { switch (esCommand.getRequestMethod()) { case PUT: client.put(url, content); break; case POST: client.post(url, content, String.class); break; case DELETE: client.delete(url); break; default: throw new IllegalStateException(String.format( "Unsupported request method: %s", esCommand.getRequestMethod())); } } catch (ElasticsearchClientException e) { throw new ElasticsearchSetupException( String.format("Cannot execute command %s", command), e); } } private ElasticsearchCommand parseStringCommand(String command) { ElasticsearchCommand esCommand = new ElasticsearchCommand(); String formattedCommand = command.trim(); // skip empty lines or lines starting with '#' if (formattedCommand.isEmpty() || formattedCommand.charAt(0) == '#') { esCommand.setSkip(true); } else { int firstSeparatorIndex = formattedCommand.indexOf(':'); int secondSeparatorIndex = formattedCommand.indexOf(':', firstSeparatorIndex + 1); if (firstSeparatorIndex == -1 || secondSeparatorIndex == -1) { throw new ElasticsearchSetupException( "Command '" + command + "' in the script file is not properly formatted." + " The format is: REQUEST_METHOD:path:json_script." + " Ex: PUT:indexName/typeName/id:{\"shoe_size\":39, \"shoe_color\":\"orange\"}"); } String methodName = formattedCommand .substring(0, firstSeparatorIndex) .trim(); ElasticsearchCommand.RequestMethod method = ElasticsearchCommand.RequestMethod .fromName(methodName); esCommand.setRequestMethod(method); String relativeUrl = formattedCommand .substring(firstSeparatorIndex + 1, secondSeparatorIndex) .trim(); esCommand.setRelativeUrl(relativeUrl); String json = formattedCommand.substring(secondSeparatorIndex + 1).trim(); esCommand.setJson(json); } return esCommand; } }