/* * Copyright © 2014 Cask Data, Inc. * * Licensed 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. */ package co.cask.cdap.client; import co.cask.cdap.api.dataset.table.Table; import co.cask.cdap.client.app.StandaloneDataset; import co.cask.cdap.client.app.StandaloneDatasetModule; import co.cask.cdap.client.common.ClientTestBase; import co.cask.cdap.common.AlreadyExistsException; import co.cask.cdap.common.DatasetModuleNotFoundException; import co.cask.cdap.common.DatasetTypeNotFoundException; import co.cask.cdap.proto.DatasetInstanceConfiguration; import co.cask.cdap.proto.DatasetMeta; import co.cask.cdap.proto.DatasetModuleMeta; import co.cask.cdap.proto.DatasetSpecificationSummary; import co.cask.cdap.proto.DatasetTypeMeta; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.NamespaceMeta; import co.cask.cdap.test.XSlowTests; import com.google.common.collect.ImmutableMap; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.experimental.categories.Category; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.File; import java.util.Collections; import java.util.List; import java.util.concurrent.TimeUnit; import javax.annotation.Nullable; /** * Test for {@link DatasetClient}, {@link DatasetModuleClient}, and {@link DatasetTypeClient}. */ @Category(XSlowTests.class) public class DatasetClientTestRun extends ClientTestBase { private static final Logger LOG = LoggerFactory.getLogger(DatasetClientTestRun.class); private static final Id.Namespace TEST_NAMESPACE = Id.Namespace.from("testNamespace"); private static final Id.Namespace OTHER_NAMESPACE = Id.Namespace.from("otherNamespace"); private DatasetClient datasetClient; private DatasetModuleClient moduleClient; private DatasetTypeClient typeClient; @Before public void setUp() throws Throwable { super.setUp(); datasetClient = new DatasetClient(clientConfig); moduleClient = new DatasetModuleClient(clientConfig); typeClient = new DatasetTypeClient(clientConfig); NamespaceClient namespaceClient = new NamespaceClient(clientConfig); try { namespaceClient.create(new NamespaceMeta.Builder().setName(TEST_NAMESPACE).build()); } catch (AlreadyExistsException e) { // expected } try { namespaceClient.create(new NamespaceMeta.Builder().setName(OTHER_NAMESPACE).build()); } catch (AlreadyExistsException e) { // expected } } @After public void tearDown() throws Exception { NamespaceClient namespaceClient = new NamespaceClient(clientConfig); namespaceClient.delete(TEST_NAMESPACE); namespaceClient.delete(OTHER_NAMESPACE); } @Test public void testAll() throws Exception { Id.DatasetModule module = Id.DatasetModule.from(TEST_NAMESPACE, StandaloneDatasetModule.NAME); Id.DatasetType type = Id.DatasetType.from(TEST_NAMESPACE, StandaloneDataset.class.getName()); Id.DatasetModule moduleInOtherNamespace = Id.DatasetModule.from(OTHER_NAMESPACE, StandaloneDatasetModule.NAME); Id.DatasetType typeInOtherNamespace = Id.DatasetType.from(OTHER_NAMESPACE, StandaloneDataset.class.getName()); int numBaseModules = moduleClient.list(TEST_NAMESPACE).size(); int numBaseTypes = typeClient.list(TEST_NAMESPACE).size(); LOG.info("Adding Dataset module"); File moduleJarFile = createAppJarFile(StandaloneDatasetModule.class); moduleClient.add(Id.DatasetModule.from(TEST_NAMESPACE, StandaloneDatasetModule.NAME), StandaloneDatasetModule.class.getName(), moduleJarFile); moduleClient.waitForExists(module, 30, TimeUnit.SECONDS); Assert.assertEquals(numBaseModules + 1, moduleClient.list(TEST_NAMESPACE).size()); Assert.assertEquals(numBaseTypes + 2, typeClient.list(TEST_NAMESPACE).size()); LOG.info("Checking that the new Dataset module exists"); DatasetModuleMeta datasetModuleMeta = moduleClient.get(module); Assert.assertNotNull(datasetModuleMeta); Assert.assertEquals(StandaloneDatasetModule.NAME, datasetModuleMeta.getName()); LOG.info("Checking that the new Dataset module does not exist in a different namespace"); try { moduleClient.get(moduleInOtherNamespace); Assert.fail("datasetModule found in namespace other than one in which it was expected"); } catch (DatasetModuleNotFoundException expected) { // expected } LOG.info("Checking that the new Dataset type exists"); typeClient.waitForExists(type, 5, TimeUnit.SECONDS); DatasetTypeMeta datasetTypeMeta = typeClient.get(type); Assert.assertNotNull(datasetTypeMeta); Assert.assertEquals(type.getId(), datasetTypeMeta.getName()); datasetTypeMeta = typeClient.get(type); Assert.assertNotNull(datasetTypeMeta); Assert.assertEquals(StandaloneDataset.class.getName(), datasetTypeMeta.getName()); LOG.info("Checking that the new Dataset type does not exist in a different namespace"); try { typeClient.get(typeInOtherNamespace); Assert.fail("datasetType found in namespace other than one in which it was expected"); } catch (DatasetTypeNotFoundException expected) { // expected } LOG.info("Creating, truncating, and deleting dataset of new Dataset type"); // Before creating dataset, there are some system datasets already exist int numBaseDataset = datasetClient.list(TEST_NAMESPACE).size(); Id.DatasetInstance instance = Id.DatasetInstance.from(TEST_NAMESPACE, "testDataset"); String description = "test description"; datasetClient.create(instance, new DatasetInstanceConfiguration(StandaloneDataset.TYPE_NAME, Collections.<String, String>emptyMap(), description)); Assert.assertEquals(numBaseDataset + 1, datasetClient.list(TEST_NAMESPACE).size()); // Assert dataset summary for the newly created dataset DatasetSpecificationSummary expectedSpec = new DatasetSpecificationSummary(instance.getId(), StandaloneDataset.TYPE_NAME, description, Collections.<String, String>emptyMap()); Assert.assertEquals(expectedSpec, getSpecForDataset(instance, datasetClient.list(TEST_NAMESPACE))); datasetClient.truncate(instance); DatasetMeta metaBefore = datasetClient.get(instance); Assert.assertEquals(0, metaBefore.getSpec().getProperties().size()); datasetClient.update(instance, ImmutableMap.of("sdf", "foo", "abc", "123")); DatasetMeta metaAfter = datasetClient.get(instance); Assert.assertEquals(2, metaAfter.getSpec().getProperties().size()); Assert.assertTrue(metaAfter.getSpec().getProperties().containsKey("sdf")); Assert.assertTrue(metaAfter.getSpec().getProperties().containsKey("abc")); Assert.assertEquals("foo", metaAfter.getSpec().getProperties().get("sdf")); Assert.assertEquals("123", metaAfter.getSpec().getProperties().get("abc")); datasetClient.updateExisting(instance, ImmutableMap.of("sdf", "fzz")); metaAfter = datasetClient.get(instance); Assert.assertEquals(2, metaAfter.getSpec().getProperties().size()); Assert.assertTrue(metaAfter.getSpec().getProperties().containsKey("sdf")); Assert.assertTrue(metaAfter.getSpec().getProperties().containsKey("abc")); Assert.assertEquals("fzz", metaAfter.getSpec().getProperties().get("sdf")); Assert.assertEquals("123", metaAfter.getSpec().getProperties().get("abc")); datasetClient.delete(instance); datasetClient.waitForDeleted(instance, 10, TimeUnit.SECONDS); Assert.assertEquals(numBaseDataset, datasetClient.list(TEST_NAMESPACE).size()); LOG.info("Creating and deleting multiple Datasets"); for (int i = 1; i <= 3; i++) { datasetClient.create(Id.DatasetInstance.from(TEST_NAMESPACE, "testDataset" + i), StandaloneDataset.TYPE_NAME); } Assert.assertEquals(numBaseDataset + 3, datasetClient.list(TEST_NAMESPACE).size()); for (int i = 1; i <= 3; i++) { datasetClient.delete(Id.DatasetInstance.from(TEST_NAMESPACE, "testDataset" + i)); } Assert.assertEquals(numBaseDataset, datasetClient.list(TEST_NAMESPACE).size()); LOG.info("Deleting Dataset module"); moduleClient.delete(module); Assert.assertEquals(numBaseModules, moduleClient.list(TEST_NAMESPACE).size()); Assert.assertEquals(numBaseTypes, typeClient.list(TEST_NAMESPACE).size()); LOG.info("Adding Dataset module and then deleting all Dataset modules"); moduleClient.add(Id.DatasetModule.from(TEST_NAMESPACE, "testModule1"), StandaloneDatasetModule.class.getName(), moduleJarFile); Assert.assertEquals(numBaseModules + 1, moduleClient.list(TEST_NAMESPACE).size()); Assert.assertEquals(numBaseTypes + 2, typeClient.list(TEST_NAMESPACE).size()); moduleClient.deleteAll(TEST_NAMESPACE); Assert.assertEquals(numBaseModules, moduleClient.list(TEST_NAMESPACE).size()); Assert.assertEquals(numBaseTypes, typeClient.list(TEST_NAMESPACE).size()); } @Test public void testSystemTypes() throws Exception { // Tests that a dataset can be created in a namespace, even if the type does not exist in that namespace. // The dataset type is being resolved from the system namespace. Id.DatasetType type = Id.DatasetType.from(TEST_NAMESPACE, Table.class.getName()); Id.DatasetInstance instance = Id.DatasetInstance.from(TEST_NAMESPACE, "tableTypeDataset"); Assert.assertFalse(typeClient.exists(type)); Assert.assertFalse(datasetClient.exists(instance)); datasetClient.create(instance, Table.class.getName()); Assert.assertTrue(datasetClient.exists(instance)); } @Nullable private DatasetSpecificationSummary getSpecForDataset(Id.DatasetInstance instance, List<DatasetSpecificationSummary> summaries) { DatasetSpecificationSummary actualSummary = null; for (DatasetSpecificationSummary summary : summaries) { if (StandaloneDataset.TYPE_NAME.equals(summary.getType()) && instance.getId().equals(summary.getName())) { actualSummary = summary; } } return actualSummary; } }