package com.thinkbiganalytics.feedmgr.rest.model; /*- * #%L * thinkbig-feed-manager-rest-model * %% * 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.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.collect.Lists; import com.thinkbiganalytics.nifi.rest.model.NifiProperty; import com.thinkbiganalytics.nifi.rest.support.NifiProcessUtil; import com.thinkbiganalytics.security.rest.model.EntityAccessControl; import org.apache.commons.lang3.StringUtils; import org.apache.nifi.web.api.dto.TemplateDTO; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; /** */ @JsonIgnoreProperties(ignoreUnknown = true) public class RegisteredTemplate extends EntityAccessControl { private List<NifiProperty> properties; private List<Processor> nonInputProcessors; private List<Processor> inputProcessors; private String id; private String nifiTemplateId; private String templateName; private Date updateDate; private Date createDate; private String icon; private String iconColor; private String description; private String state; private boolean defineTable; @JsonProperty("allowPreconditions") private boolean allowPreconditions; @JsonProperty("dataTransformation") private boolean dataTransformation; private boolean reusableTemplate; private List<ReusableTemplateConnectionInfo> reusableTemplateConnections; private List<TemplateProcessorDatasourceDefinition> registeredDatasourceDefinitions; private Long order; private List<String> templateOrder; @JsonProperty("isStream") private boolean isStream; @JsonIgnore private Set<String> feedNames; /** * The number of feeds that use this template */ private Integer feedsCount; @JsonIgnore private TemplateDTO nifiTemplate; /** * flag to indicate the template was updated */ @JsonIgnore private boolean updated; public RegisteredTemplate() { } public RegisteredTemplate(RegisteredTemplate registeredTemplate) { this.id = registeredTemplate.getId(); this.nifiTemplateId = registeredTemplate.getNifiTemplateId(); this.templateName = registeredTemplate.getTemplateName(); this.defineTable = registeredTemplate.isDefineTable(); this.updateDate = registeredTemplate.getUpdateDate(); this.createDate = registeredTemplate.getCreateDate(); this.allowPreconditions = registeredTemplate.isAllowPreconditions(); this.dataTransformation = registeredTemplate.isDataTransformation(); this.icon = registeredTemplate.getIcon(); this.iconColor = registeredTemplate.getIconColor(); this.description = registeredTemplate.getDescription(); this.state = registeredTemplate.getState(); //copy properties??? if (registeredTemplate.getProperties() != null) { this.properties = new ArrayList<>(registeredTemplate.getProperties()); } this.reusableTemplate = registeredTemplate.isReusableTemplate(); if (registeredTemplate.getReusableTemplateConnections() != null) { this.reusableTemplateConnections = new ArrayList<>(registeredTemplate.getReusableTemplateConnections()); } this.feedsCount = registeredTemplate.getFeedsCount(); this.registeredDatasourceDefinitions = registeredTemplate.getRegisteredDatasourceDefinitions(); this.order = registeredTemplate.getOrder(); this.isStream = registeredTemplate.isStream(); this.setOwner(registeredTemplate.getOwner()); this.setRoleMemberships(registeredTemplate.getRoleMemberships()); this.setAllowedActions(registeredTemplate.getAllowedActions()); this.initializeProcessors(); } @JsonIgnore public static Predicate<NifiProperty> isValidInput() { return property -> property.isInputProperty() && !NifiProcessUtil.CLEANUP_TYPE.equalsIgnoreCase(property.getProcessorType()); } @JsonIgnore public static Predicate<Processor> isValidInputProcessor() { return processor -> !NifiProcessUtil.CLEANUP_TYPE.equalsIgnoreCase(processor.getType()); } @JsonIgnore public static Predicate<NifiProperty> isPropertyModifiedFromTemplateValue() { return property -> (property.isSelected() && ((property.getValue() == null && property.getTemplateValue() != null) || (property.getValue() != null && !property.getValue().equalsIgnoreCase(property.getTemplateValue())) )); } public List<NifiProperty> getProperties() { return properties; } public void setProperties(List<NifiProperty> properties) { this.properties = properties; } public String getNifiTemplateId() { return nifiTemplateId; } public void setNifiTemplateId(String nifiTemplateId) { this.nifiTemplateId = nifiTemplateId; } public String getTemplateName() { return templateName; } public void setTemplateName(String templateName) { this.templateName = templateName; } public boolean isDefineTable() { return defineTable; } public void setDefineTable(boolean defineTable) { this.defineTable = defineTable; } public Date getUpdateDate() { return updateDate; } public void setUpdateDate(Date updateDate) { this.updateDate = updateDate; } public Date getCreateDate() { return createDate; } public void setCreateDate(Date createDate) { this.createDate = createDate; } public boolean isAllowPreconditions() { return allowPreconditions; } public void setAllowPreconditions(boolean allowPreconditions) { this.allowPreconditions = allowPreconditions; } public boolean isDataTransformation() { return dataTransformation; } public void setDataTransformation(boolean dataTransformation) { this.dataTransformation = dataTransformation; } public String getIcon() { return icon; } public void setIcon(String icon) { this.icon = icon; } public String getIconColor() { return iconColor; } public void setIconColor(String iconColor) { this.iconColor = iconColor; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public String getId() { return id; } public void setId(String id) { this.id = id; } public boolean isReusableTemplate() { return reusableTemplate; } public void setReusableTemplate(boolean reusableTemplate) { this.reusableTemplate = reusableTemplate; } public List<ReusableTemplateConnectionInfo> getReusableTemplateConnections() { return reusableTemplateConnections; } public void setReusableTemplateConnections( List<ReusableTemplateConnectionInfo> reusableTemplateConnections) { this.reusableTemplateConnections = reusableTemplateConnections; } public boolean usesReusableTemplate() { return getReusableTemplateConnections() != null && !getReusableTemplateConnections().isEmpty(); } public Integer getFeedsCount() { return feedsCount; } public void setFeedsCount(Integer feedsCount) { this.feedsCount = feedsCount; } public List<Processor> getNonInputProcessors() { return nonInputProcessors; } public void setNonInputProcessors(List<Processor> nonInputProcessors) { this.nonInputProcessors = nonInputProcessors; } public List<Processor> getInputProcessors() { return inputProcessors; } public void setInputProcessors(List<Processor> inputProcessors) { this.inputProcessors = inputProcessors; } public List<NifiProperty> findModifiedDefaultProperties() { if (properties != null) { return getProperties().stream().filter(isPropertyModifiedFromTemplateValue()).collect(Collectors.toList()); } else { return null; } } @JsonIgnore public void initializeNonInputProcessors() { Map<String, Processor> processorMap = new HashMap<>(); properties.stream().filter(property -> !property.isInputProperty()).forEach(property -> { processorMap.computeIfAbsent(property.getProcessorId(), processorId -> new Processor(processorId)).addProperty(property); }); nonInputProcessors = Lists.newArrayList(processorMap.values()); } @JsonIgnore public void initializeInputProcessors() { Map<String, Processor> processorMap = new HashMap<>(); properties.stream().filter(isValidInput()).forEach(property -> { processorMap.computeIfAbsent(property.getProcessorId(), processorId -> new Processor(property.getProcessorId())).addProperty(property); }); inputProcessors = Lists.newArrayList(processorMap.values()); } public void initializeProcessors() { Map<String, Processor> processorMap = new HashMap<>(); Map<String, Processor> inputProcessorMap = new HashMap<>(); Map<String, Processor> nonInputProcessorMap = new HashMap<>(); properties.stream().forEach(property -> { processorMap.computeIfAbsent(property.getProcessorId(), processorId -> new Processor(property.getProcessorId())).addProperty(property); if (property.isInputProperty()) { //dont allow the cleanup processor as a valid input selection if (property.isInputProperty() && !NifiProcessUtil.CLEANUP_TYPE.equalsIgnoreCase(property.getProcessorType())) { inputProcessorMap.computeIfAbsent(property.getProcessorId(), processorId -> processorMap.get(property.getProcessorId())); } //mark the template as allowing preconditions if it has an input of TriggerFeed if(NifiProcessUtil.TRIGGER_FEED_TYPE.equalsIgnoreCase(property.getProcessorType()) && !this.isAllowPreconditions()) { this.setAllowPreconditions(true); } } else { nonInputProcessorMap.computeIfAbsent(property.getProcessorId(), processorId -> processorMap.get(property.getProcessorId())); } }); inputProcessors = Lists.newArrayList(inputProcessorMap.values()); nonInputProcessors = Lists.newArrayList(nonInputProcessorMap.values()); } public String getState() { return state; } public void setState(String state) { this.state = state; } public List<String> getTemplateOrder() { return templateOrder; } public void setTemplateOrder(List<String> templateOrder) { this.templateOrder = templateOrder; } public Long getOrder() { return order; } public void setOrder(Long order) { this.order = order; } public List<TemplateProcessorDatasourceDefinition> getRegisteredDatasourceDefinitions() { if (registeredDatasourceDefinitions == null) { registeredDatasourceDefinitions = new ArrayList<>(); } return registeredDatasourceDefinitions; } public void setRegisteredDatasourceDefinitions(List<TemplateProcessorDatasourceDefinition> registeredDatasources) { this.registeredDatasourceDefinitions = registeredDatasources; } public TemplateDTO getNifiTemplate() { return nifiTemplate; } public void setNifiTemplate(TemplateDTO nifiTemplate) { this.nifiTemplate = nifiTemplate; } @JsonIgnore public Set<String> getFeedNames() { return feedNames; } @JsonIgnore public void setFeedNames(Set<String> feedNames) { this.feedNames = feedNames; } public boolean isStream() { return isStream; } public void setStream(boolean isStream) { this.isStream = isStream; } public List<NifiProperty> getConfigurationProperties(){ return getProperties().stream().filter(nifiProperty -> nifiProperty.isContainsConfigurationVariables()).collect(Collectors.toList()); } public List<NifiProperty> getSensitiveProperties(){ return getProperties().stream().filter(nifiProperty -> nifiProperty.isSensitive()).collect(Collectors.toList()); } public static class FlowProcessor extends RegisteredTemplate.Processor { private String flowId; private boolean isLeaf; public FlowProcessor() { super(); } public FlowProcessor(String processorId) { super(processorId); } public String getFlowId() { return flowId; } public void setFlowId(String flowId) { this.flowId = flowId; } public boolean isLeaf() { return isLeaf; } public void setIsLeaf(boolean isLeaf) { this.isLeaf = isLeaf; } } public static class Processor { List<NifiProperty> properties; private String type; private String name; private String id; private String groupName; private String groupId; private boolean inputProcessor; private boolean userDefinedInputProcessor; public Processor() { } public Processor(String processorId) { this.id = processorId; } private void setProcessorData(NifiProperty property) { if (StringUtils.isBlank(name)) { name = property.getProcessorName(); } if (StringUtils.isBlank(groupName)) { groupName = property.getProcessGroupName(); } if (StringUtils.isBlank(groupId)) { groupId = property.getProcessGroupId(); } if (StringUtils.isBlank(type)) { type = property.getProcessorType(); } if (property.isInputProperty()) { inputProcessor = true; } } public void addProperty(NifiProperty property) { getProperties().add(property); setProcessorData(property); } public String getType() { return type; } public void setType(String type) { this.type = type; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getGroupName() { return groupName; } public void setGroupName(String groupName) { this.groupName = groupName; } public String getGroupId() { return groupId; } public void setGroupId(String groupId) { this.groupId = groupId; } public boolean isInputProcessor() { return inputProcessor; } public void setInputProcessor(boolean inputProcessor) { this.inputProcessor = inputProcessor; } public boolean isUserDefinedInputProcessor() { return userDefinedInputProcessor; } public void setUserDefinedInputProcessor(boolean userDefinedInputProcessor) { this.userDefinedInputProcessor = userDefinedInputProcessor; } public List<NifiProperty> getProperties() { if (properties == null) { properties = new ArrayList<>(); } return properties; } public void setProperties(List<NifiProperty> properties) { this.properties = properties; } } @JsonIgnore public boolean isUpdated() { return updated; } @JsonIgnore public void setUpdated(boolean updated) { this.updated = updated; } }