package com.thinkbiganalytics.nifi.provenance.model;
/*-
* #%L
* thinkbig-nifi-provenance-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.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.thinkbiganalytics.nifi.provenance.KyloProcessorFlowType;
import com.thinkbiganalytics.nifi.provenance.model.util.ProvenanceEventUtil;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
/**
* This is used in both the NiFi KyloReportingTask and also in Kylo Operations Manager
*
*
* Note: Any modifications to this class will result in the need to update kylo-services and the KyloReportingTask nar
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProvenanceEventRecordDTO implements Serializable {
private static final long serialVersionUID = 4464985246055158127L;
private static final Logger log = LoggerFactory.getLogger(ProvenanceEventRecordDTO.class);
private transient AtomicBoolean processed = new AtomicBoolean(false);
/**
* Indicates the start of a Root Flow file
*/
private boolean isStartOfJob;
/**
* Indicates the end of a Root Flow File
*/
private boolean isEndOfJob;
/**
* indicates it is the final event in a root file or if the root file has child root flow files (as a result of a Merge) when this is true it is the final event for all of the root flow files
*/
private boolean isFinalJobEvent;
/**
* inidcates if this is a Batch Root Flow file
*/
private boolean isBatchJob;
/**
* Track all failures related to this jobFlowFileId if this is a finalJobEvent
*/
private boolean hasFailedEvents;
private Long previousEventId;
/**
* The previous events flow file id
*/
private String previousFlowfileId;
/**
* the event Time of the previous event to help determine event duration
*/
private DateTime previousEventTime;
private DateTime startTime;
private String id;
private Long eventId;
private DateTime eventTime;
private Long eventDuration;
private String eventType;
private String flowFileUuid;
private String fileSize;
private Long fileSizeBytes;
private String clusterNodeId;
private String clusterNodeAddress;
private String groupId;
private String componentId;
private String componentType;
private String componentName;
private List<String> parentUuids;
private List<String> childUuids;
private String details;
private String sourceConnectionIdentifier;
private Long inputContentClaimFileSizeBytes;
private String inputContentClaimFileSize;
private Long outputContentClaimFileSizeBytes;
private String outputContentClaimFileSize;
private Set<String> relatedRootFlowFiles;
private boolean isStartOfFlowFile;
/**
* Indicates if the processor attached to this event {@code componentId} is a FAILURE, WARNING,
*/
private KyloProcessorFlowType processorType;
/**
* if this event came from a processor or connection that has the keyword "failure" or is "Auto terminated by Failure event"
*/
private boolean isFailure;
/**
* set when the aggregator is determining if the flow of events indicate a stream (rapid fire)
*/
private boolean stream;
/**
* The flow file id the corresponds to the parent /starting event
*/
private String jobFlowFileId;
/**
* The Id that corresponds to the first event that started the job
*/
private Long jobEventId;
//flow information the following are set via looking at the rest api graph of events
/**
* The Feed name {category}.{feed}
*/
private String feedName;
/**
* The processgroup that is holding the flow for this feed
*/
private String feedProcessGroupId;
private String batchId;
private String relationship;
@JsonProperty("updatedAttributes")
private Map<String, String> updatedAttributes;
@JsonProperty("previousAttributes")
private Map<String, String> previousAttributes;
@JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
@JsonProperty("attributes")
private Map<String, String> attributeMap;
private FeedFlowFile feedFlowFile;
public ProvenanceEventRecordDTO() {
}
public FeedFlowFile getFeedFlowFile() {
return feedFlowFile;
}
public void setFeedFlowFile(FeedFlowFile feedFlowFile) {
this.feedFlowFile = feedFlowFile;
}
public String getFeedName() {
return feedName;
}
public void setFeedName(String feedName) {
this.feedName = feedName;
}
public boolean isTerminatedByFailureRelationship() {
return ProvenanceEventUtil.isTerminatedByFailureRelationship(this);
}
public boolean isEndingFlowFileEvent() {
return ProvenanceEventUtil.isEndingFlowFileEvent(this);
}
public String getRelationship() {
return relationship;
}
public void setRelationship(String relationship) {
this.relationship = relationship;
}
@JsonAnyGetter
public Map<String, Object> getAdditionalProperties() {
return this.additionalProperties;
}
public void setAdditionalProperties(Map<String, Object> additionalProperties) {
this.additionalProperties = additionalProperties;
}
@JsonAnySetter
public void setAdditionalProperty(String name, Object value) {
this.additionalProperties.put(name, value);
}
@JsonProperty("attributes")
public Map<String, String> getAttributeMap() {
return attributeMap;
}
@JsonProperty("attributes")
public void setAttributeMap(Map<String, String> attributeMap) {
this.attributeMap = attributeMap;
}
@JsonProperty("updatedAttributes")
public Map<String, String> getUpdatedAttributes() {
return updatedAttributes;
}
@JsonProperty("updatedAttributes")
public void setUpdatedAttributes(Map<String, String> updatedAttributes) {
this.updatedAttributes = updatedAttributes;
}
@JsonProperty("previousAttributes")
public Map<String, String> getPreviousAttributes() {
return previousAttributes;
}
@JsonProperty("previousAttributes")
public void setPreviousAttributes(Map<String, String> previousAttributes) {
this.previousAttributes = previousAttributes;
}
public String getSourceConnectionIdentifier() {
return sourceConnectionIdentifier;
}
public void setSourceConnectionIdentifier(String sourceConnectionIdentifier) {
this.sourceConnectionIdentifier = sourceConnectionIdentifier;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Long getEventId() {
return eventId;
}
public void setEventId(Long eventId) {
this.eventId = eventId;
}
public Long getEventDuration() {
return eventDuration;
}
public void setEventDuration(Long eventDuration) {
this.eventDuration = eventDuration;
}
public String getEventType() {
return eventType;
}
public void setEventType(String eventType) {
this.eventType = eventType;
}
public String getFlowFileUuid() {
return flowFileUuid;
}
public void setFlowFileUuid(String flowFileUuid) {
this.flowFileUuid = flowFileUuid;
}
public String getFileSize() {
return fileSize;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
public Long getFileSizeBytes() {
return fileSizeBytes;
}
public void setFileSizeBytes(Long fileSizeBytes) {
this.fileSizeBytes = fileSizeBytes;
}
public String getClusterNodeId() {
return clusterNodeId;
}
public void setClusterNodeId(String clusterNodeId) {
this.clusterNodeId = clusterNodeId;
}
public String getClusterNodeAddress() {
return clusterNodeAddress;
}
public void setClusterNodeAddress(String clusterNodeAddress) {
this.clusterNodeAddress = clusterNodeAddress;
}
public String getGroupId() {
return groupId;
}
public void setGroupId(String groupId) {
this.groupId = groupId;
}
public String getComponentId() {
return componentId;
}
public void setComponentId(String componentId) {
this.componentId = componentId;
}
public String getComponentType() {
return componentType;
}
public void setComponentType(String componentType) {
this.componentType = componentType;
}
public String getComponentName() {
return componentName;
}
public void setComponentName(String componentName) {
this.componentName = componentName;
}
public List<String> getParentUuids() {
return parentUuids;
}
public void setParentUuids(List<String> parentUuids) {
this.parentUuids = parentUuids;
}
public List<String> getChildUuids() {
return childUuids;
}
public void setChildUuids(List<String> childUuids) {
this.childUuids = childUuids;
}
public void addChildUuid(String childFlowFileId) {
if (childUuids == null) {
childUuids = new ArrayList<>();
}
if (!childUuids.contains(childFlowFileId)) {
childUuids.add(childFlowFileId);
}
}
public String getDetails() {
return details;
}
public void setDetails(String details) {
this.details = details;
}
public boolean isStartOfFlowFile() {
return isStartOfFlowFile;
}
public void setStartOfFlowFile(boolean startOfFlowFile) {
isStartOfFlowFile = startOfFlowFile;
}
public void setPreviousEvent(ProvenanceEventRecordDTO previousEvent) {
if (previousEvent != null) {
this.previousEventId = previousEvent.getEventId();
this.previousEventTime = previousEvent.getEventTime();
this.previousFlowfileId = previousEvent.getFlowFileUuid();
this.setStartTime(previousEventTime);
}
}
public Long getPreviousEventId() {
return previousEventId;
}
public DateTime getPreviousEventTime() {
return previousEventTime;
}
public DateTime getEventTime() {
return eventTime;
}
public void setEventTime(DateTime eventTime) {
this.eventTime = eventTime;
}
public Set<String> getParentFlowFileIds() {
if (getParentUuids() != null) {
return new HashSet<>(this.getParentUuids());
}
return new HashSet<>();
}
public Long getInputContentClaimFileSizeBytes() {
return inputContentClaimFileSizeBytes;
}
public void setInputContentClaimFileSizeBytes(Long inputContentClaimFileSizeBytes) {
this.inputContentClaimFileSizeBytes = inputContentClaimFileSizeBytes;
}
public String getInputContentClaimFileSize() {
return inputContentClaimFileSize;
}
public void setInputContentClaimFileSize(String inputContentClaimFileSize) {
this.inputContentClaimFileSize = inputContentClaimFileSize;
}
public Long getOutputContentClaimFileSizeBytes() {
return outputContentClaimFileSizeBytes;
}
public void setOutputContentClaimFileSizeBytes(Long outputContentClaimFileSizeBytes) {
this.outputContentClaimFileSizeBytes = outputContentClaimFileSizeBytes;
}
public String getOutputContentClaimFileSize() {
return outputContentClaimFileSize;
}
public void setOutputContentClaimFileSize(String outputContentClaimFileSize) {
this.outputContentClaimFileSize = outputContentClaimFileSize;
}
public boolean isStream() {
return stream;
}
public void setStream(boolean stream) {
this.stream = stream;
}
public AtomicBoolean getProcessed() {
return processed;
}
public String getFeedProcessGroupId() {
return feedProcessGroupId;
}
public void setFeedProcessGroupId(String feedProcessGroupId) {
this.feedProcessGroupId = feedProcessGroupId;
}
public String getJobFlowFileId() {
return jobFlowFileId;
}
public void setJobFlowFileId(String jobFlowFileId) {
this.jobFlowFileId = jobFlowFileId;
}
public Long getJobEventId() {
return jobEventId;
}
public void setJobEventId(Long jobEventId) {
this.jobEventId = jobEventId;
}
public boolean isStartOfJob() {
return isStartOfJob;
}
public void setIsStartOfJob(boolean isStartOfJob) {
this.isStartOfJob = isStartOfJob;
}
public void setIsFailure(boolean isFailure) {
this.isFailure = isFailure;
}
public boolean isFailure() {
return isFailure;
}
public boolean isEndOfJob() {
return isEndOfJob;
}
public void setIsEndOfJob(boolean isEndOfJob) {
this.isEndOfJob = isEndOfJob;
}
public String getBatchId() {
return batchId;
}
public void setBatchId(String batchId) {
this.batchId = batchId;
}
private void addRelatedRootFlowFile(String rootFlowFileId) {
}
public Set<String> getRelatedRootFlowFiles() {
return relatedRootFlowFiles;
}
public void setRelatedRootFlowFiles(Set<String> relatedRootFlowFiles) {
this.relatedRootFlowFiles = relatedRootFlowFiles;
}
public boolean isFinalJobEvent() {
return isFinalJobEvent;
}
public void setIsFinalJobEvent(boolean isFinalJobEvent) {
this.isFinalJobEvent = isFinalJobEvent;
if (this.isFinalJobEvent) {
this.hasFailedEvents = getFeedFlowFile().hasFailedEvents();
}
}
public boolean isHasFailedEvents() {
return hasFailedEvents;
}
public void setHasFailedEvents(boolean hasFailedEvents) {
this.hasFailedEvents = hasFailedEvents;
}
public boolean isBatchJob() {
return isBatchJob;
}
public void setIsBatchJob(boolean isBatchJob) {
this.isBatchJob = isBatchJob;
}
public DateTime getStartTime() {
return startTime;
}
public void setStartTime(DateTime startTime) {
this.startTime = startTime;
}
public KyloProcessorFlowType getProcessorType() {
return processorType;
}
public void setProcessorType(KyloProcessorFlowType processorType) {
this.processorType = processorType;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ProvenanceEventRecordDTO that = (ProvenanceEventRecordDTO) o;
if (eventId != null ? !eventId.equals(that.eventId) : that.eventId != null) {
return false;
}
return !(flowFileUuid != null ? !flowFileUuid.equals(that.flowFileUuid) : that.flowFileUuid != null);
}
@Override
public int hashCode() {
int result = eventId != null ? eventId.hashCode() : 0;
result = 31 * result + (flowFileUuid != null ? flowFileUuid.hashCode() : 0);
return result;
}
public String toString() {
final StringBuilder sb = new StringBuilder("ProvenanceEventRecordDTO{");
sb.append("eventId=").append(getEventId());
sb.append(", processorName=").append(getComponentName());
sb.append(", componentId=").append(getComponentId());
sb.append(", flowFile=").append(getFlowFileUuid());
sb.append(", previous=").append(getPreviousEventId());
sb.append(", eventType=").append(getEventType());
sb.append(", eventDetails=").append(getDetails());
sb.append(", isEndOfJob=").append(isEndOfJob());
sb.append(", isBatch=").append(isBatchJob());
sb.append(", isStream=").append(isStream());
sb.append(", feed=").append(getFeedName());
sb.append('}');
return sb.toString();
}
/**
* reset this object so it can go back to pool
*/
public void reset() {
this.isStartOfJob = false;
this.isEndOfJob = false;
this.isFinalJobEvent = false;
this.isBatchJob = true;
this.hasFailedEvents = false;
this.previousEventId = null;
this.previousFlowfileId = null;
this.previousEventTime = null;
this.startTime = null;
this.id = null;
this.eventId = null;
this.eventTime = null;
this.eventDuration = null;
this.eventType = null;
this.flowFileUuid = null;
this.fileSize = null;
this.fileSizeBytes = null;
this.clusterNodeId = null;
this.clusterNodeAddress = null;
this.groupId = null;
this.componentId = null;
this.componentType = null;
this.componentName = null;
this.parentUuids = null;
this.childUuids = null;
this.details = null;
this.sourceConnectionIdentifier = null;
this.inputContentClaimFileSizeBytes = null;
this.inputContentClaimFileSize = null;
this.outputContentClaimFileSizeBytes = null;
this.outputContentClaimFileSize = null;
this.relatedRootFlowFiles = null;
this.isStartOfFlowFile = false;
this.processorType = null;
this.isFailure = false;
this.stream = false;
this.jobFlowFileId = null;
this.jobEventId = null;
this.feedName = null;
this.feedProcessGroupId = null;
this.batchId = null;
this.relationship = null;
this.feedFlowFile = null;
this.updatedAttributes = null;
this.previousAttributes = null;
this.additionalProperties = null;
this.attributeMap = null;
}
}