package com.thinkbiganalytics.feedmgr.service.feed; /*- * #%L * thinkbig-feed-manager-controller * %% * Copyright (C) 2017 ThinkBig Analytics * %% * 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. * #L% */ import com.google.common.base.Predicate; import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import com.thinkbiganalytics.feedmgr.rest.model.FeedCategory; import com.thinkbiganalytics.feedmgr.rest.model.FeedMetadata; import com.thinkbiganalytics.feedmgr.rest.model.FeedSummary; import com.thinkbiganalytics.feedmgr.rest.model.NifiFeed; import com.thinkbiganalytics.feedmgr.rest.model.RegisteredTemplate; import com.thinkbiganalytics.feedmgr.rest.model.UIFeed; import com.thinkbiganalytics.feedmgr.rest.model.UserField; import com.thinkbiganalytics.feedmgr.rest.model.UserProperty; import com.thinkbiganalytics.feedmgr.service.FileObjectPersistence; import com.thinkbiganalytics.feedmgr.service.category.FeedManagerCategoryService; import com.thinkbiganalytics.feedmgr.service.template.FeedManagerTemplateService; import com.thinkbiganalytics.metadata.api.feed.Feed; import com.thinkbiganalytics.nifi.rest.client.LegacyNifiRestClient; import com.thinkbiganalytics.policy.rest.model.FieldRuleProperty; import com.thinkbiganalytics.rest.model.LabelValue; import com.thinkbiganalytics.security.action.Action; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; import javax.annotation.Nonnull; import javax.annotation.PostConstruct; import javax.inject.Inject; /** * In memory implementation */ public class InMemoryFeedManagerFeedService implements FeedManagerFeedService { @Inject private LegacyNifiRestClient nifiRestClient; @Inject private FeedManagerCategoryService categoryProvider; @Inject private FeedManagerTemplateService templateProvider; private Map<String, FeedMetadata> feeds = new HashMap<>(); @PostConstruct private void postConstruct() { Collection<FeedMetadata> savedFeeds = FileObjectPersistence.getInstance().getFeedsFromFile(); if (savedFeeds != null) { Long maxId = 0L; for (FeedMetadata feed : savedFeeds) { //update the category mappings String categoryId = feed.getCategory().getId(); FeedCategory category = categoryProvider.getCategoryById(categoryId); feed.setCategory(category); category.addRelatedFeed(new FeedSummary(feed)); //add it to the map feeds.put(feed.getId(), feed); } loadSavedFeedsToMetaClientStore(); } } @Override public boolean checkFeedPermission(String id, Action action, Action... more) { // Permission checking not currently implemented for the in-memory implementation return true; } public Collection<FeedMetadata> getFeeds() { return feeds.values(); } public Collection<? extends UIFeed> getFeeds(boolean verbose) { if (verbose) { return getFeeds(); } else { return getFeedSummaryData(); } } public List<FeedSummary> getFeedSummaryData() { List<FeedSummary> summaryList = new ArrayList<>(); if (feeds != null && !feeds.isEmpty()) { for (FeedMetadata feed : feeds.values()) { summaryList.add(new FeedSummary(feed)); } } return summaryList; } public List<FeedSummary> getFeedSummaryForCategory(String categoryId) { List<FeedSummary> summaryList = new ArrayList<>(); FeedCategory category = categoryProvider.getCategoryById(categoryId); if (category != null && category.getFeeds() != null) { summaryList.addAll(category.getFeeds()); } return summaryList; } @Override public FeedMetadata getFeedByName(final String categoryName, final String feedName) { if (feeds != null && !feeds.isEmpty()) { return Iterables.tryFind(feeds.values(), new Predicate<FeedMetadata>() { @Override public boolean apply(FeedMetadata metadata) { return metadata.getFeedName().equalsIgnoreCase(feedName) && metadata.getCategoryName().equalsIgnoreCase(categoryName); } }).orNull(); } return feeds.get(feedName); } @Override public FeedMetadata getFeedById(String id) { return getFeedById(id, false); } @Override public FeedMetadata getFeedById(String id, boolean refreshTargetTableSchema) { if (feeds != null && !feeds.isEmpty()) { FeedMetadata feed = feeds.get(id); if (feed != null) { //get the latest category data FeedCategory category = categoryProvider.getCategoryById(feed.getCategory().getId()); feed.setCategory(category); //set the template to the feed RegisteredTemplate registeredTemplate = templateProvider.getRegisteredTemplate(feed.getTemplateId()); if (registeredTemplate != null) { RegisteredTemplate copy = new RegisteredTemplate(registeredTemplate); copy.getProperties().clear(); feed.setRegisteredTemplate(copy); feed.setTemplateId(copy.getNifiTemplateId()); } return feed; } } return null; } @Override public List<FeedMetadata> getFeedsWithTemplate(final String registeredTemplateId) { return Lists.newArrayList(Iterables.filter(feeds.values(), new Predicate<FeedMetadata>() { @Override public boolean apply(FeedMetadata feed) { return feed.getTemplateId().equalsIgnoreCase(registeredTemplateId); } })); } @Override public Feed.ID resolveFeed(@Nonnull Serializable fid) { throw new UnsupportedOperationException(); } @Override public void enableFeedCleanup(@Nonnull String feedId) { throw new UnsupportedOperationException(); } /** * Needed to rewire feeds to ids in the server upon server start since the Feed Metadata store is in memory now */ private void loadSavedFeedsToMetaClientStore() { for (FeedMetadata feedMetadata : feeds.values()) { feedMetadata.setFeedId(null); // saveToMetadataStore(feedMetadata); } } public void saveFeed(FeedMetadata feed) { if (feed.getId() == null || !feeds.containsKey(feed.getId())) { feed.setId(UUID.randomUUID().toString()); feed.setVersion(new Long(1)); } else { FeedMetadata previousFeed = feeds.get(feed.getId()); feed.setId(previousFeed.getId()); feed.setVersion(previousFeed.getVersion() + 1L); } //match up the related category String categoryId = feed.getCategory().getId(); FeedCategory category = null; if (categoryId != null) { category = categoryProvider.getCategoryById(categoryId); } if (category == null) { final String categoryName = feed.getCategory().getSystemName(); category = categoryProvider.getCategoryBySystemName(categoryName); feed.setCategory(category); } if (category != null) { category.addRelatedFeed(new FeedSummary(feed)); } // saveToMetadataStore(feed); feeds.put(feed.getId(), feed); FileObjectPersistence.getInstance().writeFeedsToFile(feeds.values()); } @Override public void deleteFeed(@Nonnull String feedId) { feeds.remove(feedId); } @Override public FeedSummary enableFeed(String feedId) { FeedMetadata feedMetadata = getFeedById(feedId); if (feedMetadata != null) { feedMetadata.setState("ENABLED"); return new FeedSummary(feedMetadata); } return null; } @Override public FeedSummary disableFeed(String feedId) { FeedMetadata feedMetadata = getFeedById(feedId); if (feedMetadata != null) { feedMetadata.setState("DISABLED"); return new FeedSummary(feedMetadata); } return null; } @Override public void applyFeedSelectOptions(List<FieldRuleProperty> properties) { if (properties != null && !properties.isEmpty()) { List<FeedSummary> feedSummaries = getFeedSummaryData(); List<LabelValue> feedSelection = new ArrayList<>(); for (FeedSummary feedSummary : feedSummaries) { feedSelection.add(new LabelValue(feedSummary.getCategoryAndFeedDisplayName(), feedSummary.getCategoryAndFeedSystemName())); } for (FieldRuleProperty property : properties) { property.setSelectableValues(feedSelection); if (property.getValues() == null) { property.setValues(new ArrayList<>()); // reset the intial values to be an empty arraylist } } } } @Nonnull @Override public Set<UserField> getUserFields() { return Collections.emptySet(); } @Override public void setUserFields(@Nonnull Set<UserField> userFields) { } @Nonnull @Override public Optional<Set<UserProperty>> getUserFields(@Nonnull String categoryId) { return Optional.of(Collections.emptySet()); } @Override public NifiFeed createFeed(FeedMetadata feedMetadata) { saveFeed(feedMetadata); NifiFeed nifiFeed = new NifiFeed(); nifiFeed.setFeedMetadata(feedMetadata); nifiFeed.setSuccess(true); return nifiFeed; } }