You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/01/21 14:05:10 UTC
[58/64] incubator-nifi git commit: Merge branch 'develop' into
NIFI-250
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/c5d452c1/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
----------------------------------------------------------------------
diff --cc nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
index 0000000,9a2dc30..027bae0
mode 000000,100644..100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java
@@@ -1,0 -1,2142 +1,2268 @@@
+ /*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.nifi.web.api.dto;
+
+ import java.text.Collator;
+ import java.util.ArrayList;
+ import java.util.Arrays;
+ import java.util.Collection;
+ import java.util.Collections;
+ import java.util.Comparator;
+ import java.util.Date;
+ import java.util.HashMap;
+ import java.util.HashSet;
+ import java.util.LinkedHashMap;
+ import java.util.LinkedHashSet;
+ import java.util.List;
+ import java.util.Locale;
+ import java.util.Map;
+ import java.util.Set;
+ import java.util.TreeMap;
+ import java.util.TreeSet;
+ import java.util.concurrent.TimeUnit;
+
+ import javax.ws.rs.WebApplicationException;
+
+ import org.apache.nifi.action.Action;
+ import org.apache.nifi.action.component.details.ComponentDetails;
+ import org.apache.nifi.action.component.details.ProcessorDetails;
+ import org.apache.nifi.action.component.details.RemoteProcessGroupDetails;
+ import org.apache.nifi.action.details.ActionDetails;
+ import org.apache.nifi.action.details.ConfigureDetails;
+ import org.apache.nifi.action.details.ConnectDetails;
+ import org.apache.nifi.action.details.MoveDetails;
+ import org.apache.nifi.action.details.PurgeDetails;
+ import org.apache.nifi.authorization.Authority;
+ import org.apache.nifi.cluster.HeartbeatPayload;
+ import org.apache.nifi.cluster.event.Event;
+ import org.apache.nifi.cluster.node.Node;
+ import org.apache.nifi.cluster.protocol.NodeIdentifier;
+ import org.apache.nifi.components.AllowableValue;
+ import org.apache.nifi.components.PropertyDescriptor;
+ import org.apache.nifi.components.ValidationResult;
+ import org.apache.nifi.connectable.Connectable;
+ import org.apache.nifi.connectable.ConnectableType;
+ import org.apache.nifi.connectable.Connection;
+ import org.apache.nifi.connectable.Funnel;
+ import org.apache.nifi.connectable.Port;
+ import org.apache.nifi.connectable.Position;
+ import org.apache.nifi.controller.ControllerService;
+ import org.apache.nifi.controller.ControllerServiceLookup;
+ import org.apache.nifi.controller.Counter;
+ import org.apache.nifi.controller.ProcessorNode;
+ import org.apache.nifi.controller.Snippet;
+ import org.apache.nifi.controller.Template;
+ import org.apache.nifi.controller.label.Label;
+ import org.apache.nifi.controller.status.ConnectionStatus;
+ import org.apache.nifi.controller.status.PortStatus;
+ import org.apache.nifi.controller.status.ProcessGroupStatus;
+ import org.apache.nifi.controller.status.ProcessorStatus;
+ import org.apache.nifi.controller.status.RemoteProcessGroupStatus;
+ import org.apache.nifi.diagnostics.GarbageCollection;
+ import org.apache.nifi.diagnostics.StorageUsage;
+ import org.apache.nifi.diagnostics.SystemDiagnostics;
+ import org.apache.nifi.flowfile.FlowFilePrioritizer;
+ import org.apache.nifi.groups.ProcessGroup;
+ import org.apache.nifi.groups.ProcessGroupCounts;
+ import org.apache.nifi.groups.RemoteProcessGroup;
+ import org.apache.nifi.history.History;
+ import org.apache.nifi.processor.Processor;
+ import org.apache.nifi.processor.Relationship;
+ import org.apache.nifi.processor.annotation.CapabilityDescription;
+ import org.apache.nifi.processor.annotation.Tags;
+ import org.apache.nifi.provenance.lineage.ComputeLineageResult;
+ import org.apache.nifi.provenance.lineage.ComputeLineageSubmission;
+ import org.apache.nifi.provenance.lineage.LineageEdge;
+ import org.apache.nifi.provenance.lineage.LineageNode;
+ import org.apache.nifi.provenance.lineage.ProvenanceEventLineageNode;
+ import org.apache.nifi.remote.RemoteGroupPort;
+ import org.apache.nifi.remote.RootGroupPort;
+ import org.apache.nifi.reporting.Bulletin;
+ import org.apache.nifi.reporting.BulletinRepository;
+ import org.apache.nifi.scheduling.SchedulingStrategy;
+ import org.apache.nifi.user.NiFiUser;
+ import org.apache.nifi.user.NiFiUserGroup;
+ import org.apache.nifi.util.FormatUtils;
+ import org.apache.nifi.util.NiFiProperties;
+ import org.apache.nifi.web.Revision;
+ import org.apache.nifi.web.api.dto.ProcessorConfigDTO.AllowableValueDTO;
+ import org.apache.nifi.web.api.dto.ProcessorConfigDTO.PropertyDescriptorDTO;
+ import org.apache.nifi.web.api.dto.action.ActionDTO;
+ import org.apache.nifi.web.api.dto.action.HistoryDTO;
+ import org.apache.nifi.web.api.dto.action.component.details.ComponentDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.component.details.ProcessorDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.component.details.RemoteProcessGroupDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.details.ActionDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.details.ConfigureDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.details.ConnectDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.details.MoveDetailsDTO;
+ import org.apache.nifi.web.api.dto.action.details.PurgeDetailsDTO;
+ import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO;
+ import org.apache.nifi.web.api.dto.provenance.lineage.LineageRequestDTO;
+ import org.apache.nifi.web.api.dto.provenance.lineage.LineageRequestDTO.LineageRequestType;
+ import org.apache.nifi.web.api.dto.provenance.lineage.LineageResultsDTO;
+ import org.apache.nifi.web.api.dto.provenance.lineage.ProvenanceLinkDTO;
+ import org.apache.nifi.web.api.dto.provenance.lineage.ProvenanceNodeDTO;
+ import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO;
+ import org.apache.nifi.web.api.dto.status.PortStatusDTO;
+ import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO;
+ import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO;
+ import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
+ import org.apache.nifi.web.api.dto.status.StatusDTO;
+ import org.apache.commons.lang3.StringUtils;
+
+ /**
+ *
+ */
+ public final class DtoFactory {
+
+ @SuppressWarnings("rawtypes")
+ private final static Comparator<Class> CLASS_NAME_COMPARATOR = new Comparator<Class>() {
+ @Override
+ public int compare(Class class1, Class class2) {
+ return Collator.getInstance(Locale.US).compare(class1.getSimpleName(), class2.getSimpleName());
+ }
+ };
+
+ final int MAX_BULLETINS_PER_COMPONENT = 5;
+
+ private NiFiProperties properties;
+ private ControllerServiceLookup controllerServiceLookup;
+
+ /**
+ * Creates an ActionDTO for the specified Action.
+ *
+ * @param action
+ * @return
+ */
+ public ActionDTO createActionDto(final Action action) {
+ final ActionDTO actionDto = new ActionDTO();
+ actionDto.setId(action.getId());
+ actionDto.setSourceId(action.getSourceId());
+ actionDto.setSourceName(action.getSourceName());
+ actionDto.setSourceType(action.getSourceType().name());
+ actionDto.setTimestamp(action.getTimestamp());
+ actionDto.setUserDn(action.getUserDn());
+ actionDto.setUserName(action.getUserName());
+ actionDto.setOperation(action.getOperation().name());
+ actionDto.setActionDetails(createActionDetailsDto(action.getActionDetails()));
+ actionDto.setComponentDetails(createComponentDetailsDto(action.getComponentDetails()));
+
+ return actionDto;
+ }
+
+ /**
+ * Creates an ActionDetailsDTO for the specified ActionDetails.
+ *
+ * @param actionDetails
+ * @return
+ */
+ private ActionDetailsDTO createActionDetailsDto(final ActionDetails actionDetails) {
+ if (actionDetails == null) {
+ return null;
+ }
+
+ if (actionDetails instanceof ConfigureDetails) {
+ final ConfigureDetailsDTO configureDetails = new ConfigureDetailsDTO();
+ configureDetails.setName(((ConfigureDetails) actionDetails).getName());
+ configureDetails.setPreviousValue(((ConfigureDetails) actionDetails).getPreviousValue());
+ configureDetails.setValue(((ConfigureDetails) actionDetails).getValue());
+ return configureDetails;
+ } else if (actionDetails instanceof ConnectDetails) {
+ final ConnectDetailsDTO connectDetails = new ConnectDetailsDTO();
+ connectDetails.setSourceId(((ConnectDetails) actionDetails).getSourceId());
+ connectDetails.setSourceName(((ConnectDetails) actionDetails).getSourceName());
+ connectDetails.setSourceType(((ConnectDetails) actionDetails).getSourceType().toString());
+ connectDetails.setRelationship(((ConnectDetails) actionDetails).getRelationship());
+ connectDetails.setDestinationId(((ConnectDetails) actionDetails).getDestinationId());
+ connectDetails.setDestinationName(((ConnectDetails) actionDetails).getDestinationName());
+ connectDetails.setDestinationType(((ConnectDetails) actionDetails).getDestinationType().toString());
+ return connectDetails;
+ } else if (actionDetails instanceof MoveDetails) {
+ final MoveDetailsDTO moveDetails = new MoveDetailsDTO();
+ moveDetails.setPreviousGroup(((MoveDetails) actionDetails).getPreviousGroup());
+ moveDetails.setPreviousGroupId(((MoveDetails) actionDetails).getPreviousGroupId());
+ moveDetails.setGroup(((MoveDetails) actionDetails).getGroup());
+ moveDetails.setGroupId(((MoveDetails) actionDetails).getGroupId());
+ return moveDetails;
+ } else if (actionDetails instanceof PurgeDetails) {
+ final PurgeDetailsDTO purgeDetails = new PurgeDetailsDTO();
+ purgeDetails.setEndDate(((PurgeDetails) actionDetails).getEndDate());
+ return purgeDetails;
+ } else {
+ throw new WebApplicationException(new IllegalArgumentException(String.format("Unrecognized type of action details encountered %s during serialization.", actionDetails.toString())));
+ }
+ }
+
+ /**
+ * Creates a ComponentDetailsDTO for the specified ComponentDetails.
+ *
+ * @param componentDetails
+ * @return
+ */
+ private ComponentDetailsDTO createComponentDetailsDto(final ComponentDetails componentDetails) {
+ if (componentDetails == null) {
+ return null;
+ }
+
+ if (componentDetails instanceof ProcessorDetails) {
+ final ProcessorDetailsDTO processorDetails = new ProcessorDetailsDTO();
+ processorDetails.setType(((ProcessorDetails) componentDetails).getType());
+ return processorDetails;
+ } else if (componentDetails instanceof RemoteProcessGroupDetails) {
+ final RemoteProcessGroupDetailsDTO remoteProcessGroupDetails = new RemoteProcessGroupDetailsDTO();
+ remoteProcessGroupDetails.setUri(((RemoteProcessGroupDetails) componentDetails).getUri());
+ return remoteProcessGroupDetails;
+ } else {
+ throw new WebApplicationException(new IllegalArgumentException(String.format("Unrecognized type of component details encountered %s during serialization. ", componentDetails.toString())));
+ }
+ }
+
+ /**
+ * Creates a HistoryDTO from the specified History.
+ *
+ * @param history
+ * @return
+ */
+ public HistoryDTO createHistoryDto(final History history) {
+ final HistoryDTO historyDto = new HistoryDTO();
+ historyDto.setTotal(history.getTotal());
+ historyDto.setLastRefreshed(history.getLastRefreshed());
+
+ if (history.getActions() != null) {
+ List<ActionDTO> actionDtos = new ArrayList<>();
+ for (Action action : history.getActions()) {
+ actionDtos.add(createActionDto(action));
+ }
+ historyDto.setActions(actionDtos);
+ }
+
+ return historyDto;
+ }
+
+ /**
+ * Creates CounterDTOs for each Counter specified.
+ *
+ * @param counterDtos
+ * @return
+ */
+ public CountersDTO createCountersDto(final Collection<CounterDTO> counterDtos) {
+ final CountersDTO dto = new CountersDTO();
+ dto.setCounters(counterDtos);
+ dto.setGenerated(new Date());
+ return dto;
+ }
+
+ /**
+ * Creates a CounterDTO from the specified Counter.
+ *
+ * @param counter
+ * @return
+ */
+ public CounterDTO createCounterDto(final Counter counter) {
+ final CounterDTO dto = new CounterDTO();
+ dto.setId(counter.getIdentifier());
+ dto.setContext(counter.getContext());
+ dto.setName(counter.getName());
+ dto.setValueCount(counter.getValue());
+ dto.setValue(FormatUtils.formatCount(counter.getValue()));
+ return dto;
+ }
+
+ /**
+ * Creates a PositionDTO from the specified position
+ *
+ * @param position
+ * @return
+ */
+ public PositionDTO createPositionDto(final Position position) {
+ return new PositionDTO(position.getX(), position.getY());
+ }
+
+ /**
+ * Creates a ConnectionDTO from the specified Connection.
+ *
+ * @param connection
+ * @return
+ */
+ public ConnectionDTO createConnectionDto(final Connection connection) {
+ if (connection == null) {
+ return null;
+ }
+ final ConnectionDTO dto = new ConnectionDTO();
+
+ dto.setId(connection.getIdentifier());
+ dto.setParentGroupId(connection.getProcessGroup().getIdentifier());
+
+ final List<PositionDTO> bendPoints = new ArrayList<>();
+ for (final Position bendPoint : connection.getBendPoints()) {
+ bendPoints.add(createPositionDto(bendPoint));
+ }
+ dto.setBends(bendPoints);
+ dto.setName(connection.getName());
+ dto.setLabelIndex(connection.getLabelIndex());
+ dto.setzIndex(connection.getZIndex());
+ dto.setSource(createConnectableDto(connection.getSource()));
+ dto.setDestination(createConnectableDto(connection.getDestination()));
+
+ dto.setBackPressureObjectThreshold(connection.getFlowFileQueue().getBackPressureObjectThreshold());
+ dto.setBackPressureDataSizeThreshold(connection.getFlowFileQueue().getBackPressureDataSizeThreshold());
+ dto.setFlowFileExpiration(connection.getFlowFileQueue().getFlowFileExpiration());
+ dto.setPrioritizers(new ArrayList<String>());
+ for (final FlowFilePrioritizer comparator : connection.getFlowFileQueue().getPriorities()) {
+ dto.getPrioritizers().add(comparator.getClass().getCanonicalName());
+ }
+
+ // For ports, we do not want to populate the relationships.
+ for (final Relationship selectedRelationship : connection.getRelationships()) {
+ if (!Relationship.ANONYMOUS.equals(selectedRelationship)) {
+ if (dto.getSelectedRelationships() == null) {
+ dto.setSelectedRelationships(new TreeSet<String>(Collator.getInstance(Locale.US)));
+ }
+
+ dto.getSelectedRelationships().add(selectedRelationship.getName());
+ }
+ }
+
+ // For ports, we do not want to populate the relationships.
+ for (final Relationship availableRelationship : connection.getSource().getRelationships()) {
+ if (!Relationship.ANONYMOUS.equals(availableRelationship)) {
+ if (dto.getAvailableRelationships() == null) {
+ dto.setAvailableRelationships(new TreeSet<String>(Collator.getInstance(Locale.US)));
+ }
+
+ dto.getAvailableRelationships().add(availableRelationship.getName());
+ }
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a ConnectableDTO from the specified Connectable.
+ *
+ * @param connectable
+ * @return
+ */
+ public ConnectableDTO createConnectableDto(final Connectable connectable) {
+ if (connectable == null) {
+ return null;
+ }
+
+ final ConnectableDTO dto = new ConnectableDTO();
+ dto.setId(connectable.getIdentifier());
+ dto.setName(connectable.getName());
+ dto.setType(connectable.getConnectableType().name());
+
+ if (connectable instanceof RemoteGroupPort) {
+ final RemoteGroupPort remoteGroupPort = (RemoteGroupPort) connectable;
+ final RemoteProcessGroup remoteGroup = remoteGroupPort.getRemoteProcessGroup();
+ dto.setGroupId(remoteGroup.getIdentifier());
+ dto.setRunning(remoteGroupPort.isTargetRunning());
+ dto.setTransmitting(remoteGroupPort.isRunning());
+ dto.setExists(remoteGroupPort.getTargetExists());
+ dto.setComments(remoteGroup.getComments());
+ } else {
+ dto.setGroupId(connectable.getProcessGroup().getIdentifier());
+ dto.setRunning(connectable.isRunning());
+ dto.setComments(connectable.getComments());
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a LabelDTO from the specified Label.
+ *
+ * @param label
+ * @return
+ */
+ public LabelDTO createLabelDto(final Label label) {
+ if (label == null) {
+ return null;
+ }
+
+ final LabelDTO dto = new LabelDTO();
+ dto.setId(label.getIdentifier());
+ dto.setPosition(createPositionDto(label.getPosition()));
+ dto.setStyle(label.getStyle());
+ dto.setHeight(label.getSize().getHeight());
+ dto.setWidth(label.getSize().getWidth());
+ dto.setLabel(label.getValue());
+ dto.setParentGroupId(label.getProcessGroup().getIdentifier());
+
+ return dto;
+ }
+
+ /**
+ * Creates a FunnelDTO from the specified Funnel.
+ *
+ * @param funnel
+ * @return
+ */
+ public FunnelDTO createFunnelDto(final Funnel funnel) {
+ if (funnel == null) {
+ return null;
+ }
+
+ final FunnelDTO dto = new FunnelDTO();
+ dto.setId(funnel.getIdentifier());
+ dto.setPosition(createPositionDto(funnel.getPosition()));
+ dto.setParentGroupId(funnel.getProcessGroup().getIdentifier());
+
+ return dto;
+ }
+
+ /**
+ * Creates a SnippetDTO from the specified Snippet.
+ *
+ * @param snippet
+ * @return
+ */
+ public SnippetDTO createSnippetDto(final Snippet snippet) {
+ final SnippetDTO dto = new SnippetDTO();
+ dto.setId(snippet.getId());
+ dto.setParentGroupId(snippet.getParentGroupId());
+ dto.setLinked(snippet.isLinked());
+
+ // populate the snippet contents ids
+ dto.setConnections(copy(snippet.getConnections()));
+ dto.setFunnels(copy(snippet.getFunnels()));
+ dto.setInputPorts(copy(snippet.getInputPorts()));
+ dto.setLabels(copy(snippet.getLabels()));
+ dto.setOutputPorts(copy(snippet.getOutputPorts()));
+ dto.setProcessGroups(copy(snippet.getProcessGroups()));
+ dto.setProcessors(copy(snippet.getProcessors()));
+ dto.setRemoteProcessGroups(copy(snippet.getRemoteProcessGroups()));
+
+ return dto;
+ }
+
+ /**
+ * Creates a TemplateDTO from the specified template.
+ *
+ * @param template
+ * @return
+ */
+ public TemplateDTO createTemplateDTO(final Template template) {
+ if (template == null) {
+ return null;
+ }
+
+ final TemplateDTO original = template.getDetails();
+
+ final TemplateDTO copy = new TemplateDTO();
+ copy.setId(original.getId());
+ copy.setName(original.getName());
+ copy.setDescription(original.getDescription());
+ copy.setTimestamp(original.getTimestamp());
+ copy.setUri(original.getUri());
+ return copy;
+ }
+
+ private String formatCount(final Integer intStatus) {
+ return intStatus == null ? "-" : FormatUtils.formatCount(intStatus);
+ }
+
+ private String formatDataSize(final Long longStatus) {
+ return longStatus == null ? "-" : FormatUtils.formatDataSize(longStatus);
+ }
+
+ public RemoteProcessGroupStatusDTO createRemoteProcessGroupStatusDto(final RemoteProcessGroupStatus remoteProcessGroupStatus) {
+ final RemoteProcessGroupStatusDTO dto = new RemoteProcessGroupStatusDTO();
+ dto.setId(remoteProcessGroupStatus.getId());
+ dto.setGroupId(remoteProcessGroupStatus.getGroupId());
+ dto.setTargetUri(remoteProcessGroupStatus.getTargetUri());
+ dto.setName(remoteProcessGroupStatus.getName());
+ dto.setTransmissionStatus(remoteProcessGroupStatus.getTransmissionStatus().toString());
+ dto.setActiveThreadCount(remoteProcessGroupStatus.getActiveThreadCount());
+ dto.setSent(formatCount(remoteProcessGroupStatus.getSentCount()) + " / " + formatDataSize(remoteProcessGroupStatus.getSentContentSize()));
+ dto.setReceived(formatCount(remoteProcessGroupStatus.getReceivedCount()) + " / " + formatDataSize(remoteProcessGroupStatus.getReceivedContentSize()));
+ dto.setAuthorizationIssues(remoteProcessGroupStatus.getAuthorizationIssues());
+
+ return dto;
+ }
+
+ public ProcessGroupStatusDTO createProcessGroupStatusDto(final BulletinRepository bulletinRepository, final ProcessGroupStatus processGroupStatus) {
+
+ final ProcessGroupStatusDTO processGroupStatusDto = new ProcessGroupStatusDTO();
+ processGroupStatusDto.setId(processGroupStatus.getId());
+ processGroupStatusDto.setName(processGroupStatus.getName());
+ processGroupStatusDto.setStatsLastRefreshed(new Date(processGroupStatus.getCreationTimestamp()));
+ processGroupStatusDto.setQueued(formatCount(processGroupStatus.getQueuedCount()) + " / " + formatDataSize(processGroupStatus.getQueuedContentSize()));
+ processGroupStatusDto.setRead(formatDataSize(processGroupStatus.getBytesRead()));
+ processGroupStatusDto.setWritten(formatDataSize(processGroupStatus.getBytesWritten()));
+ processGroupStatusDto.setInput(formatCount(processGroupStatus.getInputCount()) + " / " + formatDataSize(processGroupStatus.getInputContentSize()));
+ processGroupStatusDto.setOutput(formatCount(processGroupStatus.getOutputCount()) + " / " + formatDataSize(processGroupStatus.getOutputContentSize()));
+ processGroupStatusDto.setActiveThreadCount(processGroupStatus.getActiveThreadCount());
+
+ final Map<String, StatusDTO> componentStatusDtoMap = new HashMap<>();
+
+ // processor status
+ final Collection<ProcessorStatusDTO> processorStatDtoCollection = new ArrayList<>();
+ processGroupStatusDto.setProcessorStatus(processorStatDtoCollection);
+ final Collection<ProcessorStatus> processorStatusCollection = processGroupStatus.getProcessorStatus();
+ if (processorStatusCollection != null) {
+ for (final ProcessorStatus processorStatus : processorStatusCollection) {
+ final ProcessorStatusDTO processorStatusDto = createProcessorStatusDto(processorStatus);
+ processorStatDtoCollection.add(processorStatusDto);
+ componentStatusDtoMap.put(processorStatusDto.getId(), processorStatusDto);
+ }
+ }
+
+ // connection status
+ final Collection<ConnectionStatusDTO> connectionStatusDtoCollection = new ArrayList<>();
+ processGroupStatusDto.setConnectionStatus(connectionStatusDtoCollection);
+ final Collection<ConnectionStatus> connectionStatusCollection = processGroupStatus.getConnectionStatus();
+ if (connectionStatusCollection != null) {
+ for (final ConnectionStatus connectionStatus : connectionStatusCollection) {
+ final ConnectionStatusDTO connectionStatusDto = createConnectionStatusDto(connectionStatus);
+ connectionStatusDtoCollection.add(connectionStatusDto);
+ }
+ }
+
+ // local child process groups
+ final Collection<ProcessGroupStatusDTO> childProcessGroupStatusDtoCollection = new ArrayList<>();
+ processGroupStatusDto.setProcessGroupStatus(childProcessGroupStatusDtoCollection);
+ final Collection<ProcessGroupStatus> childProcessGroupStatusCollection = processGroupStatus.getProcessGroupStatus();
+ if (childProcessGroupStatusCollection != null) {
+ for (final ProcessGroupStatus childProcessGroupStatus : childProcessGroupStatusCollection) {
+ final ProcessGroupStatusDTO childProcessGroupStatusDto = createProcessGroupStatusDto(bulletinRepository, childProcessGroupStatus);
+ childProcessGroupStatusDtoCollection.add(childProcessGroupStatusDto);
+ }
+ }
+
+ // remote child process groups
+ final Collection<RemoteProcessGroupStatusDTO> childRemoteProcessGroupStatusDtoCollection = new ArrayList<>();
+ processGroupStatusDto.setRemoteProcessGroupStatus(childRemoteProcessGroupStatusDtoCollection);
+ final Collection<RemoteProcessGroupStatus> childRemoteProcessGroupStatusCollection = processGroupStatus.getRemoteProcessGroupStatus();
+ if (childRemoteProcessGroupStatusCollection != null) {
+ for (final RemoteProcessGroupStatus childRemoteProcessGroupStatus : childRemoteProcessGroupStatusCollection) {
+ final RemoteProcessGroupStatusDTO childRemoteProcessGroupStatusDto = createRemoteProcessGroupStatusDto(childRemoteProcessGroupStatus);
+ childRemoteProcessGroupStatusDtoCollection.add(childRemoteProcessGroupStatusDto);
+ componentStatusDtoMap.put(childRemoteProcessGroupStatusDto.getId(), childRemoteProcessGroupStatusDto);
+ }
+ }
+
+ // input ports
+ final Collection<PortStatusDTO> inputPortStatusDtoCollection = new ArrayList<>();
+ processGroupStatusDto.setInputPortStatus(inputPortStatusDtoCollection);
+ final Collection<PortStatus> inputPortStatusCollection = processGroupStatus.getInputPortStatus();
+ if (inputPortStatusCollection != null) {
+ for (final PortStatus portStatus : inputPortStatusCollection) {
+ final PortStatusDTO portStatusDto = createPortStatusDto(portStatus);
+ inputPortStatusDtoCollection.add(portStatusDto);
+ componentStatusDtoMap.put(portStatusDto.getId(), portStatusDto);
+ }
+ }
+
+ // output ports
+ final Collection<PortStatusDTO> outputPortStatusDtoCollection = new ArrayList<>();
+ processGroupStatusDto.setOutputPortStatus(outputPortStatusDtoCollection);
+ final Collection<PortStatus> outputPortStatusCollection = processGroupStatus.getOutputPortStatus();
+ if (outputPortStatusCollection != null) {
+ for (final PortStatus portStatus : outputPortStatusCollection) {
+ final PortStatusDTO portStatusDto = createPortStatusDto(portStatus);
+ outputPortStatusDtoCollection.add(portStatusDto);
+ componentStatusDtoMap.put(portStatusDto.getId(), portStatusDto);
+ }
+ }
+
+ // get the bulletins for this group and associate with the specific child component
+ if (bulletinRepository != null) {
+ if (processGroupStatusDto.getBulletins() == null) {
+ processGroupStatusDto.setBulletins(new ArrayList<BulletinDTO>());
+ }
+
+ // locate bulletins for this process group
+ final List<Bulletin> results = bulletinRepository.findBulletinsForGroupBySource(processGroupStatus.getId(), MAX_BULLETINS_PER_COMPONENT);
+ for (final Bulletin bulletin : results) {
+ final StatusDTO status = componentStatusDtoMap.get(bulletin.getSourceId());
+
+ // ensure this connectable is still in the flow
+ if (status != null) {
+ if (status.getBulletins() == null) {
+ status.setBulletins(new ArrayList<BulletinDTO>());
+ }
+
+ // convert the result into a dto
+ final BulletinDTO bulletinDto = createBulletinDto(bulletin);
+ status.getBulletins().add(bulletinDto);
+
+ // create a copy for the parent group
+ final BulletinDTO copy = copy(bulletinDto);
+ copy.setGroupId(StringUtils.EMPTY);
+ copy.setSourceId(processGroupStatus.getId());
+ copy.setSourceName(processGroupStatus.getName());
+ processGroupStatusDto.getBulletins().add(copy);
+ }
+ }
+
+ // copy over descendant bulletins
+ for (final ProcessGroupStatusDTO childProcessGroupStatusDto : processGroupStatusDto.getProcessGroupStatus()) {
+ if (childProcessGroupStatusDto.getBulletins() != null) {
+ for (final BulletinDTO descendantBulletinDto : childProcessGroupStatusDto.getBulletins()) {
+ // create a copy for the parent group
+ final BulletinDTO copy = copy(descendantBulletinDto);
+ copy.setGroupId(StringUtils.EMPTY);
+ copy.setSourceId(processGroupStatus.getId());
+ copy.setSourceName(processGroupStatus.getName());
+ processGroupStatusDto.getBulletins().add(copy);
+ }
+ }
+ }
+
+ // sort the bulletins
+ Collections.sort(processGroupStatusDto.getBulletins(), new Comparator<BulletinDTO>() {
+ @Override
+ public int compare(BulletinDTO o1, BulletinDTO o2) {
+ if (o1 == null && o2 == null) {
+ return 0;
+ }
+ if (o1 == null) {
+ return 1;
+ }
+ if (o2 == null) {
+ return -1;
+ }
+
+ return -Long.compare(o1.getId(), o2.getId());
+ }
+ });
+
+ // prune the response to only include the max number of bulletins
+ if (processGroupStatusDto.getBulletins().size() > MAX_BULLETINS_PER_COMPONENT) {
+ processGroupStatusDto.setBulletins(processGroupStatusDto.getBulletins().subList(0, MAX_BULLETINS_PER_COMPONENT));
+ }
+ }
+
+ return processGroupStatusDto;
+ }
+
+ public ConnectionStatusDTO createConnectionStatusDto(final ConnectionStatus connectionStatus) {
+
+ final ConnectionStatusDTO connectionStatusDto = new ConnectionStatusDTO();
+ connectionStatusDto.setGroupId(connectionStatus.getGroupId());
+ connectionStatusDto.setId(connectionStatus.getId());
+ connectionStatusDto.setName(connectionStatus.getName());
+ connectionStatusDto.setSourceId(connectionStatus.getSourceId());
+ connectionStatusDto.setSourceName(connectionStatus.getSourceName());
+ connectionStatusDto.setDestinationId(connectionStatus.getDestinationId());
+ connectionStatusDto.setDestinationName(connectionStatus.getDestinationName());
+
+ final String queuedCount = FormatUtils.formatCount(connectionStatus.getQueuedCount());
+ final String queuedSize = FormatUtils.formatDataSize(connectionStatus.getQueuedBytes());
+ connectionStatusDto.setQueuedCount(queuedCount);
+ connectionStatusDto.setQueuedSize(queuedSize);
+ connectionStatusDto.setQueued(queuedCount + " / " + queuedSize);
+
+ final int inputCount = connectionStatus.getInputCount();
+ final long inputBytes = connectionStatus.getInputBytes();
+ connectionStatusDto.setInput(FormatUtils.formatCount(inputCount) + " / " + FormatUtils.formatDataSize(inputBytes));
+
+ final int outputCount = connectionStatus.getOutputCount();
+ final long outputBytes = connectionStatus.getOutputBytes();
+ connectionStatusDto.setOutput(FormatUtils.formatCount(outputCount) + " / " + FormatUtils.formatDataSize(outputBytes));
+
+ return connectionStatusDto;
+ }
+
+ public ProcessorStatusDTO createProcessorStatusDto(final ProcessorStatus procStatus) {
+
+ final ProcessorStatusDTO dto = new ProcessorStatusDTO();
+ dto.setId(procStatus.getId());
+ dto.setGroupId(procStatus.getGroupId());
+ dto.setName(procStatus.getName());
+
+ final int processedCount = procStatus.getOutputCount();
+ final long numProcessedBytes = procStatus.getOutputBytes();
+ dto.setOutput(FormatUtils.formatCount(processedCount) + " / " + FormatUtils.formatDataSize(numProcessedBytes));
+
+ final int inputCount = procStatus.getInputCount();
+ final long inputBytes = procStatus.getInputBytes();
+ dto.setInput(FormatUtils.formatCount(inputCount) + " / " + FormatUtils.formatDataSize(inputBytes));
+
+ final long readBytes = procStatus.getBytesRead();
+ dto.setRead(FormatUtils.formatDataSize(readBytes));
+
+ final long writtenBytes = procStatus.getBytesWritten();
+ dto.setWritten(FormatUtils.formatDataSize(writtenBytes));
+
+ dto.setTasksDuration(FormatUtils.formatHoursMinutesSeconds(procStatus.getProcessingNanos(), TimeUnit.NANOSECONDS));
+ dto.setTasks(FormatUtils.formatCount(procStatus.getInvocations()));
+
+ // determine the run status
+ dto.setRunStatus(procStatus.getRunStatus().toString());
+
+ dto.setActiveThreadCount(procStatus.getActiveThreadCount());
+ dto.setType(procStatus.getType());
+
+ return dto;
+ }
+
+ /**
+ * Creates a PortStatusDTO for the specified PortStatus.
+ *
+ * @param portStatus
+ * @return
+ */
+ public PortStatusDTO createPortStatusDto(final PortStatus portStatus) {
+ final PortStatusDTO dto = new PortStatusDTO();
+ dto.setId(portStatus.getId());
+ dto.setGroupId(portStatus.getGroupId());
+ dto.setName(portStatus.getName());
+ dto.setActiveThreadCount(portStatus.getActiveThreadCount());
+ dto.setRunStatus(portStatus.getRunStatus().toString());
+ dto.setTransmitting(portStatus.isTransmitting());
+
+ final int processedCount = portStatus.getOutputCount();
+ final long numProcessedBytes = portStatus.getOutputBytes();
+ dto.setOutput(FormatUtils.formatCount(processedCount) + " / " + FormatUtils.formatDataSize(numProcessedBytes));
+
+ final int inputCount = portStatus.getInputCount();
+ final long inputBytes = portStatus.getInputBytes();
+ dto.setInput(FormatUtils.formatCount(inputCount) + " / " + FormatUtils.formatDataSize(inputBytes));
+
+ return dto;
+ }
+
+ /**
+ * Copies the specified snippet.
+ *
+ * @param originalSnippet
+ * @return
+ */
+ public FlowSnippetDTO copySnippetContents(FlowSnippetDTO originalSnippet) {
+ final FlowSnippetDTO copySnippet = new FlowSnippetDTO();
+
+ if (originalSnippet.getConnections() != null) {
+ for (final ConnectionDTO connection : originalSnippet.getConnections()) {
+ copySnippet.getConnections().add(copy(connection));
+ }
+ }
+ if (originalSnippet.getInputPorts() != null) {
+ for (final PortDTO port : originalSnippet.getInputPorts()) {
+ copySnippet.getInputPorts().add(copy(port));
+ }
+ }
+ if (originalSnippet.getOutputPorts() != null) {
+ for (final PortDTO port : originalSnippet.getOutputPorts()) {
+ copySnippet.getOutputPorts().add(copy(port));
+ }
+ }
+ if (originalSnippet.getProcessGroups() != null) {
+ for (final ProcessGroupDTO processGroup : originalSnippet.getProcessGroups()) {
+ copySnippet.getProcessGroups().add(copy(processGroup, true));
+ }
+ }
+ if (originalSnippet.getProcessors() != null) {
+ for (final ProcessorDTO processor : originalSnippet.getProcessors()) {
+ copySnippet.getProcessors().add(copy(processor));
+ }
+ }
+ if (originalSnippet.getLabels() != null) {
+ for (final LabelDTO label : originalSnippet.getLabels()) {
+ copySnippet.getLabels().add(copy(label));
+ }
+ }
+ if (originalSnippet.getFunnels() != null) {
+ for (final FunnelDTO funnel : originalSnippet.getFunnels()) {
+ copySnippet.getFunnels().add(copy(funnel));
+ }
+ }
+ if (originalSnippet.getRemoteProcessGroups() != null) {
+ for (final RemoteProcessGroupDTO remoteGroup : originalSnippet.getRemoteProcessGroups()) {
+ copySnippet.getRemoteProcessGroups().add(copy(remoteGroup));
+ }
+ }
+
+ return copySnippet;
+ }
+
+ /**
+ * Creates a PortDTO from the specified Port.
+ *
+ * @param port
+ * @return
+ */
+ public PortDTO createPortDto(final Port port) {
+ if (port == null) {
+ return null;
+ }
+
+ final PortDTO dto = new PortDTO();
+ dto.setId(port.getIdentifier());
+ dto.setPosition(createPositionDto(port.getPosition()));
+ dto.setName(port.getName());
+ dto.setComments(port.getComments());
+ dto.setConcurrentlySchedulableTaskCount(port.getMaxConcurrentTasks());
+ dto.setParentGroupId(port.getProcessGroup().getIdentifier());
+ dto.setState(port.getScheduledState().toString());
+ dto.setType(port.getConnectableType().name());
+
+ // if this port is on the root group, determine if its actually connected to another nifi
+ if (port instanceof RootGroupPort) {
+ final RootGroupPort rootGroupPort = (RootGroupPort) port;
+ dto.setTransmitting(rootGroupPort.isTransmitting());
+ dto.setGroupAccessControl(rootGroupPort.getGroupAccessControl());
+ dto.setUserAccessControl(rootGroupPort.getUserAccessControl());
+ }
+
+ final Collection<ValidationResult> validationErrors = port.getValidationErrors();
+ if (validationErrors != null && !validationErrors.isEmpty()) {
+ final List<String> errors = new ArrayList<>();
+ for (final ValidationResult validationResult : validationErrors) {
+ errors.add(validationResult.toString());
+ }
+
+ dto.setValidationErrors(errors);
+ }
+
+ return dto;
+ }
+
+ public RemoteProcessGroupPortDTO createRemoteProcessGroupPortDto(final RemoteGroupPort port) {
+ if (port == null) {
+ return null;
+ }
+
+ final RemoteProcessGroupPortDTO dto = new RemoteProcessGroupPortDTO();
+ dto.setId(port.getIdentifier());
+ dto.setName(port.getName());
+ dto.setComments(port.getComments());
+ dto.setTransmitting(port.isRunning());
+ dto.setTargetRunning(port.isTargetRunning());
+ dto.setConcurrentlySchedulableTaskCount(port.getMaxConcurrentTasks());
+ dto.setUseCompression(port.isUseCompression());
+ dto.setExists(port.getTargetExists());
+
+ // determine if this port is currently connected to another component locally
+ if (ConnectableType.REMOTE_OUTPUT_PORT.equals(port.getConnectableType())) {
+ dto.setConnected(!port.getConnections().isEmpty());
+ } else {
+ dto.setConnected(port.hasIncomingConnection());
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a RemoteProcessGroupDTO from the specified RemoteProcessGroup.
+ *
+ * @param group
+ * @return
+ */
+ public RemoteProcessGroupDTO createRemoteProcessGroupDto(final RemoteProcessGroup group) {
+ if (group == null) {
+ return null;
+ }
+
+ final Set<RemoteProcessGroupPortDTO> inputPorts = new TreeSet<>(new DtoFactory.SortedRemoteGroupPortComparator());
+ final Set<RemoteProcessGroupPortDTO> outputPorts = new TreeSet<>(new DtoFactory.SortedRemoteGroupPortComparator());
+
+ int activeRemoteInputPortCount = 0;
+ int inactiveRemoteInputPortCount = 0;
+ for (final Port port : group.getInputPorts()) {
+ inputPorts.add(createRemoteProcessGroupPortDto((RemoteGroupPort) port));
+
+ if (port.hasIncomingConnection()) {
+ if (port.isRunning()) {
+ activeRemoteInputPortCount++;
+ } else {
+ inactiveRemoteInputPortCount++;
+ }
+ }
+ }
+
+ int activeRemoteOutputPortCount = 0;
+ int inactiveRemoteOutputPortCount = 0;
+ for (final Port port : group.getOutputPorts()) {
+ outputPorts.add(createRemoteProcessGroupPortDto((RemoteGroupPort) port));
+
+ if (!port.getConnections().isEmpty()) {
+ if (port.isRunning()) {
+ activeRemoteOutputPortCount++;
+ } else {
+ activeRemoteOutputPortCount++;
+ }
+ }
+ }
+
+ final RemoteProcessGroupContentsDTO contents = new RemoteProcessGroupContentsDTO();
+ contents.setInputPorts(inputPorts);
+ contents.setOutputPorts(outputPorts);
+
+ final RemoteProcessGroupDTO dto = new RemoteProcessGroupDTO();
+ dto.setId(group.getIdentifier());
+ dto.setName(group.getName());
+ dto.setPosition(createPositionDto(group.getPosition()));
+ dto.setComments(group.getComments());
+ dto.setTransmitting(group.isTransmitting());
+ dto.setCommunicationsTimeout(group.getCommunicationsTimeout());
+ dto.setYieldDuration(group.getYieldDuration());
+ dto.setParentGroupId(group.getProcessGroup().getIdentifier());
+ dto.setTargetUri(group.getTargetUri().toString());
+ dto.setFlowRefreshed(group.getLastRefreshTime());
+ dto.setContents(contents);
+
+ // only specify the secure flag if we know the target system has site to site enabled
+ if (group.isSiteToSiteEnabled()) {
+ dto.setTargetSecure(group.getSecureFlag());
+ }
+
+ if (group.getAuthorizationIssue() != null) {
+ dto.setAuthorizationIssues(Arrays.asList(group.getAuthorizationIssue()));
+ }
+
+ dto.setActiveRemoteInputPortCount(activeRemoteInputPortCount);
+ dto.setInactiveRemoteInputPortCount(inactiveRemoteInputPortCount);
+ dto.setActiveRemoteOutputPortCount(activeRemoteOutputPortCount);
+ dto.setInactiveRemoteOutputPortCount(inactiveRemoteOutputPortCount);
+
+ final ProcessGroupCounts counts = group.getCounts();
+ if (counts != null) {
+ dto.setInputPortCount(counts.getInputPortCount());
+ dto.setOutputPortCount(counts.getOutputPortCount());
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a ProcessGroupDTO from the specified parent ProcessGroup.
+ *
+ * @param parentGroup
+ * @return
+ */
+ private ProcessGroupDTO createParentProcessGroupDto(final ProcessGroup parentGroup) {
+ if (parentGroup == null) {
+ return null;
+ }
+
+ final ProcessGroupDTO dto = new ProcessGroupDTO();
+ dto.setId(parentGroup.getIdentifier());
+ dto.setName(parentGroup.getName());
+
+ if (parentGroup.getParent() != null) {
+ dto.setParent(createParentProcessGroupDto(parentGroup.getParent()));
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a ProcessGroupDTO from the specified ProcessGroup.
+ *
+ * @param group
+ * @return
+ */
+ public ProcessGroupDTO createProcessGroupDto(final ProcessGroup group) {
+ return createProcessGroupDto(group, false);
+ }
+
+ /**
+ * Creates a ProcessGroupDTO from the specified ProcessGroup.
+ *
+ * @param group
+ * @param recurse
+ * @return
+ */
+ public ProcessGroupDTO createProcessGroupDto(final ProcessGroup group, final boolean recurse) {
+ final ProcessGroupDTO dto = createConciseProcessGroupDto(group);
+ dto.setContents(createProcessGroupContentsDto(group, recurse));
+ return dto;
+ }
+
+ /**
+ * Creates a ProcessGroupDTO from the specified ProcessGroup.
+ *
+ * @param group
+ * @param recurse
+ * @return
+ */
+ private ProcessGroupDTO createConciseProcessGroupDto(final ProcessGroup group) {
+ if (group == null) {
+ return null;
+ }
+
+ final ProcessGroupDTO dto = new ProcessGroupDTO();
+ dto.setId(group.getIdentifier());
+ dto.setPosition(createPositionDto(group.getPosition()));
+ dto.setComments(group.getComments());
+ dto.setName(group.getName());
+
+ ProcessGroup parentGroup = group.getParent();
+ if (parentGroup != null) {
+ dto.setParentGroupId(parentGroup.getIdentifier());
+ dto.setParent(createParentProcessGroupDto(parentGroup));
+ }
+
+ final ProcessGroupCounts counts = group.getCounts();
+ dto.setRunningCount(counts.getRunningCount());
+ dto.setStoppedCount(counts.getStoppedCount());
+ dto.setInvalidCount(counts.getInvalidCount());
+ dto.setDisabledCount(counts.getDisabledCount());
+ dto.setInputPortCount(counts.getInputPortCount());
+ dto.setOutputPortCount(counts.getOutputPortCount());
+ dto.setActiveRemotePortCount(counts.getActiveRemotePortCount());
+ dto.setInactiveRemotePortCount(counts.getInactiveRemotePortCount());
+
+ return dto;
+ }
+
+ /**
+ * Creates a ProcessGroupContentDTO from the specified ProcessGroup.
+ *
+ * @param group
+ * @param recurse
+ * @return
+ */
+ private FlowSnippetDTO createProcessGroupContentsDto(final ProcessGroup group, final boolean recurse) {
+ if (group == null) {
+ return null;
+ }
+
+ final FlowSnippetDTO dto = new FlowSnippetDTO();
+
+ for (final ProcessorNode procNode : group.getProcessors()) {
+ dto.getProcessors().add(createProcessorDto(procNode));
+ }
+
+ for (final Connection connNode : group.getConnections()) {
+ dto.getConnections().add(createConnectionDto(connNode));
+ }
+
+ for (final Label label : group.getLabels()) {
+ dto.getLabels().add(createLabelDto(label));
+ }
+
+ for (final Funnel funnel : group.getFunnels()) {
+ dto.getFunnels().add(createFunnelDto(funnel));
+ }
+
+ for (final ProcessGroup childGroup : group.getProcessGroups()) {
+ if (recurse) {
+ dto.getProcessGroups().add(createProcessGroupDto(childGroup, recurse));
+ } else {
+ dto.getProcessGroups().add(createConciseProcessGroupDto(childGroup));
+ }
+ }
+
+ for (final RemoteProcessGroup remoteProcessGroup : group.getRemoteProcessGroups()) {
+ dto.getRemoteProcessGroups().add(createRemoteProcessGroupDto(remoteProcessGroup));
+ }
+
+ for (final Port inputPort : group.getInputPorts()) {
+ dto.getInputPorts().add(createPortDto(inputPort));
+ }
+
+ for (final Port outputPort : group.getOutputPorts()) {
+ dto.getOutputPorts().add(createPortDto(outputPort));
+ }
+
+ return dto;
+ }
+
+ /**
+ * Gets the capability description from the specified class.
+ *
+ * @param cls
+ * @return
+ */
+ private String getCapabilityDescription(final Class<?> cls) {
+ final CapabilityDescription description = cls.getAnnotation(CapabilityDescription.class);
+ return (description == null) ? null : description.value();
+ }
+
+ /**
+ * Gets the tags from the specified class.
+ *
+ * @param cls
+ * @return
+ */
+ private Set<String> getTags(final Class<?> cls) {
+ final Set<String> tags = new HashSet<>();
+ final Tags tagsAnnotation = cls.getAnnotation(Tags.class);
+ if (tagsAnnotation != null) {
+ for (final String tag : tagsAnnotation.value()) {
+ tags.add(tag);
+ }
+ }
+
+ return tags;
+ }
+
+ /**
+ * Gets the DocumentedTypeDTOs from the specified classes.
+ *
+ * @param classes
+ * @return
+ */
+ @SuppressWarnings("rawtypes")
+ public Set<DocumentedTypeDTO> fromDocumentedTypes(final Set<Class> classes) {
+ final Set<DocumentedTypeDTO> types = new LinkedHashSet<>();
+ final Set<Class> sortedClasses = new TreeSet<>(CLASS_NAME_COMPARATOR);
+ sortedClasses.addAll(classes);
+
+ for (final Class<?> cls : sortedClasses) {
+ final DocumentedTypeDTO type = new DocumentedTypeDTO();
+ type.setType(cls.getName());
+ type.setDescription(getCapabilityDescription(cls));
+ type.setTags(getTags(cls));
+ types.add(type);
+ }
+
+ return types;
+ }
++
++ /**
++ * Identifies all baseTypes for the specified type that are assignable to the specified baseType.
++ *
++ * @param baseType
++ * @param type
++ * @param baseTypes
++ */
++ private void identifyBaseTypes(final Class baseType, final Class type, final Set<Class> baseTypes, final boolean recurse) {
++ final Class[] interfaces = type.getInterfaces();
++ for (final Class i : interfaces) {
++ if (baseType.isAssignableFrom(i) && !baseType.equals(i)) {
++ baseTypes.add(i);
++ }
++ }
++
++ if (recurse) {
++ if (type.getSuperclass() != null) {
++ identifyBaseTypes(baseType, type.getSuperclass(), baseTypes, recurse);
++ }
++ }
++ }
++
++ /**
++ * Gets the DocumentedTypeDTOs from the specified classes for the specified baseClass.
++ *
++ * @param baseClass
++ * @param classes
++ * @return
++ */
++ public Set<DocumentedTypeDTO> fromDocumentedTypes(final Class baseClass, final Set<Class> classes) {
++ final Set<DocumentedTypeDTO> types = new LinkedHashSet<>();
++ final Set<Class> sortedClasses = new TreeSet<>(CLASS_NAME_COMPARATOR);
++ sortedClasses.addAll(classes);
++
++ // identify all interfaces that extend baseClass for all classes
++ final Set<Class> interfaces = new HashSet<>();
++ for (final Class<?> cls : sortedClasses) {
++ identifyBaseTypes(baseClass, cls, interfaces, true);
++ }
++
++ // build a lookup of all interfaces
++ final Map<Class, DocumentedTypeDTO> lookup = new HashMap<>();
++
++ // convert the interfaces to DTO form
++ for (final Class<?> i : interfaces) {
++ final DocumentedTypeDTO type = new DocumentedTypeDTO();
++ type.setType(i.getName());
++ type.setDescription(getCapabilityDescription(i));
++ type.setTags(getTags(i));
++ type.setChildTypes(new LinkedHashSet<DocumentedTypeDTO>());
++ lookup.put(i, type);
++ }
++
++ // move the interfaces into the appropriate hierarchy
++ for (final Class<?> i : interfaces) {
++ // identify the base types
++ final Set<Class> baseTypes = new LinkedHashSet<>();
++ identifyBaseTypes(baseClass, i, baseTypes, false);
++
++ // move this interfaces into the hierarchy where appropriate
++ if (!baseTypes.isEmpty()) {
++ // get the DTO for each base type
++ for (final Class baseType : baseTypes) {
++ final DocumentedTypeDTO parentInteface = lookup.get(baseType);
++ final DocumentedTypeDTO childInterface = lookup.get(i);
++
++ // include all parent tags in the respective children
++ childInterface.getTags().addAll(parentInteface.getTags());
++
++ // update the hierarchy
++ parentInteface.getChildTypes().add(childInterface);
++ }
++
++ // remove this interface from the lookup (this will only
++ // leave the interfaces that are ancestor roots)
++ lookup.remove(i);
++ }
++ }
++
++ // include the interfaces
++ sortedClasses.addAll(lookup.keySet());
++
++ // get the DTO form for all interfaces and classes
++ for (final Class<?> cls : sortedClasses) {
++ boolean add = false;
++
++ final DocumentedTypeDTO type;
++ if (lookup.containsKey(cls)) {
++ type = lookup.get(cls);
++ add = true;
++ } else {
++ type = new DocumentedTypeDTO();
++ type.setType(cls.getName());
++ type.setDescription(getCapabilityDescription(cls));
++ type.setTags(getTags(cls));
++ }
++
++ // identify the base types
++ final Set<Class> baseTypes = new LinkedHashSet<>();
++ identifyBaseTypes(baseClass, cls, baseTypes, false);
++
++ // include this type if it doesn't belong to another hierarchy
++ if (baseTypes.isEmpty()) {
++ add = true;
++ } else {
++ // get the DTO for each base type
++ for (final Class baseType : baseTypes) {
++ final DocumentedTypeDTO parentInteface = lookup.get(baseType);
++
++ // include all parent tags in the respective children
++ type.getTags().addAll(parentInteface.getTags());
++
++ // update the hierarchy
++ parentInteface.getChildTypes().add(type);
++ }
++ }
++
++ // add if appropriate
++ if (add) {
++ types.add(type);
++ }
++ }
++
++ return types;
++ }
+
+ /**
+ * Creates a ProcessorDTO from the specified ProcessorNode.
+ *
+ * @param node
+ * @return
+ */
+ public ProcessorDTO createProcessorDto(final ProcessorNode node) {
+ if (node == null) {
+ return null;
+ }
+
+ final ProcessorDTO dto = new ProcessorDTO();
+ dto.setId(node.getIdentifier());
+ dto.setPosition(createPositionDto(node.getPosition()));
+ dto.setStyle(node.getStyle());
+ dto.setParentGroupId(node.getProcessGroup().getIdentifier());
+
+ dto.setType(node.getProcessor().getClass().getCanonicalName());
+ dto.setName(node.getName());
+ dto.setState(node.getScheduledState().toString());
+
+ // build the relationship dtos
+ final List<RelationshipDTO> relationships = new ArrayList<>();
+ for (final Relationship rel : node.getRelationships()) {
+ final RelationshipDTO relationshipDTO = new RelationshipDTO();
+ relationshipDTO.setDescription(rel.getDescription());
+ relationshipDTO.setName(rel.getName());
+ relationshipDTO.setAutoTerminate(node.isAutoTerminated(rel));
+ relationships.add(relationshipDTO);
+ }
+
+ // sort the relationships
+ Collections.sort(relationships, new Comparator<RelationshipDTO>() {
+ @Override
+ public int compare(RelationshipDTO r1, RelationshipDTO r2) {
+ return Collator.getInstance(Locale.US).compare(r1.getName(), r2.getName());
+ }
+ });
+
+ // set the relationships
+ dto.setRelationships(relationships);
+
+ dto.setDescription(getCapabilityDescription(node.getClass()));
+ dto.setSupportsParallelProcessing(!node.isTriggeredSerially());
+ dto.setSupportsEventDriven(node.isEventDrivenSupported());
+ dto.setConfig(createProcessorConfigDto(node));
+
+ final Collection<ValidationResult> validationErrors = node.getValidationErrors();
+ if (validationErrors != null && !validationErrors.isEmpty()) {
+ final List<String> errors = new ArrayList<>();
+ for (final ValidationResult validationResult : validationErrors) {
+ errors.add(validationResult.toString());
+ }
+
+ dto.setValidationErrors(errors);
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a BulletinBoardDTO for the specified bulletins.
+ *
+ * @param bulletins
+ * @return
+ */
+ public BulletinBoardDTO createBulletinBoardDto(final List<BulletinDTO> bulletins) {
+ // sort the bulletins
+ Collections.sort(bulletins, new Comparator<BulletinDTO>() {
+ @Override
+ public int compare(BulletinDTO bulletin1, BulletinDTO bulletin2) {
+ if (bulletin1 == null && bulletin2 == null) {
+ return 0;
+ } else if (bulletin1 == null) {
+ return 1;
+ } else if (bulletin2 == null) {
+ return -1;
+ }
+
+ final Date timestamp1 = bulletin1.getTimestamp();
+ final Date timestamp2 = bulletin2.getTimestamp();
+ if (timestamp1 == null && timestamp2 == null) {
+ return 0;
+ } else if (timestamp1 == null) {
+ return 1;
+ } else if (timestamp2 == null) {
+ return -1;
+ } else {
+ return timestamp1.compareTo(timestamp2);
+ }
+ }
+ });
+
+ // create the bulletin board
+ final BulletinBoardDTO bulletinBoard = new BulletinBoardDTO();
+ bulletinBoard.setBulletins(bulletins);
+ bulletinBoard.setGenerated(new Date());
+ return bulletinBoard;
+ }
+
+ /**
+ * Creates a BulletinDTO for the specified Bulletin.
+ *
+ * @param bulletin
+ * @return
+ */
+ public BulletinDTO createBulletinDto(final Bulletin bulletin) {
+ final BulletinDTO dto = new BulletinDTO();
+ dto.setId(bulletin.getId());
+ dto.setNodeAddress(bulletin.getNodeAddress());
+ dto.setTimestamp(bulletin.getTimestamp());
+ dto.setGroupId(bulletin.getGroupId());
+ dto.setSourceId(bulletin.getSourceId());
+ dto.setSourceName(bulletin.getSourceName());
+ dto.setCategory(bulletin.getCategory());
+ dto.setLevel(bulletin.getLevel());
+ dto.setMessage(bulletin.getMessage());
+ return dto;
+ }
+
+ /**
+ * Creates a ProvenanceEventNodeDTO for the specified
+ * ProvenanceEventLineageNode.
+ *
+ * @param node
+ * @return
+ */
+ public ProvenanceNodeDTO createProvenanceEventNodeDTO(final ProvenanceEventLineageNode node) {
+ final ProvenanceNodeDTO dto = new ProvenanceNodeDTO();
+ dto.setId(node.getIdentifier());
+ dto.setType("EVENT");
+ dto.setEventType(node.getEventType().toString());
+ dto.setTimestamp(new Date(node.getTimestamp()));
+ dto.setMillis(node.getTimestamp());
+ dto.setFlowFileUuid(node.getFlowFileUuid());
+ dto.setParentUuids(node.getParentUuids());
+ dto.setChildUuids(node.getChildUuids());
+ dto.setClusterNodeIdentifier(node.getClusterNodeIdentifier());
+ return dto;
+ }
+
+ /**
+ * Creates a FlowFileNodeDTO for the specified LineageNode.
+ *
+ * @param node
+ * @return
+ */
+ public ProvenanceNodeDTO createFlowFileNodeDTO(final LineageNode node) {
+ final ProvenanceNodeDTO dto = new ProvenanceNodeDTO();
+ dto.setId(node.getIdentifier());
+ dto.setType("FLOWFILE");
+ dto.setTimestamp(new Date(node.getTimestamp()));
+ dto.setMillis(node.getTimestamp());
+ dto.setFlowFileUuid(node.getFlowFileUuid());
+ dto.setClusterNodeIdentifier(node.getClusterNodeIdentifier());
+ return dto;
+ }
+
+ /**
+ * Creates a ProvenanceLinkDTO for the specified LineageEdge.
+ *
+ * @param edge
+ * @return
+ */
+ public ProvenanceLinkDTO createProvenanceLinkDTO(final LineageEdge edge) {
+ final LineageNode source = edge.getSource();
+ final LineageNode target = edge.getDestination();
+
+ final ProvenanceLinkDTO dto = new ProvenanceLinkDTO();
+ dto.setTimestamp(new Date(target.getTimestamp()));
+ dto.setMillis(target.getTimestamp());
+ dto.setFlowFileUuid(edge.getUuid());
+ dto.setSourceId(source.getIdentifier());
+ dto.setTargetId(target.getIdentifier());
+ return dto;
+ }
+
+ /**
+ * Creates a LineageDTO for the specified Lineage.
+ *
+ * @param computeLineageSubmission
+ * @return
+ */
+ public LineageDTO createLineageDto(final ComputeLineageSubmission computeLineageSubmission) {
+ // build the lineage dto
+ final LineageDTO dto = new LineageDTO();
+ final LineageRequestDTO requestDto = new LineageRequestDTO();
+ final LineageResultsDTO resultsDto = new LineageResultsDTO();
+
+ // include the original request and results
+ dto.setRequest(requestDto);
+ dto.setResults(resultsDto);
+
+ // rebuild the request from the submission object
+ switch (computeLineageSubmission.getLineageComputationType()) {
+ case EXPAND_CHILDREN:
+ requestDto.setEventId(computeLineageSubmission.getExpandedEventId());
+ requestDto.setLineageRequestType(LineageRequestType.CHILDREN);
+ break;
+ case EXPAND_PARENTS:
+ requestDto.setEventId(computeLineageSubmission.getExpandedEventId());
+ requestDto.setLineageRequestType(LineageRequestType.PARENTS);
+ break;
+ case FLOWFILE_LINEAGE:
+ final Collection<String> uuids = computeLineageSubmission.getLineageFlowFileUuids();
+ if (uuids.size() == 1) {
+ requestDto.setUuid(uuids.iterator().next());
+ }
+ requestDto.setLineageRequestType(LineageRequestType.FLOWFILE);
+ break;
+ }
+
+ // include lineage details
+ dto.setId(computeLineageSubmission.getLineageIdentifier());
+ dto.setSubmissionTime(computeLineageSubmission.getSubmissionTime());
+
+ // create the results dto
+ final ComputeLineageResult results = computeLineageSubmission.getResult();
+ dto.setFinished(results.isFinished());
+ dto.setPercentCompleted(results.getPercentComplete());
+ dto.setExpiration(results.getExpiration());
+
+ final List<LineageNode> nodes = results.getNodes();
+ final List<LineageEdge> edges = results.getEdges();
+
+ final List<ProvenanceNodeDTO> nodeDtos = new ArrayList<>();
+ if (results.isFinished()) {
+ // create the node dto's
+ for (final LineageNode node : nodes) {
+ switch (node.getNodeType()) {
+ case FLOWFILE_NODE:
+ nodeDtos.add(createFlowFileNodeDTO(node));
+ break;
+ case PROVENANCE_EVENT_NODE:
+ nodeDtos.add(createProvenanceEventNodeDTO((ProvenanceEventLineageNode) node));
+ break;
+ }
+ }
+ }
+ resultsDto.setNodes(nodeDtos);
+
+ // include any errors
+ if (results.getError() != null) {
+ final Set<String> errors = new HashSet<>();
+ errors.add(results.getError());
+ resultsDto.setErrors(errors);
+ }
+
+ // create the link dto's
+ final List<ProvenanceLinkDTO> linkDtos = new ArrayList<>();
+ for (final LineageEdge edge : edges) {
+ linkDtos.add(createProvenanceLinkDTO(edge));
+ }
+ resultsDto.setLinks(linkDtos);
+
+ return dto;
+ }
+
+ /**
+ * Creates a SystemDiagnosticsDTO for the specified SystemDiagnostics.
+ *
+ * @param sysDiagnostics
+ * @return
+ */
+ public SystemDiagnosticsDTO createSystemDiagnosticsDto(final SystemDiagnostics sysDiagnostics) {
+
+ final SystemDiagnosticsDTO dto = new SystemDiagnosticsDTO();
+ dto.setStatsLastRefreshed(new Date(sysDiagnostics.getCreationTimestamp()));
+
+ // processors
+ dto.setAvailableProcessors(sysDiagnostics.getAvailableProcessors());
+ dto.setProcessorLoadAverage(sysDiagnostics.getProcessorLoadAverage());
+
+ // threads
+ dto.setDaemonThreads(sysDiagnostics.getDaemonThreads());
+ dto.setTotalThreads(sysDiagnostics.getTotalThreads());
+
+ // heap
+ dto.setMaxHeap(FormatUtils.formatDataSize(sysDiagnostics.getMaxHeap()));
+ dto.setTotalHeap(FormatUtils.formatDataSize(sysDiagnostics.getTotalHeap()));
+ dto.setUsedHeap(FormatUtils.formatDataSize(sysDiagnostics.getUsedHeap()));
+ dto.setFreeHeap(FormatUtils.formatDataSize(sysDiagnostics.getFreeHeap()));
+ dto.setHeapUtilization(FormatUtils.formatUtilization(sysDiagnostics.getHeapUtilization()));
+
+ // non heap
+ dto.setMaxNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getMaxNonHeap()));
+ dto.setTotalNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getTotalNonHeap()));
+ dto.setUsedNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getUsedNonHeap()));
+ dto.setFreeNonHeap(FormatUtils.formatDataSize(sysDiagnostics.getFreeNonHeap()));
+ dto.setNonHeapUtilization(FormatUtils.formatUtilization(sysDiagnostics.getNonHeapUtilization()));
+
+ // flow file disk usage
+ final SystemDiagnosticsDTO.StorageUsageDTO flowFileRepositoryStorageUsageDto = createStorageUsageDTO(null, sysDiagnostics.getFlowFileRepositoryStorageUsage());
+ dto.setFlowFileRepositoryStorageUsage(flowFileRepositoryStorageUsageDto);
+
+ // content disk usage
+ final Set<SystemDiagnosticsDTO.StorageUsageDTO> contentRepositoryStorageUsageDtos = new LinkedHashSet<>();
+ dto.setContentRepositoryStorageUsage(contentRepositoryStorageUsageDtos);
+ for (final Map.Entry<String, StorageUsage> entry : sysDiagnostics.getContentRepositoryStorageUsage().entrySet()) {
+ contentRepositoryStorageUsageDtos.add(createStorageUsageDTO(entry.getKey(), entry.getValue()));
+ }
+
+ // garbage collection
+ final Set<SystemDiagnosticsDTO.GarbageCollectionDTO> garbageCollectionDtos = new LinkedHashSet<>();
+ dto.setGarbageCollection(garbageCollectionDtos);
+ for (final Map.Entry<String, GarbageCollection> entry : sysDiagnostics.getGarbageCollection().entrySet()) {
+ garbageCollectionDtos.add(createGarbageCollectionDTO(entry.getKey(), entry.getValue()));
+ }
+
+ return dto;
+ }
+
+ /**
+ * Creates a StorageUsageDTO from the specified StorageUsage.
+ *
+ * @param identifier
+ * @param storageUsage
+ * @return
+ */
+ public SystemDiagnosticsDTO.StorageUsageDTO createStorageUsageDTO(final String identifier, final StorageUsage storageUsage) {
+ final SystemDiagnosticsDTO.StorageUsageDTO dto = new SystemDiagnosticsDTO.StorageUsageDTO();
+ dto.setIdentifier(identifier);
+ dto.setFreeSpace(FormatUtils.formatDataSize(storageUsage.getFreeSpace()));
+ dto.setTotalSpace(FormatUtils.formatDataSize(storageUsage.getTotalSpace()));
+ dto.setUsedSpace(FormatUtils.formatDataSize(storageUsage.getUsedSpace()));
+ dto.setFreeSpaceBytes(storageUsage.getFreeSpace());
+ dto.setTotalSpaceBytes(storageUsage.getTotalSpace());
+ dto.setUsedSpaceBytes(storageUsage.getUsedSpace());
+ dto.setUtilization(FormatUtils.formatUtilization(storageUsage.getDiskUtilization()));
+ return dto;
+ }
+
+ /**
+ * Creates a GarbageCollectionDTO from the specified GarbageCollection.
+ *
+ * @param name
+ * @param garbageCollection
+ * @return
+ */
+ public SystemDiagnosticsDTO.GarbageCollectionDTO createGarbageCollectionDTO(final String name, final GarbageCollection garbageCollection) {
+ final SystemDiagnosticsDTO.GarbageCollectionDTO dto = new SystemDiagnosticsDTO.GarbageCollectionDTO();
+ dto.setName(name);
+ dto.setCollectionCount(garbageCollection.getCollectionCount());
+ dto.setCollectionTime(FormatUtils.formatHoursMinutesSeconds(garbageCollection.getCollectionTime(), TimeUnit.MILLISECONDS));
+ return dto;
+ }
+
+ /**
+ * Creates a ProcessorConfigDTO from the specified ProcessorNode.
+ *
+ * @param procNode
+ * @return
+ */
+ public ProcessorConfigDTO createProcessorConfigDto(final ProcessorNode procNode) {
+ if (procNode == null) {
+ return null;
+ }
+
+ final ProcessorConfigDTO dto = new ProcessorConfigDTO();
+
+ // sort a copy of the properties
+ final Map<PropertyDescriptor, String> sortedProperties = new TreeMap<>(new Comparator<PropertyDescriptor>() {
+ @Override
+ public int compare(PropertyDescriptor o1, PropertyDescriptor o2) {
+ return Collator.getInstance(Locale.US).compare(o1.getName(), o2.getName());
+ }
+ });
+ sortedProperties.putAll(procNode.getProperties());
+
+ // get the property order from the processor
+ final Processor processor = procNode.getProcessor();
+ final Map<PropertyDescriptor, String> orderedProperties = new LinkedHashMap<>();
+ final List<PropertyDescriptor> descriptors = processor.getPropertyDescriptors();
+ if (descriptors != null && !descriptors.isEmpty()) {
+ for (PropertyDescriptor descriptor : descriptors) {
+ orderedProperties.put(descriptor, null);
+ }
+ }
+ orderedProperties.putAll(sortedProperties);
+
+ // build the descriptor and property dtos
+ dto.setDescriptors(new LinkedHashMap<String, PropertyDescriptorDTO>());
+ dto.setProperties(new LinkedHashMap<String, String>());
+ for (final Map.Entry<PropertyDescriptor, String> entry : orderedProperties.entrySet()) {
+ final PropertyDescriptor descriptor = entry.getKey();
+
+ // store the property descriptor
+ dto.getDescriptors().put(descriptor.getName(), createPropertyDescriptorDto(descriptor));
+
+ // determine the property value - don't include sensitive properties
+ String propertyValue = entry.getValue();
+ if (propertyValue != null && descriptor.isSensitive()) {
+ propertyValue = "********";
+ }
+
+ // set the property value
+ dto.getProperties().put(descriptor.getName(), propertyValue);
+ }
+
+ dto.setSchedulingPeriod(procNode.getSchedulingPeriod());
+ dto.setPenaltyDuration(procNode.getPenalizationPeriod());
+ dto.setYieldDuration(procNode.getYieldPeriod());
+ dto.setRunDurationMillis(procNode.getRunDuration(TimeUnit.MILLISECONDS));
+ dto.setConcurrentlySchedulableTaskCount(procNode.getMaxConcurrentTasks());
+ dto.setLossTolerant(procNode.isLossTolerant());
+ dto.setComments(procNode.getComments());
+ dto.setBulletinLevel(procNode.getBulletinLevel().name());
+ dto.setSchedulingStrategy(procNode.getSchedulingStrategy().name());
+ dto.setAnnotationData(procNode.getAnnotationData());
+
+ // set up the default values for concurrent tasks and scheduling period
+ final Map<String, String> defaultConcurrentTasks = new HashMap<>();
+ defaultConcurrentTasks.put(SchedulingStrategy.TIMER_DRIVEN.name(), String.valueOf(SchedulingStrategy.TIMER_DRIVEN.getDefaultConcurrentTasks()));
+ defaultConcurrentTasks.put(SchedulingStrategy.EVENT_DRIVEN.name(), String.valueOf(SchedulingStrategy.EVENT_DRIVEN.getDefaultConcurrentTasks()));
+ defaultConcurrentTasks.put(SchedulingStrategy.CRON_DRIVEN.name(), String.valueOf(SchedulingStrategy.CRON_DRIVEN.getDefaultConcurrentTasks()));
+ dto.setDefaultConcurrentTasks(defaultConcurrentTasks);
+
+ final Map<String, String> defaultSchedulingPeriod = new HashMap<>();
+ defaultSchedulingPeriod.put(SchedulingStrategy.TIMER_DRIVEN.name(), SchedulingStrategy.TIMER_DRIVEN.getDefaultSchedulingPeriod());
+ defaultSchedulingPeriod.put(SchedulingStrategy.CRON_DRIVEN.name(), SchedulingStrategy.CRON_DRIVEN.getDefaultSchedulingPeriod());
+ dto.setDefaultSchedulingPeriod(defaultSchedulingPeriod);
+
+ return dto;
+ }
+
+ /**
+ * Creates a PropertyDesriptorDTO from the specified PropertyDesriptor.
+ *
+ * @param propertyDescriptor
+ * @return
+ */
+ private ProcessorConfigDTO.PropertyDescriptorDTO createPropertyDescriptorDto(final PropertyDescriptor propertyDescriptor) {
+ if (propertyDescriptor == null) {
+ return null;
+ }
+
+ final ProcessorConfigDTO.PropertyDescriptorDTO dto = new ProcessorConfigDTO.PropertyDescriptorDTO();
+
+ dto.setName(propertyDescriptor.getName());
+ dto.setDisplayName(propertyDescriptor.getDisplayName());
+ dto.setRequired(propertyDescriptor.isRequired());
+ dto.setSensitive(propertyDescriptor.isSensitive());
+ dto.setDynamic(propertyDescriptor.isDynamic());
+ dto.setDescription(propertyDescriptor.getDescription());
+ dto.setDefaultValue(propertyDescriptor.getDefaultValue());
+ dto.setSupportsEl(propertyDescriptor.isExpressionLanguageSupported());
+
+ final Class<? extends ControllerService> serviceDefinition = propertyDescriptor.getControllerServiceDefinition();
+ if (propertyDescriptor.getAllowableValues() == null) {
+ if (serviceDefinition == null) {
+ dto.setAllowableValues(null);
+ } else {
+ final Set<AllowableValueDTO> allowableValues = new LinkedHashSet<>();
+ for (final String serviceIdentifier : controllerServiceLookup.getControllerServiceIdentifiers(serviceDefinition)) {
+ String displayName = serviceIdentifier;
+
+ // TODO: attempt to get the controller service name
+ final ControllerService controllerService = controllerServiceLookup.getControllerService(serviceIdentifier);
+
+ final AllowableValueDTO allowableValue = new AllowableValueDTO();
+ allowableValue.setDisplayName(displayName);
+ allowableValue.setValue(serviceIdentifier);
+ allowableValues.add(allowableValue);
+ }
+ dto.setAllowableValues(allowableValues);
+ }
+ } else {
+ final Set<AllowableValueDTO> allowableValues = new LinkedHashSet<>();
+ for (final AllowableValue allowableValue : propertyDescriptor.getAllowableValues()) {
+ final AllowableValueDTO allowableValueDto = new AllowableValueDTO();
+ allowableValueDto.setDisplayName(allowableValue.getDisplayName());
+ allowableValueDto.setValue(allowableValue.getValue());
+ allowableValueDto.setDescription(allowableValue.getDescription());
+ allowableValues.add(allowableValueDto);
+ }
+ dto.setAllowableValues(allowableValues);
+ }
+
+ return dto;
+ }
+
+ //
+ // Copy methods
+ //
+ public LabelDTO copy(final LabelDTO original) {
+ final LabelDTO copy = new LabelDTO();
+ copy.setId(original.getId());
+ copy.setParentGroupId(original.getParentGroupId());
+ copy.setLabel(original.getLabel());
+ copy.setStyle(copy(original.getStyle()));
+ copy.setPosition(original.getPosition());
+ copy.setWidth(original.getWidth());
+ copy.setHeight(original.getHeight());
+ copy.setUri(original.getUri());
+
+ return copy;
+ }
+
+ public FunnelDTO copy(final FunnelDTO original) {
+ final FunnelDTO copy = new FunnelDTO();
+ copy.setId(original.getId());
+ copy.setParentGroupId(original.getParentGroupId());
+ copy.setPosition(original.getPosition());
+ copy.setUri(original.getUri());
+
+ return copy;
+ }
+
+ private <T> List<T> copy(final List<T> original) {
+ if (original == null) {
+ return null;
+ } else {
+ return new ArrayList<>(original);
+ }
+ }
+
+ private <T> List<T> copy(final Collection<T> original) {
+ if (original == null) {
+ return null;
+ } else {
+ return new ArrayList<>(original);
+ }
+ }
+
+ private <T> Set<T> copy(final Set<T> original) {
+ if (original == null) {
+ return null;
+ } else {
+ return new LinkedHashSet<>(original);
+ }
+ }
+
+ private <S, T> Map<S, T> copy(final Map<S, T> original) {
+ if (original == null) {
+ return null;
+ } else {
+ return new LinkedHashMap<>(original);
+ }
+ }
+
+ public ProcessorDTO copy(final ProcessorDTO original) {
+ final ProcessorDTO copy = new ProcessorDTO();
+ copy.setConfig(copy(original.getConfig()));
+ copy.setPosition(original.getPosition());
+ copy.setId(original.getId());
+ copy.setName(original.getName());
+ copy.setDescription(original.getDescription());
+ copy.setParentGroupId(original.getParentGroupId());
+ copy.setRelationships(copy(original.getRelationships()));
+ copy.setState(original.getState());
+ copy.setStyle(copy(original.getStyle()));
+ copy.setType(original.getType());
+ copy.setUri(original.getUri());
+ copy.setSupportsParallelProcessing(original.getSupportsParallelProcessing());
+ copy.setSupportsEventDriven(original.getSupportsEventDriven());
+ copy.setValidationErrors(copy(original.getValidationErrors()));
+
+ return copy;
+ }
+
+ private ProcessorConfigDTO copy(final ProcessorConfigDTO original) {
+ final ProcessorConfigDTO copy = new ProcessorConfigDTO();
+ copy.setAnnotationData(original.getAnnotationData());
+ copy.setAutoTerminatedRelationships(copy(original.getAutoTerminatedRelationships()));
+ copy.setComments(original.getComments());
+ copy.setSchedulingStrategy(original.getSchedulingStrategy());
+ copy.setConcurrentlySchedulableTaskCount(original.getConcurrentlySchedulableTaskCount());
+ copy.setCustomUiUrl(original.getCustomUiUrl());
+ copy.setDescriptors(copy(original.getDescriptors()));
+ copy.setProperties(copy(original.getProperties()));
+ copy.setSchedulingPeriod(original.getSchedulingPeriod());
+ copy.setPenaltyDuration(original.getPenaltyDuration());
+ copy.setYieldDuration(original.getYieldDuration());
+ copy.setRunDurationMillis(original.getRunDurationMillis());
+ copy.setBulletinLevel(original.getBulletinLevel());
+ copy.setDefaultConcurrentTasks(original.getDefaultConcurrentTasks());
+ copy.setDefaultSchedulingPeriod(original.getDefaultSchedulingPeriod());
+ copy.setLossTolerant(original.isLossTolerant());
+
+ return copy;
+ }
+
+ public ConnectionDTO copy(final ConnectionDTO original) {
+ final ConnectionDTO copy = new ConnectionDTO();
+ copy.setAvailableRelationships(copy(original.getAvailableRelationships()));
+ copy.setDestination(original.getDestination());
+ copy.setPosition(original.getPosition());
+ copy.setId(original.getId());
+ copy.setName(original.getName());
+ copy.setParentGroupId(original.getParentGroupId());
+ copy.setSelectedRelationships(copy(original.getSelectedRelationships()));
+ copy.setFlowFileExpiration(original.getFlowFileExpiration());
+ copy.setBackPressureObjectThreshold(original.getBackPressureObjectThreshold());
+ copy.setBackPressureDataSizeThreshold(original.getBackPressureDataSizeThreshold());
+ copy.setPrioritizers(copy(original.getPrioritizers()));
+ copy.setSource(original.getSource());
+ copy.setUri(original.getUri());
+ copy.setzIndex(original.getzIndex());
+ copy.setLabelIndex(original.getLabelIndex());
+ copy.setBends(copy(original.getBends()));
+
+ return copy;
+ }
+
+ public BulletinDTO copy(final BulletinDTO original) {
+ final BulletinDTO copy = new BulletinDTO();
+ copy.setId(original.getId());
+ copy.setTimestamp(original.getTimestamp());
+ copy.setGroupId(original.getGroupId());
+ copy.setSourceId(original.getSourceId());
+ copy.setSourceName(original.getSourceName());
+ copy.setCategory(original.getCategory());
+ copy.setLevel(original.getLevel());
+ copy.setMessage(original.getMessage());
+ copy.setNodeAddress(original.getNodeAddress());
+ return copy;
+ }
+
+ public PortDTO copy(final PortDTO original) {
+ final PortDTO copy = new PortDTO();
+ copy.setPosition(original.getPosition());
+ copy.setId(original.getId());
+ copy.setName(original.getName());
+ copy.setComments(original.getComments());
+ copy.setParentGroupId(original.getParentGroupId());
+ copy.setUri(original.getUri());
+ copy.setState(original.getState());
+ copy.setType(original.getType());
+ copy.setTransmitting(original.isTransmitting());
+ copy.setConcurrentlySchedulableTaskCount(original.getConcurrentlySchedulableTaskCount());
+ copy.setUserAccessControl(copy(original.getUserAccessControl()));
+ copy.setGroupAccessControl(copy(original.getGroupAccessControl()));
+ copy.setValidationErrors(copy(original.getValidationErrors()));
+ return copy;
+ }
+
+ public RemoteProcessGroupPortDTO copy(final RemoteProcessGroupPortDTO original) {
+ final RemoteProcessGroupPortDTO copy = new RemoteProcessGroupPortDTO();
+ copy.setId(original.getId());
+ copy.setGroupId(original.getGroupId());
+ copy.setName(original.getName());
+ copy.setComments(original.getComments());
+ copy.setConnected(original.isConnected());
+ copy.setTargetRunning(original.isTargetRunning());
+ copy.setTransmitting(original.isTransmitting());
+ copy.setConcurrentlySchedulableTaskCount(original.getConcurrentlySchedulableTaskCount());
+ copy.setUseCompression(original.getUseCompression());
+ copy.setExists(original.getExists());
+ return copy;
+ }
+
+ public ProcessGroupDTO copy(final ProcessGroupDTO original, final boolean deep) {
+ final ProcessGroupDTO copy = new ProcessGroupDTO();
+ copy.setComments(original.getComments());
+ copy.setContents(copy(original.getContents(), deep));
+ copy.setPosition(original.getPosition());
+ copy.setId(original.getId());
+ copy.setInputPortCount(original.getInputPortCount());
+ copy.setInvalidCount(original.getInvalidCount());
+ copy.setName(original.getName());
+ copy.setOutputPortCount(original.getOutputPortCount());
+ copy.setParent(original.getParent());
+ copy.setParentGroupId(original.getParentGroupId());
+
+ copy.setRunning(original.isRunning());
+ copy.setRunningCount(original.getRunningCount());
+ copy.setStoppedCount(original.getStoppedCount());
+ copy.setDisabledCount(original.getDisabledCount());
+ copy.setActiveRemotePortCount(original.getActiveRemotePortCount());
+ copy.setInactiveRemotePortCount(original.getInactiveRemotePortCount());
+ copy.setUri(original.getUri());
+
+ return copy;
+ }
+
+ public RemoteProcessGroupDTO copy(final RemoteProcessGroupDTO original) {
+ final RemoteProcessGroupContentsDTO originalContents = original.getContents();
+ final RemoteProcessGroupContentsDTO copyContents = new RemoteProcessGroupContentsDTO();
+
+ if (originalContents.getInputPorts() != null) {
+ final Set<RemoteProcessGroupPortDTO> inputPorts = new HashSet<>();
+ for (final RemoteProcessGroupPortDTO port : originalContents.getInputPorts()) {
+ inputPorts.add(copy(port));
+ }
+ copyContents.setInputPorts(inputPorts);
+ }
+
+ if (originalContents.getOutputPorts() != null) {
+ final Set<RemoteProcessGroupPortDTO> outputPorts = new HashSet<>();
+ for (final RemoteProcessGroupPortDTO port : originalContents.getOutputPorts()) {
+ outputPorts.add(copy(port));
+ }
+ copyContents.setOutputPorts(outputPorts);
+ }
+
+ final RemoteProcessGroupDTO copy = new RemoteProcessGroupDTO();
+ copy.setComments(original.getComments());
+ copy.setPosition(original.getPosition());
+ copy.setId(original.getId());
+ copy.setCommunicationsTimeout(original.getCommunicationsTimeout());
+ copy.setYieldDuration(original.getYieldDuration());
+ copy.setName(original.getName());
+ copy.setInputPortCount(original.getInputPortCount());
+ copy.setOutputPortCount(original.getOutputPortCount());
+ copy.setActiveRemoteInputPortCount(original.getActiveRemoteInputPortCount());
+ copy.setInactiveRemoteInputPortCount(original.getInactiveRemoteInputPortCount());
+ copy.setActiveRemoteOutputPortCount(original.getActiveRemoteOutputPortCount());
+ copy.setInactiveRemoteOutputPortCount(original.getInactiveRemoteOutputPortCount());
+ copy.setParentGroupId(original.getParentGroupId());
+ copy.setTargetUri(original.getTargetUri());
+ copy.setUri(original.getUri());
+
+ copy.setContents(copyContents);
+
+ return copy;
+ }
+
+ public Connect
<TRUNCATED>