/* * 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.data2.transaction.queue.inmemory; import co.cask.cdap.api.data.stream.StreamSpecification; import co.cask.cdap.common.StreamNotFoundException; import co.cask.cdap.common.conf.Constants; import co.cask.cdap.common.queue.QueueName; import co.cask.cdap.data.stream.service.StreamMetaStore; import co.cask.cdap.data.view.ViewAdmin; import co.cask.cdap.data2.audit.AuditPublisher; import co.cask.cdap.data2.audit.AuditPublishers; import co.cask.cdap.data2.metadata.lineage.AccessType; import co.cask.cdap.data2.metadata.store.MetadataStore; import co.cask.cdap.data2.metadata.writer.LineageWriter; import co.cask.cdap.data2.registry.UsageRegistry; import co.cask.cdap.data2.transaction.stream.StreamAdmin; import co.cask.cdap.data2.transaction.stream.StreamConfig; import co.cask.cdap.proto.Id; import co.cask.cdap.proto.StreamProperties; import co.cask.cdap.proto.ViewSpecification; import co.cask.cdap.proto.audit.AuditPayload; import co.cask.cdap.proto.audit.AuditType; import com.google.common.base.Preconditions; import com.google.inject.Inject; import com.google.inject.Singleton; import java.io.IOException; import java.util.List; import java.util.Map; import java.util.Properties; import javax.annotation.Nullable; /** * admin for queues in memory. */ @Singleton public class InMemoryStreamAdmin extends InMemoryQueueAdmin implements StreamAdmin { private final StreamMetaStore streamMetaStore; private final UsageRegistry usageRegistry; private final LineageWriter lineageWriter; private final MetadataStore metadataStore; private final ViewAdmin viewAdmin; private AuditPublisher auditPublisher; @Inject public InMemoryStreamAdmin(InMemoryQueueService queueService, UsageRegistry usageRegistry, LineageWriter lineageWriter, StreamMetaStore streamMetaStore, MetadataStore metadataStore, ViewAdmin viewAdmin) { super(queueService); this.usageRegistry = usageRegistry; this.streamMetaStore = streamMetaStore; this.lineageWriter = lineageWriter; this.metadataStore = metadataStore; this.viewAdmin = viewAdmin; } @SuppressWarnings("unused") @Inject(optional = true) public void setAuditPublisher(AuditPublisher auditPublisher) { this.auditPublisher = auditPublisher; } @Override public void dropAllInNamespace(Id.Namespace namespace) throws Exception { queueService.resetStreamsWithPrefix(QueueName.prefixForNamedspacedStream(namespace.getId())); for (StreamSpecification spec : streamMetaStore.listStreams(namespace)) { // Remove metadata for the stream metadataStore.removeMetadata(Id.Stream.from(namespace, spec.getName())); streamMetaStore.removeStream(Id.Stream.from(namespace, spec.getName())); } } @Override public void configureInstances(Id.Stream streamId, long groupId, int instances) throws Exception { // No-op } @Override public void configureGroups(Id.Stream streamId, Map<Long, Integer> groupInfo) throws Exception { // No-op } @Override public StreamConfig getConfig(Id.Stream streamId) { throw new UnsupportedOperationException("Stream config not supported for non-file based stream."); } @Override public StreamProperties getProperties(Id.Stream streamId) { throw new UnsupportedOperationException("Stream properties not supported for non-file based stream."); } @Override public void updateConfig(Id.Stream streamId, StreamProperties properties) throws IOException { throw new UnsupportedOperationException("Stream config not supported for non-file based stream."); } @Override public boolean exists(Id.Stream streamId) throws Exception { return exists(QueueName.fromStream(streamId)); } @Override public StreamConfig create(Id.Stream streamId) throws Exception { create(QueueName.fromStream(streamId)); publishAudit(streamId, AuditType.CREATE); return null; } @Override public StreamConfig create(Id.Stream streamId, @Nullable Properties props) throws Exception { create(QueueName.fromStream(streamId), props); String description = (props != null) ? props.getProperty(Constants.Stream.DESCRIPTION) : null; streamMetaStore.addStream(streamId, description); publishAudit(streamId, AuditType.CREATE); return null; } @Override public void truncate(Id.Stream streamId) throws Exception { Preconditions.checkArgument(exists(streamId), "Stream '%s' does not exist.", streamId); truncate(QueueName.fromStream(streamId)); publishAudit(streamId, AuditType.TRUNCATE); } @Override public void drop(Id.Stream streamId) throws Exception { Preconditions.checkArgument(exists(streamId), "Stream '%s' does not exist.", streamId); // Remove metadata for the stream metadataStore.removeMetadata(streamId); drop(QueueName.fromStream(streamId)); streamMetaStore.removeStream(streamId); publishAudit(streamId, AuditType.DELETE); } @Override public boolean createOrUpdateView(Id.Stream.View viewId, ViewSpecification spec) throws Exception { Preconditions.checkArgument(exists(viewId.getStream()), "Stream '%s' does not exist.", viewId.getStreamId()); return viewAdmin.createOrUpdate(viewId, spec); } @Override public void deleteView(Id.Stream.View viewId) throws Exception { Preconditions.checkArgument(exists(viewId.getStream()), "Stream '%s' does not exist.", viewId.getStreamId()); viewAdmin.delete(viewId); } @Override public List<Id.Stream.View> listViews(Id.Stream streamId) throws Exception { Preconditions.checkArgument(exists(streamId), "Stream '%s' does not exist.", streamId); return viewAdmin.list(streamId); } @Override public ViewSpecification getView(Id.Stream.View viewId) throws Exception { Preconditions.checkArgument(exists(viewId.getStream()), "Stream '%s' does not exist.", viewId.getStreamId()); return viewAdmin.get(viewId); } @Override public boolean viewExists(Id.Stream.View viewId) throws Exception { if (!exists(viewId.getStream())) { throw new StreamNotFoundException(viewId.getStream()); } return viewAdmin.exists(viewId); } @Override public void register(Iterable<? extends Id> owners, Id.Stream streamId) { usageRegistry.registerAll(owners, streamId); } @Override public void addAccess(Id.Run run, Id.Stream streamId, AccessType accessType) { lineageWriter.addAccess(run, streamId, accessType); AuditPublishers.publishAccess(auditPublisher, streamId, accessType, run); } private void publishAudit(Id.Stream stream, AuditType auditType) { AuditPublishers.publishAudit(auditPublisher, stream, auditType, AuditPayload.EMPTY_PAYLOAD); } }