/* * Copyright © 2016 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.client.common.ClientTestBase; import co.cask.cdap.common.NotFoundException; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.artifact.ArtifactRange; import co.cask.cdap.proto.id.NamespaceId; import co.cask.cdap.proto.metadata.MetadataRecord; import co.cask.cdap.proto.metadata.MetadataScope; import co.cask.cdap.proto.metadata.MetadataSearchResultRecord; import co.cask.cdap.proto.metadata.MetadataSearchTargetType; import co.cask.cdap.proto.metadata.lineage.CollapseType; import co.cask.cdap.proto.metadata.lineage.LineageRecord; import com.google.common.collect.Iterators; import com.google.common.io.Files; import org.junit.Assert; import org.junit.Before; import java.io.IOException; import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.jar.Manifest; import javax.annotation.Nullable; /** * Base class for metadata tests. */ public abstract class MetadataTestBase extends ClientTestBase { protected static final NamespaceId TEST_NAMESPACE1 = new NamespaceId("testnamespace1"); private MetadataClient metadataClient; private LineageClient lineageClient; protected ArtifactClient artifactClient; protected NamespaceClient namespaceClient; protected ApplicationClient appClient; protected ProgramClient programClient; protected StreamClient streamClient; protected StreamViewClient streamViewClient; protected DatasetClient datasetClient; @Before public void beforeTest() throws IOException { metadataClient = new MetadataClient(getClientConfig()); lineageClient = new LineageClient(getClientConfig()); artifactClient = new ArtifactClient(getClientConfig()); namespaceClient = new NamespaceClient(getClientConfig()); appClient = new ApplicationClient(getClientConfig()); programClient = new ProgramClient(getClientConfig()); streamClient = new StreamClient(getClientConfig()); streamViewClient = new StreamViewClient(getClientConfig()); datasetClient = new DatasetClient(getClientConfig()); } protected void addAppArtifact(Id.Artifact artifactId, Class<?> cls) throws Exception { artifactClient.add(artifactId, null, Files.newInputStreamSupplier(createAppJarFile(cls))); } protected void addPluginArtifact(Id.Artifact artifactId, Class<?> cls, Manifest manifest, @Nullable Set<ArtifactRange> parents) throws Exception { artifactClient.add(artifactId, parents, Files.newInputStreamSupplier(createArtifactJarFile(cls, manifest))); } protected void addProperties(Id.Application app, @Nullable Map<String, String> properties) throws Exception { metadataClient.addProperties(app, properties); } protected void addProperties(final Id.Application app, @Nullable final Map<String, String> properties, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addProperties(app, properties); return null; } }, expectedExceptionClass); } protected void addProperties(Id.Artifact artifact, @Nullable Map<String, String> properties) throws Exception { metadataClient.addProperties(artifact, properties); } protected void addProperties(final Id.Artifact artifact, @Nullable final Map<String, String> properties, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addProperties(artifact, properties); return null; } }, expectedExceptionClass); } protected void addProperties(Id.Program program, @Nullable Map<String, String> properties) throws Exception { metadataClient.addProperties(program, properties); } protected void addProperties(final Id.Program program, @Nullable final Map<String, String> properties, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addProperties(program, properties); return null; } }, expectedExceptionClass); } protected void addProperties(Id.DatasetInstance dataset, @Nullable Map<String, String> properties) throws Exception { metadataClient.addProperties(dataset, properties); } protected void addProperties(final Id.DatasetInstance dataset, @Nullable final Map<String, String> properties, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addProperties(dataset, properties); return null; } }, expectedExceptionClass); } protected void addProperties(Id.Stream stream, @Nullable Map<String, String> properties) throws Exception { metadataClient.addProperties(stream, properties); } protected void addProperties(Id.Stream.View view, @Nullable Map<String, String> properties) throws Exception { metadataClient.addProperties(view, properties); } protected void addProperties(final Id.Stream stream, @Nullable final Map<String, String> properties, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addProperties(stream, properties); return null; } }, expectedExceptionClass); } protected void addProperties(final Id.Stream.View view, @Nullable final Map<String, String> properties, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addProperties(view, properties); return null; } }, expectedExceptionClass); } protected Set<MetadataRecord> getMetadata(Id.Application app) throws Exception { return getMetadata(app, null); } protected Set<MetadataRecord> getMetadata(Id.Artifact artifact) throws Exception { return getMetadata(artifact, null); } protected Set<MetadataRecord> getMetadata(Id.Program program) throws Exception { return getMetadata(program, null); } protected Set<MetadataRecord> getMetadata(Id.DatasetInstance dataset) throws Exception { return getMetadata(dataset, null); } protected Set<MetadataRecord> getMetadata(Id.Stream stream) throws Exception { return getMetadata(stream, null); } protected Set<MetadataRecord> getMetadata(Id.Stream.View view) throws Exception { return getMetadata(view, null); } protected Set<MetadataRecord> getMetadata(Id.Application app, @Nullable MetadataScope scope) throws Exception { return metadataClient.getMetadata(app, scope); } protected Set<MetadataRecord> getMetadata(Id.Artifact artifact, @Nullable MetadataScope scope) throws Exception { return metadataClient.getMetadata(artifact, scope); } protected Set<MetadataRecord> getMetadata(Id.Program program, @Nullable MetadataScope scope) throws Exception { return metadataClient.getMetadata(program, scope); } protected Set<MetadataRecord> getMetadata(Id.DatasetInstance dataset, @Nullable MetadataScope scope) throws Exception { return metadataClient.getMetadata(dataset, scope); } protected Set<MetadataRecord> getMetadata(Id.Stream stream, @Nullable MetadataScope scope) throws Exception { return metadataClient.getMetadata(stream, scope); } protected Set<MetadataRecord> getMetadata(Id.Stream.View view, @Nullable MetadataScope scope) throws Exception { return metadataClient.getMetadata(view, scope); } protected Map<String, String> getProperties(Id.Application app, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(app, scope).iterator()).getProperties(); } protected Map<String, String> getProperties(Id.Artifact artifact, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(artifact, scope).iterator()).getProperties(); } protected Map<String, String> getProperties(Id.Program program, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(program, scope).iterator()).getProperties(); } protected Map<String, String> getProperties(Id.DatasetInstance dataset, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(dataset, scope).iterator()).getProperties(); } protected Map<String, String> getProperties(Id.Stream stream, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(stream, scope).iterator()).getProperties(); } protected Map<String, String> getProperties(Id.Stream.View view, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(view, scope).iterator()).getProperties(); } protected void getPropertiesFromInvalidEntity(Id.Application app) throws Exception { try { getProperties(app, MetadataScope.USER); Assert.fail("Expected not to be able to get properties from invalid entity: " + app); } catch (NotFoundException expected) { // expected } } protected void getPropertiesFromInvalidEntity(Id.Program program) throws Exception { try { getProperties(program, MetadataScope.USER); Assert.fail("Expected not to be able to get properties from invalid entity: " + program); } catch (NotFoundException expected) { // expected } } protected void getPropertiesFromInvalidEntity(Id.DatasetInstance dataset) throws Exception { try { getProperties(dataset, MetadataScope.USER); Assert.fail("Expected not to be able to get properties from invalid entity: " + dataset); } catch (NotFoundException expected) { // expected } } protected void getPropertiesFromInvalidEntity(Id.Stream stream) throws Exception { try { getProperties(stream, MetadataScope.USER); Assert.fail("Expected not to be able to get properties from invalid entity: " + stream); } catch (NotFoundException expected) { // expected } } protected void getPropertiesFromInvalidEntity(Id.Stream.View view) throws Exception { try { getProperties(view, MetadataScope.USER); Assert.fail("Expected not to be able to get properties from invalid entity: " + view); } catch (NotFoundException expected) { // expected } } protected void removeMetadata(Id.Application app) throws Exception { metadataClient.removeMetadata(app); } protected void removeMetadata(Id.Artifact artifact) throws Exception { metadataClient.removeMetadata(artifact); } protected void removeMetadata(Id.Program program) throws Exception { metadataClient.removeMetadata(program); } protected void removeMetadata(Id.DatasetInstance dataset) throws Exception { metadataClient.removeMetadata(dataset); } protected void removeMetadata(Id.Stream stream) throws Exception { metadataClient.removeMetadata(stream); } protected void removeMetadata(Id.Stream.View view) throws Exception { metadataClient.removeMetadata(view); } protected void removeProperties(Id.Application app) throws Exception { metadataClient.removeProperties(app); } private void removeProperty(Id.Application app, String propertyToRemove) throws Exception { metadataClient.removeProperty(app, propertyToRemove); } protected void removeProperties(Id.Artifact artifact) throws Exception { metadataClient.removeProperties(artifact); } private void removeProperty(Id.Artifact artifact, String propertyToRemove) throws Exception { metadataClient.removeProperty(artifact, propertyToRemove); } protected void removeProperties(Id.Program program) throws Exception { metadataClient.removeProperties(program); } protected void removeProperty(Id.Program program, String propertyToRemove) throws Exception { metadataClient.removeProperty(program, propertyToRemove); } protected void removeProperties(Id.DatasetInstance dataset) throws Exception { metadataClient.removeProperties(dataset); } protected void removeProperty(Id.DatasetInstance dataset, String propertyToRemove) throws Exception { metadataClient.removeProperty(dataset, propertyToRemove); } protected void removeProperties(Id.Stream stream) throws Exception { metadataClient.removeProperties(stream); } protected void removeProperties(Id.Stream.View view) throws Exception { metadataClient.removeProperties(view); } protected void removeProperty(Id.Stream stream, String propertyToRemove) throws Exception { metadataClient.removeProperty(stream, propertyToRemove); } protected void removeProperty(Id.Stream.View view, String propertyToRemove) throws Exception { metadataClient.removeProperty(view, propertyToRemove); } protected void addTags(Id.Application app, @Nullable Set<String> tags) throws Exception { metadataClient.addTags(app, tags); } protected void addTags(final Id.Application app, @Nullable final Set<String> tags, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addTags(app, tags); return null; } }, expectedExceptionClass); } protected void addTags(Id.Artifact artifact, @Nullable Set<String> tags) throws Exception { metadataClient.addTags(artifact, tags); } protected void addTags(final Id.Artifact artifact, @Nullable final Set<String> tags, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addTags(artifact, tags); return null; } }, expectedExceptionClass); } protected void addTags(Id.Program program, @Nullable Set<String> tags) throws Exception { metadataClient.addTags(program, tags); } protected void addTags(final Id.Program program, @Nullable final Set<String> tags, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addTags(program, tags); return null; } }, expectedExceptionClass); } protected void addTags(Id.DatasetInstance dataset, @Nullable Set<String> tags) throws Exception { metadataClient.addTags(dataset, tags); } protected void addTags(final Id.DatasetInstance dataset, @Nullable final Set<String> tags, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addTags(dataset, tags); return null; } }, expectedExceptionClass); } protected void addTags(Id.Stream stream, @Nullable Set<String> tags) throws Exception { metadataClient.addTags(stream, tags); } protected void addTags(Id.Stream.View view, @Nullable Set<String> tags) throws Exception { metadataClient.addTags(view, tags); } protected void addTags(final Id.Stream stream, @Nullable final Set<String> tags, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addTags(stream, tags); return null; } }, expectedExceptionClass); } protected void addTags(final Id.Stream.View view, @Nullable final Set<String> tags, Class<? extends Exception> expectedExceptionClass) throws IOException { expectException(new Callable<Void>() { @Override public Void call() throws Exception { addTags(view, tags); return null; } }, expectedExceptionClass); } protected Set<MetadataSearchResultRecord> searchMetadata(Id.Namespace namespaceId, String query, Set<MetadataSearchTargetType> targets) throws Exception { return metadataClient.searchMetadata(namespaceId, query, targets); } protected Set<String> getTags(Id.Application app, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(app, scope).iterator()).getTags(); } protected Set<String> getTags(Id.Artifact artifact, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(artifact, scope).iterator()).getTags(); } protected Set<String> getTags(Id.Program program, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(program, scope).iterator()).getTags(); } protected Set<String> getTags(Id.DatasetInstance dataset, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(dataset, scope).iterator()).getTags(); } protected Set<String> getTags(Id.Stream stream, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(stream, scope).iterator()).getTags(); } protected Set<String> getTags(Id.Stream.View view, MetadataScope scope) throws Exception { return Iterators.getOnlyElement(getMetadata(view, scope).iterator()).getTags(); } protected void removeTags(Id.Application app) throws Exception { metadataClient.removeTags(app); } protected void removeTag(Id.Application app, String tagToRemove) throws Exception { metadataClient.removeTag(app, tagToRemove); } protected void removeTags(Id.Artifact artifact) throws Exception { metadataClient.removeTags(artifact); } protected void removeTag(Id.Artifact artifact, String tagToRemove) throws Exception { metadataClient.removeTag(artifact, tagToRemove); } protected void removeTags(Id.Program program) throws Exception { metadataClient.removeTags(program); } private void removeTag(Id.Program program, String tagToRemove) throws Exception { metadataClient.removeTag(program, tagToRemove); } protected void removeTags(Id.DatasetInstance dataset) throws Exception { metadataClient.removeTags(dataset); } protected void removeTag(Id.DatasetInstance dataset, String tagToRemove) throws Exception { metadataClient.removeTag(dataset, tagToRemove); } protected void removeTags(Id.Stream stream) throws Exception { metadataClient.removeTags(stream); } protected void removeTags(Id.Stream.View view) throws Exception { metadataClient.removeTags(view); } protected void removeTag(Id.Stream stream, String tagToRemove) throws Exception { metadataClient.removeTag(stream, tagToRemove); } protected void removeTag(Id.Stream.View view, String tagToRemove) throws Exception { metadataClient.removeTag(view, tagToRemove); } // expect an exception during fetching of lineage protected void fetchLineage(Id.DatasetInstance datasetInstance, long start, long end, int levels, Class<? extends Exception> expectedExceptionClass) throws Exception { fetchLineage(datasetInstance, Long.toString(start), Long.toString(end), levels, expectedExceptionClass); } // expect an exception during fetching of lineage protected void fetchLineage(final Id.DatasetInstance datasetInstance, final String start, final String end, final int levels, Class<? extends Exception> expectedExceptionClass) throws Exception { expectException(new Callable<Void>() { @Override public Void call() throws Exception { fetchLineage(datasetInstance, start, end, levels); return null; } }, expectedExceptionClass); } protected LineageRecord fetchLineage(Id.DatasetInstance datasetInstance, long start, long end, int levels) throws Exception { return lineageClient.getLineage(datasetInstance, start, end, levels); } protected LineageRecord fetchLineage(Id.DatasetInstance datasetInstance, long start, long end, Set<CollapseType> collapseTypes, int levels) throws Exception { return lineageClient.getLineage(datasetInstance, start, end, collapseTypes, levels); } protected LineageRecord fetchLineage(Id.DatasetInstance datasetInstance, String start, String end, int levels) throws Exception { return lineageClient.getLineage(datasetInstance, start, end, levels); } protected LineageRecord fetchLineage(Id.Stream stream, long start, long end, int levels) throws Exception { return lineageClient.getLineage(stream, start, end, levels); } protected LineageRecord fetchLineage(Id.Stream stream, String start, String end, int levels) throws Exception { return lineageClient.getLineage(stream, start, end, levels); } protected LineageRecord fetchLineage(Id.Stream stream, long start, long end, Set<CollapseType> collapseTypes, int levels) throws Exception { return lineageClient.getLineage(stream, start, end, collapseTypes, levels); } protected Set<MetadataRecord> fetchRunMetadata(Id.Run run) throws Exception { return metadataClient.getMetadata(run); } protected void assertRunMetadataNotFound(Id.Run run) throws Exception { try { fetchRunMetadata(run); Assert.fail("Excepted not to fetch Metadata for a nonexistent Run."); } catch (NotFoundException expected) { // expected } } private <T> void expectException(Callable<T> callable, Class<? extends Exception> expectedExceptionClass) { try { callable.call(); Assert.fail("Expected to have exception of class: " + expectedExceptionClass); } catch (Exception e) { Assert.assertTrue(e.getClass() == expectedExceptionClass); } } }