+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.platform.db.migration.es;
-
-public interface ElasticsearchClient {
-
- /**
- * This method is reentrant and does not fail if indexName or otherIndexNames does not exist
- */
- void deleteIndexes(String... otherIndexNames);
-}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.platform.db.migration.es;
+
+public interface MigrationEsClient {
+
+ /**
+ * This method is re-entrant and does not fail if indexName or otherIndexNames do not exist
+ */
+ void deleteIndexes(String name, String... otherNames);
+}
import java.sql.SQLException;
import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.es.MigrationEsClient;
import org.sonar.server.platform.db.migration.sql.RenameColumnsBuilder;
import org.sonar.server.platform.db.migration.step.DdlChange;
public class RenameSubmitterLoginToSubmitterUuidOnTableCeActivity extends DdlChange {
- public RenameSubmitterLoginToSubmitterUuidOnTableCeActivity(Database db) {
+ private final MigrationEsClient esClient;
+
+ public RenameSubmitterLoginToSubmitterUuidOnTableCeActivity(Database db, MigrationEsClient esClient) {
super(db);
+ this.esClient = esClient;
}
@Override
.build())
.build());
- context.deleteIndexes("users");
+ esClient.deleteIndexes("users");
}
}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.platform.db.migration.step;
-
-import java.sql.SQLException;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.sonar.server.platform.db.migration.es.ElasticsearchClient;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-public class ElasticsearchChangeTest {
-
- private ElasticsearchClient client = mock(ElasticsearchClient.class);
-
- @Test
- public void deleteIndice_call() throws SQLException {
- ArgumentCaptor<String> indices = ArgumentCaptor.forClass(String.class);
-
- new ElasticsearchChange(client) {
- @Override
- protected void execute(Context context) throws SQLException {
- context.deleteIndice("a", "b", "c");
- }
- }.execute();
-
- verify(client, times(1)).deleteIndice(indices.capture());
- assertThat(indices.getAllValues()).containsExactly("a", "b", "c");
- }
-}
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.es.MigrationEsClient;
import static java.sql.Types.VARCHAR;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
public class RenameSubmitterLoginToSubmitterUuidOnTableCeActivityTest {
@Rule
public ExpectedException expectedException = ExpectedException.none();
- private RenameSubmitterLoginToSubmitterUuidOnTableCeActivity underTest = new RenameSubmitterLoginToSubmitterUuidOnTableCeActivity(db.database());
+ private MigrationEsClient esClient = mock(MigrationEsClient.class);
+ private RenameSubmitterLoginToSubmitterUuidOnTableCeActivity underTest = new RenameSubmitterLoginToSubmitterUuidOnTableCeActivity(db.database(), esClient);
@Test
public void rename_column() throws SQLException {
db.assertColumnDefinition("ce_activity", "submitter_uuid", VARCHAR, 255, true);
db.assertColumnDoesNotExist("ce_activity", "submitter_login");
+
+ verify(esClient).deleteIndexes("users");
}
public void migration_is_not_reentrant() throws SQLException {
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.es;
+
+import com.google.common.collect.Sets;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.stream.Stream;
+import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
+import org.sonar.server.platform.db.migration.es.MigrationEsClient;
+
+public class MigrationEsClientImpl implements MigrationEsClient {
+ private final EsClient client;
+
+ public MigrationEsClientImpl(EsClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public void deleteIndexes(String name, String... otherNames) {
+ GetMappingsResponse mappings = client.nativeClient().admin().indices().prepareGetMappings("_all").get();
+ Set<String> existingIndices = Sets.newHashSet(mappings.mappings().keysIt());
+ Stream.concat(Stream.of(name), Arrays.stream(otherNames))
+ .distinct()
+ .filter(existingIndices::contains)
+ .forEach(index -> client.nativeClient().admin().indices().prepareDelete(index).get());
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.es;
-
-import java.util.Arrays;
-import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
-import org.elasticsearch.client.Client;
-import org.sonar.server.platform.db.migration.es.ElasticsearchClient;
-
-import static java.util.Objects.requireNonNull;
-
-public class SimpleEsClientImpl implements ElasticsearchClient {
- private final Client nativeClient;
-
- public SimpleEsClientImpl(Client nativeClient) {
- this.nativeClient = requireNonNull(nativeClient);
- }
-
- /**
- * This method is reentrant and does not fail if indexName or otherIndexNames does not exist
- */
- public void deleteIndexes(String... indexNames) {
- if (indexNames.length == 0) {
- return;
- }
-
- GetMappingsResponse getMappingsResponse = nativeClient.admin().indices().prepareGetMappings("_all").get();
- String[] allIndexes = getMappingsResponse.mappings().keys().toArray(String.class);
- String[] intersection = intersection(indexNames, allIndexes);
- nativeClient.admin().indices().prepareDelete(intersection).get();
- }
-
- private String[] intersection(String[] a, String[] b) {
- return Arrays.stream(a)
- .distinct()
- .filter(x -> Arrays.stream(b).anyMatch(y -> y != null && y.equals(x)))
- .toArray(String[]::new);
- }
-}
import org.sonar.core.extension.CoreExtensionRepositoryImpl;
import org.sonar.core.extension.CoreExtensionsLoader;
import org.sonar.server.l18n.ServerI18n;
+import org.sonar.server.es.MigrationEsClientImpl;
import org.sonar.server.platform.DatabaseServerCompatibility;
import org.sonar.server.platform.DefaultServerUpgradeStatus;
import org.sonar.server.platform.StartupMetadataProvider;
MigrationConfigurationModule.class,
DatabaseVersion.class,
DatabaseServerCompatibility.class,
+ MigrationEsClientImpl.class,
new StartupMetadataProvider(),
DefaultServerUpgradeStatus.class,
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.server.es;
+
+import java.util.Iterator;
+import org.elasticsearch.cluster.metadata.IndexMetaData;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.config.internal.MapSettings;
+import org.sonar.server.platform.db.migration.es.MigrationEsClient;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
+
+public class MigrationEsClientImplTest {
+ @Rule
+ public EsTester es = EsTester.createCustom(
+ new SimpleIndexDefinition("a"),
+ new SimpleIndexDefinition("b"),
+ new SimpleIndexDefinition("c"));
+
+ private MigrationEsClient underTest = new MigrationEsClientImpl(es.client());
+
+ @Test
+ public void delete_existing_index() {
+ underTest.deleteIndexes("a");
+
+ assertThat(loadExistingIndices())
+ .doesNotContain("a")
+ .contains("b", "c");
+ }
+
+ @Test
+ public void ignore_indices_that_do_not_exist() {
+ underTest.deleteIndexes("a", "xxx", "c");
+
+ assertThat(loadExistingIndices())
+ .doesNotContain("a", "c")
+ .contains("b");
+ }
+
+ private Iterator<String> loadExistingIndices() {
+ return es.client().nativeClient().admin().indices().prepareGetMappings().get().mappings().keysIt();
+ }
+
+ private static class SimpleIndexDefinition implements IndexDefinition {
+ private final String indexName;
+
+ public SimpleIndexDefinition(String indexName) {
+ this.indexName = indexName;
+ }
+
+ @Override
+ public void define(IndexDefinitionContext context) {
+ NewIndex index = context.create(indexName, newBuilder(new MapSettings().asConfig()).build());
+ index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0);
+ index.getSettings().put("index.refresh_interval", "-1");
+ }
+ }
+}
+++ /dev/null
-/*
- * SonarQube
- * Copyright (C) 2009-2018 SonarSource SA
- * mailto:info AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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.server.es;
-
-import org.elasticsearch.client.Client;
-import org.elasticsearch.cluster.metadata.IndexMetaData;
-import org.junit.Rule;
-import org.junit.Test;
-import org.sonar.api.config.internal.MapSettings;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.sonar.server.es.NewIndex.SettingsConfiguration.newBuilder;
-
-public class SimpleEsClientImplTest {
- @Rule
- public EsTester es = EsTester.createCustom(new FakeIndexDefinition(),
- new SimpleIndexDefinition("a"),
- new SimpleIndexDefinition("b"),
- new SimpleIndexDefinition("c"));
-
- private Client client = es.client().nativeClient();
- private SimpleEsClientImpl underTest = new SimpleEsClientImpl(client);
-
- @Test
- public void call_without_arguments_does_not_generate_an_elasticsearch_call() {
- Client client = mock(Client.class);
- SimpleEsClientImpl underTest = new SimpleEsClientImpl(client);
- underTest.deleteIndexes();
-
- verify(client, never()).admin();
- }
-
- @Test
- public void delete_known_indice_must_delete_the_index() {
- underTest.deleteIndexes("fakes");
-
- assertThat(es.client().nativeClient().admin().indices().prepareGetMappings().get().mappings().get("fakes")).isNull();
- }
-
- @Test
- public void delete_unknown_indice_must_delete_all_existing_indexes() {
- underTest.deleteIndexes("a", "xxx", "c");
-
- assertThat(es.client().nativeClient().admin().indices().prepareGetMappings().get().mappings().get("a")).isNull();
- assertThat(es.client().nativeClient().admin().indices().prepareGetMappings().get().mappings().get("c")).isNull();
- }
-
- public class SimpleIndexDefinition implements IndexDefinition {
- private final String indexName;
-
- public SimpleIndexDefinition(String indexName) {
- this.indexName = indexName;
- }
-
- @Override
- public void define(IndexDefinitionContext context) {
- NewIndex index = context.create(indexName, newBuilder(new MapSettings().asConfig()).build());
- index.getSettings().put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0);
- index.getSettings().put("index.refresh_interval", "-1");
- }
- }
-}