/* * Licensed to Crate under one or more contributor license agreements. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership. Crate licenses this file * to you under the Apache License, Version 2.0 (the "License"); you may * not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial * agreement. */ package io.crate.executor.transport; import com.google.common.collect.ImmutableList; import io.crate.analyze.CreateRepositoryAnalyzedStatement; import io.crate.test.integration.CrateDummyClusterServiceUnitTest; import org.elasticsearch.Version; import org.elasticsearch.action.ActionListener; import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.delete.DeleteRepositoryResponse; import org.elasticsearch.action.admin.cluster.repositories.delete.TransportDeleteRepositoryAction; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryResponse; import org.elasticsearch.action.admin.cluster.repositories.put.TransportPutRepositoryAction; import org.elasticsearch.action.support.ActionFilters; import org.elasticsearch.cluster.ClusterName; import org.elasticsearch.cluster.ClusterState; import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver; import org.elasticsearch.cluster.metadata.MetaData; import org.elasticsearch.cluster.metadata.RepositoriesMetaData; import org.elasticsearch.cluster.metadata.RepositoryMetaData; import org.elasticsearch.common.inject.CreationException; import org.elasticsearch.common.inject.spi.Message; import org.elasticsearch.common.settings.Settings; import org.elasticsearch.repositories.RepositoriesService; import org.elasticsearch.repositories.RepositoryException; import org.elasticsearch.tasks.Task; import org.elasticsearch.test.ClusterServiceUtils; import org.elasticsearch.test.transport.MockTransportService; import org.junit.Test; import org.mockito.Answers; import java.util.Collections; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import static org.hamcrest.core.Is.is; import static org.mockito.Mockito.mock; public class RepositoryServiceTest extends CrateDummyClusterServiceUnitTest { @Test public void testConvertException() throws Throwable { expectedException.expect(RepositoryException.class); expectedException.expectMessage("[foo] failed: [foo] missing location"); throw RepositoryService.convertRepositoryException(new RepositoryException("foo", "failed", new CreationException(ImmutableList.of( new Message(Collections.singletonList(10), "creation error", new RepositoryException("foo", "missing location")) )))); } @Test public void testRepositoryIsDroppedOnFailure() throws Throwable { expectedException.expect(RepositoryException.class); // add repo to cluster service so that it exists.. RepositoriesMetaData repos = new RepositoriesMetaData(new RepositoryMetaData("repo1", "fs", Settings.EMPTY)); ClusterState state = ClusterState.builder(new ClusterName("dummy")).metaData( MetaData.builder().putCustom(RepositoriesMetaData.TYPE, repos)).build(); ClusterServiceUtils.setState(clusterService, state); final ActionFilters actionFilters = mock(ActionFilters.class, Answers.RETURNS_MOCKS.get()); IndexNameExpressionResolver indexNameExpressionResolver = new IndexNameExpressionResolver(Settings.EMPTY); final AtomicBoolean deleteRepoCalled = new AtomicBoolean(false); TransportDeleteRepositoryAction deleteRepositoryAction = new TransportDeleteRepositoryAction( Settings.EMPTY, MockTransportService.local(Settings.EMPTY, Version.V_5_0_1, THREAD_POOL), clusterService, mock(RepositoriesService.class), THREAD_POOL, actionFilters, indexNameExpressionResolver) { @Override protected void doExecute(Task task, DeleteRepositoryRequest request, ActionListener<DeleteRepositoryResponse> listener) { deleteRepoCalled.set(true); listener.onResponse(mock(DeleteRepositoryResponse.class)); } }; TransportPutRepositoryAction putRepo = new TransportPutRepositoryAction( Settings.EMPTY, MockTransportService.local(Settings.EMPTY, Version.V_5_0_1, THREAD_POOL), clusterService, mock(RepositoriesService.class), THREAD_POOL, actionFilters, indexNameExpressionResolver) { @Override protected void doExecute(Task task, PutRepositoryRequest request, ActionListener<PutRepositoryResponse> listener) { listener.onFailure(new RepositoryException(request.name(), "failure")); } }; RepositoryService repositoryService = new RepositoryService( clusterService, deleteRepositoryAction, putRepo); try { repositoryService.execute( new CreateRepositoryAnalyzedStatement("repo1", "fs", Settings.EMPTY)).get(10, TimeUnit.SECONDS); } catch (ExecutionException e) { assertThat(deleteRepoCalled.get(), is(true)); throw e.getCause(); } } }