From 00ce3c9972c692b380e958c095767252d7eb0ec3 Mon Sep 17 00:00:00 2001 From: Stephane Gamard Date: Wed, 9 Jul 2014 16:13:13 +0200 Subject: [PATCH] SONAR-5410 - created ES engine in sonar-search --- .../java/org/sonar/search/ElasticSearch.java | 134 ++++++++++++++++++ .../sonar/search/ElasticSearchMainTest.java | 68 +++++++++ 2 files changed, 202 insertions(+) create mode 100644 sonar-search/src/main/java/org/sonar/search/ElasticSearch.java create mode 100644 sonar-search/src/test/java/org/sonar/search/ElasticSearchMainTest.java diff --git a/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java b/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java new file mode 100644 index 00000000000..5ca543ffcce --- /dev/null +++ b/sonar-search/src/main/java/org/sonar/search/ElasticSearch.java @@ -0,0 +1,134 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.search; + +import org.apache.commons.io.FileUtils; +import org.elasticsearch.common.logging.ESLoggerFactory; +import org.elasticsearch.common.logging.slf4j.Slf4jESLoggerFactory; +import org.elasticsearch.common.settings.ImmutableSettings; +import org.elasticsearch.node.Node; +import org.elasticsearch.node.NodeBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.search.script.ListUpdate; + +import java.io.File; + +public class ElasticSearch extends org.sonar.process.Process { + + private static final Logger LOGGER = LoggerFactory.getLogger(ElasticSearch.class); + + static final String MISSING_ARGUMENTS = "2 arguments are required for org.sonar.search.Application"; + static final String MISSING_NAME_ARGUMENT = "Missing Name argument"; + static final String MISSING_PORT_ARGUMENT = "Missing Port argument"; + static final String COULD_NOT_PARSE_ARGUMENT_INTO_A_NUMBER = "Could not parse argument into a number"; + + private final Node node; + + public ElasticSearch(String name, int port) { + super(name, port); + + ESLoggerFactory.setDefaultFactory(new Slf4jESLoggerFactory()); + + ImmutableSettings.Builder esSettings = ImmutableSettings.settingsBuilder() + .put("index.merge.policy.max_merge_at_once", "200") + .put("index.merge.policy.segments_per_tier", "200") + .put("index.number_of_shards", "1") + .put("index.number_of_replicas", "0") + .put("index.store.type", "mmapfs") +// + .put("indices.store.throttle.type", "merge") + .put("indices.store.throttle.max_bytes_per_sec", "200mb") +// + .put("script.default_lang", "native") + .put("script.native." + ListUpdate.NAME + ".type", ListUpdate.UpdateListScriptFactory.class.getName()) +// + .put("cluster.name", "sonarqube") +// + .put("node.name", "sonarqube-" + System.currentTimeMillis()) + .put("node.data", true) + .put("node.local", false) +// +// .put("network.bind_host", "127.0.0.1") +// .put("http.enabled", true) +// .put("http.host", "127.0.0.1") + + .put("transport.tcp.port", 9300) + .put("http.port", 9200); + + File esDir = FileUtils.getTempDirectory(); + try { + FileUtils.forceMkdir(esDir); + esSettings.put("path.home", esDir.getAbsolutePath()); + } catch (Exception e) { + throw new IllegalStateException("Fail to create directory " + esDir.getAbsolutePath(), e); + } + + node = NodeBuilder.nodeBuilder() + .settings(esSettings) + .build().start(); + } + + + @Override + public void execute() { + while (node != null && !node.isClosed()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + System.out.println("-- ES is done."); + } + + public void shutdown() { + this.node.close(); + } + + private static final String getName(String... args) { + if (args[0].isEmpty()) { + throw new IllegalStateException(MISSING_NAME_ARGUMENT); + } + return args[0]; + } + + private static final Integer getPort(String... args) { + if (args[1].isEmpty()) { + throw new IllegalStateException(MISSING_PORT_ARGUMENT); + } + try { + return Integer.valueOf(args[1]); + } catch (Exception e) { + throw new IllegalStateException(COULD_NOT_PARSE_ARGUMENT_INTO_A_NUMBER); + } + } + + public static void main(String... args) { + if (args.length != 2) { + throw new IllegalStateException(MISSING_ARGUMENTS); + } + String name = ElasticSearch.getName(args); + Integer port = ElasticSearch.getPort(args); + LOGGER.info("Launching '{}' with heartbeat on port '{}'", name, port); + ElasticSearch elasticSearch = new ElasticSearch(name, port); + elasticSearch.execute(); + } +} \ No newline at end of file diff --git a/sonar-search/src/test/java/org/sonar/search/ElasticSearchMainTest.java b/sonar-search/src/test/java/org/sonar/search/ElasticSearchMainTest.java new file mode 100644 index 00000000000..a60eb7ba4a0 --- /dev/null +++ b/sonar-search/src/test/java/org/sonar/search/ElasticSearchMainTest.java @@ -0,0 +1,68 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * SonarQube is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.search; + +import org.junit.Test; + +import static org.fest.assertions.Assertions.assertThat; +import static org.junit.Assert.fail; + +public class ElasticSearchMainTest { + + @Test + public void fail_missing_arguments() { + try { + ElasticSearch.main(new String[]{""}); + fail(); + } catch (Exception e) { + assertThat(e.getMessage()).isEqualTo(ElasticSearch.MISSING_ARGUMENTS); + } + } + + @Test + public void fail_missing_name_arguments() { + try { + ElasticSearch.main(new String[]{"", ""}); + fail(); + } catch (Exception e) { + assertThat(e.getMessage()).isEqualTo(ElasticSearch.MISSING_NAME_ARGUMENT); + } + } + + @Test + public void fail_missing_port_arguments() { + try { + ElasticSearch.main(new String[]{"hello", ""}); + fail(); + } catch (Exception e) { + assertThat(e.getMessage()).isEqualTo(ElasticSearch.MISSING_PORT_ARGUMENT); + } + } + + @Test + public void fail_bad_port_arguments() { + try { + ElasticSearch.main(new String[]{"hello", "x0x0x0x0"}); + fail(); + } catch (Exception e) { + assertThat(e.getMessage()).isEqualTo(ElasticSearch.COULD_NOT_PARSE_ARGUMENT_INTO_A_NUMBER); + } + } +} \ No newline at end of file -- 2.39.5