mirror of https://github.com/apache/nifi.git
NIFI-1800:
- UI style updates to make the components stand out better. - Reusing controller service table in different contexts (controller, process group, etc). - This closes #469
This commit is contained in:
parent
ae3012a992
commit
9152a9fdbb
|
@ -17,10 +17,11 @@
|
|||
package org.apache.nifi.web.api.dto;
|
||||
|
||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import java.util.Date;
|
||||
import org.apache.nifi.web.api.dto.util.TimeAdapter;
|
||||
|
||||
import javax.xml.bind.annotation.XmlType;
|
||||
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
||||
import org.apache.nifi.web.api.dto.util.TimeAdapter;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Details for the controller configuration.
|
||||
|
@ -28,13 +29,10 @@ import org.apache.nifi.web.api.dto.util.TimeAdapter;
|
|||
@XmlType(name = "config")
|
||||
public class ControllerConfigurationDTO {
|
||||
|
||||
private String name;
|
||||
private String comments;
|
||||
private Integer maxTimerDrivenThreadCount;
|
||||
private Integer maxEventDrivenThreadCount;
|
||||
|
||||
private Long autoRefreshIntervalSeconds;
|
||||
private Boolean siteToSiteSecure;
|
||||
|
||||
private Date currentTime;
|
||||
private Integer timeOffset;
|
||||
|
@ -67,34 +65,6 @@ public class ControllerConfigurationDTO {
|
|||
this.maxEventDrivenThreadCount = maxEventDrivenThreadCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return name of this NiFi
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The name of this NiFi."
|
||||
)
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return comments for this NiFi
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The comments for this NiFi."
|
||||
)
|
||||
public String getComments() {
|
||||
return comments;
|
||||
}
|
||||
|
||||
public void setComments(String comments) {
|
||||
this.comments = comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return interval in seconds between the automatic NiFi refresh requests. This value is read only
|
||||
*/
|
||||
|
@ -110,21 +80,6 @@ public class ControllerConfigurationDTO {
|
|||
this.autoRefreshIntervalSeconds = autoRefreshIntervalSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Indicates whether or not Site-to-Site communications with this instance is secure (2-way authentication). This value is read only
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "Indicates whether site to site communication with the NiFi is secure (requires 2-way authenticiation).",
|
||||
readOnly = true
|
||||
)
|
||||
public Boolean isSiteToSiteSecure() {
|
||||
return siteToSiteSecure;
|
||||
}
|
||||
|
||||
public void setSiteToSiteSecure(Boolean siteToSiteSecure) {
|
||||
this.siteToSiteSecure = siteToSiteSecure;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return current time on the server
|
||||
*/
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
package org.apache.nifi.web.api.entity;
|
||||
|
||||
import com.wordnik.swagger.annotations.ApiModelProperty;
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
||||
import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
|
||||
|
@ -26,10 +27,11 @@ import javax.xml.bind.annotation.XmlRootElement;
|
|||
* A serialized representation of this class can be placed in the entity body of a request or response to or from the API. This particular entity holds a reference to a ControllerConfigurationDTO.
|
||||
*/
|
||||
@XmlRootElement(name = "controllerConfigurationEntity")
|
||||
public class ControllerConfigurationEntity extends ComponentEntity {
|
||||
public class ControllerConfigurationEntity extends Entity {
|
||||
|
||||
private ControllerConfigurationDTO config;
|
||||
private RevisionDTO revision;
|
||||
private AccessPolicyDTO accessPolicy;
|
||||
|
||||
/**
|
||||
* @return revision for this request/response
|
||||
|
@ -65,4 +67,19 @@ public class ControllerConfigurationEntity extends ComponentEntity {
|
|||
this.config = config;
|
||||
}
|
||||
|
||||
/**
|
||||
* The access policy for this component.
|
||||
*
|
||||
* @return The access policy
|
||||
*/
|
||||
@ApiModelProperty(
|
||||
value = "The access policy for the controller."
|
||||
)
|
||||
public AccessPolicyDTO getAccessPolicy() {
|
||||
return accessPolicy;
|
||||
}
|
||||
|
||||
public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
|
||||
this.accessPolicy = accessPolicy;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,9 +16,6 @@
|
|||
*/
|
||||
package org.apache.nifi.audit;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import org.apache.nifi.action.Action;
|
||||
import org.apache.nifi.action.Component;
|
||||
import org.apache.nifi.action.FlowChangeAction;
|
||||
|
@ -33,6 +30,10 @@ import org.aspectj.lang.annotation.Aspect;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Audits configuration changes to the controller.
|
||||
*/
|
||||
|
@ -41,112 +42,6 @@ public class ControllerAuditor extends NiFiAuditor {
|
|||
|
||||
private static final Logger logger = LoggerFactory.getLogger(ControllerAuditor.class);
|
||||
|
||||
/**
|
||||
* Audits updating the name of the controller.
|
||||
*
|
||||
* @param proceedingJoinPoint join point
|
||||
* @param name name
|
||||
* @param controllerFacade facade
|
||||
* @throws java.lang.Throwable ex
|
||||
*/
|
||||
@Around("within(org.apache.nifi.web.controller.ControllerFacade) && "
|
||||
+ "execution(void setName(java.lang.String)) && "
|
||||
+ "args(name) && "
|
||||
+ "target(controllerFacade)")
|
||||
public void updateControllerNameAdvice(ProceedingJoinPoint proceedingJoinPoint, String name, ControllerFacade controllerFacade) throws Throwable {
|
||||
// get the previous name
|
||||
String previousName = controllerFacade.getName();
|
||||
|
||||
// update the configuraion
|
||||
proceedingJoinPoint.proceed();
|
||||
|
||||
// if no exception were thrown, add the configuration action...
|
||||
// ensure the name changed
|
||||
if (!name.equals(previousName)) {
|
||||
// get the current user
|
||||
NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
|
||||
// ensure the user was found
|
||||
if (user != null) {
|
||||
Collection<Action> actions = new ArrayList<>();
|
||||
|
||||
// create the configuration details
|
||||
FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
|
||||
configDetails.setName("Controller Name");
|
||||
configDetails.setValue(name);
|
||||
configDetails.setPreviousValue(previousName);
|
||||
|
||||
// create the config action
|
||||
FlowChangeAction configAction = new FlowChangeAction();
|
||||
configAction.setUserIdentity(user.getIdentity());
|
||||
configAction.setUserName(user.getUserName());
|
||||
configAction.setOperation(Operation.Configure);
|
||||
configAction.setTimestamp(new Date());
|
||||
configAction.setSourceId("Flow Controller");
|
||||
configAction.setSourceName(controllerFacade.getName());
|
||||
configAction.setSourceType(Component.Controller);
|
||||
configAction.setActionDetails(configDetails);
|
||||
actions.add(configAction);
|
||||
|
||||
// record the action
|
||||
saveActions(actions, logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Audits updating the comments of the controller.
|
||||
*
|
||||
* @param proceedingJoinPoint join point
|
||||
* @param comments comments
|
||||
* @param controllerFacade facade
|
||||
* @throws java.lang.Throwable ex
|
||||
*/
|
||||
@Around("within(org.apache.nifi.web.controller.ControllerFacade) && "
|
||||
+ "execution(void setComments(java.lang.String)) && "
|
||||
+ "args(comments) && "
|
||||
+ "target(controllerFacade)")
|
||||
public void updateControllerCommentsAdvice(ProceedingJoinPoint proceedingJoinPoint, String comments, ControllerFacade controllerFacade) throws Throwable {
|
||||
// get the previous name
|
||||
String previousComments = controllerFacade.getComments();
|
||||
|
||||
// update the configuraion
|
||||
proceedingJoinPoint.proceed();
|
||||
|
||||
// if no exception were thrown, add the configuration action...
|
||||
// ensure the name changed
|
||||
if (!comments.equals(previousComments)) {
|
||||
// get the current user
|
||||
NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
|
||||
// ensure the user was found
|
||||
if (user != null) {
|
||||
Collection<Action> actions = new ArrayList<>();
|
||||
|
||||
// create the configuration details
|
||||
FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
|
||||
configDetails.setName("Controller Comments");
|
||||
configDetails.setValue(comments);
|
||||
configDetails.setPreviousValue(previousComments);
|
||||
|
||||
// create the config action
|
||||
FlowChangeAction configAction = new FlowChangeAction();
|
||||
configAction.setUserIdentity(user.getIdentity());
|
||||
configAction.setUserName(user.getUserName());
|
||||
configAction.setOperation(Operation.Configure);
|
||||
configAction.setTimestamp(new Date());
|
||||
configAction.setSourceId("Flow Controller");
|
||||
configAction.setSourceName(controllerFacade.getName());
|
||||
configAction.setSourceType(Component.Controller);
|
||||
configAction.setActionDetails(configDetails);
|
||||
actions.add(configAction);
|
||||
|
||||
// record the action
|
||||
saveActions(actions, logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Audits updating the max number of timer driven threads for the controller.
|
||||
*
|
||||
|
@ -189,7 +84,7 @@ public class ControllerAuditor extends NiFiAuditor {
|
|||
configAction.setOperation(Operation.Configure);
|
||||
configAction.setTimestamp(new Date());
|
||||
configAction.setSourceId("Flow Controller");
|
||||
configAction.setSourceName(controllerFacade.getName());
|
||||
configAction.setSourceName("Flow Controller");
|
||||
configAction.setSourceType(Component.Controller);
|
||||
configAction.setActionDetails(configDetails);
|
||||
actions.add(configAction);
|
||||
|
@ -242,7 +137,7 @@ public class ControllerAuditor extends NiFiAuditor {
|
|||
configAction.setOperation(Operation.Configure);
|
||||
configAction.setTimestamp(new Date());
|
||||
configAction.setSourceId("Flow Controller");
|
||||
configAction.setSourceName(controllerFacade.getName());
|
||||
configAction.setSourceName("Flow Controller");
|
||||
configAction.setSourceType(Component.Controller);
|
||||
configAction.setActionDetails(configDetails);
|
||||
actions.add(configAction);
|
||||
|
|
|
@ -66,6 +66,7 @@ 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.StatusHistoryDTO;
|
||||
import org.apache.nifi.web.api.entity.ConnectionEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
|
||||
import org.apache.nifi.web.api.entity.FlowEntity;
|
||||
|
@ -262,7 +263,7 @@ public interface NiFiServiceFacade {
|
|||
*
|
||||
* @return Controller configuration transfer object
|
||||
*/
|
||||
ControllerConfigurationDTO getControllerConfiguration();
|
||||
ControllerConfigurationEntity getControllerConfiguration();
|
||||
|
||||
/**
|
||||
* Updates the configuration for this controller.
|
||||
|
@ -271,7 +272,7 @@ public interface NiFiServiceFacade {
|
|||
* @param controllerConfigurationDTO Controller configuration DTO
|
||||
* @return Controller configuration DTO
|
||||
*/
|
||||
ConfigurationSnapshot<ControllerConfigurationDTO> updateControllerConfiguration(Revision revision, ControllerConfigurationDTO controllerConfigurationDTO);
|
||||
ControllerConfigurationEntity updateControllerConfiguration(Revision revision, ControllerConfigurationDTO controllerConfigurationDTO);
|
||||
|
||||
/**
|
||||
* Creates a new archive of the flow configuration.
|
||||
|
|
|
@ -45,6 +45,7 @@ import org.apache.nifi.connectable.Funnel;
|
|||
import org.apache.nifi.connectable.Port;
|
||||
import org.apache.nifi.controller.ConfiguredComponent;
|
||||
import org.apache.nifi.controller.Counter;
|
||||
import org.apache.nifi.controller.FlowController;
|
||||
import org.apache.nifi.controller.ProcessorNode;
|
||||
import org.apache.nifi.controller.ReportingTaskNode;
|
||||
import org.apache.nifi.controller.ScheduledState;
|
||||
|
@ -67,7 +68,6 @@ import org.apache.nifi.remote.RootGroupPort;
|
|||
import org.apache.nifi.reporting.Bulletin;
|
||||
import org.apache.nifi.reporting.BulletinQuery;
|
||||
import org.apache.nifi.reporting.BulletinRepository;
|
||||
import org.apache.nifi.util.FormatUtils;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
|
||||
import org.apache.nifi.web.api.dto.BulletinBoardDTO;
|
||||
|
@ -127,6 +127,7 @@ 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.StatusHistoryDTO;
|
||||
import org.apache.nifi.web.api.entity.ConnectionEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity;
|
||||
|
@ -183,9 +184,7 @@ import java.util.ListIterator;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
@ -886,32 +885,25 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ConfigurationSnapshot<ControllerConfigurationDTO> updateControllerConfiguration(final Revision revision, final ControllerConfigurationDTO controllerConfigurationDTO) {
|
||||
final Supplier<ControllerConfigurationDTO> daoUpdate = () -> {
|
||||
// update the controller configuration through the proxy
|
||||
if (controllerConfigurationDTO.getName() != null) {
|
||||
controllerFacade.setName(controllerConfigurationDTO.getName());
|
||||
}
|
||||
if (controllerConfigurationDTO.getComments() != null) {
|
||||
controllerFacade.setComments(controllerConfigurationDTO.getComments());
|
||||
}
|
||||
if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount());
|
||||
}
|
||||
if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
|
||||
}
|
||||
|
||||
return controllerConfigurationDTO;
|
||||
};
|
||||
|
||||
public ControllerConfigurationEntity updateControllerConfiguration(final Revision revision, final ControllerConfigurationDTO controllerConfigurationDTO) {
|
||||
final RevisionUpdate<ControllerConfigurationDTO> updatedComponent = updateComponent(
|
||||
revision,
|
||||
controllerFacade,
|
||||
daoUpdate,
|
||||
controller -> getControllerConfiguration());
|
||||
() -> {
|
||||
if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount());
|
||||
}
|
||||
if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() != null) {
|
||||
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
|
||||
}
|
||||
|
||||
return new ConfigurationSnapshot<>(updatedComponent.getLastModification().getRevision().getVersion());
|
||||
return controllerConfigurationDTO;
|
||||
},
|
||||
controller -> dtoFactory.createControllerConfigurationDto(controllerFacade, properties.getAutoRefreshInterval()));
|
||||
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
|
||||
final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(updatedComponent.getLastModification());
|
||||
return entityFactory.createControllerConfigurationEntity(updatedComponent.getComponent(), updateRevision, accessPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1266,9 +1258,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
*
|
||||
* @return a RevisionUpdate that represents the updated configuration
|
||||
*/
|
||||
private <D, C> RevisionUpdate<D> createComponent(final ComponentDTO componentDto,
|
||||
final Supplier<C> daoCreation, final Function<C, D> dtoCreation) {
|
||||
|
||||
private <D, C> RevisionUpdate<D> createComponent(final ComponentDTO componentDto, final Supplier<C> daoCreation, final Function<C, D> dtoCreation) {
|
||||
final String modifier = NiFiUserUtils.getNiFiUserName();
|
||||
|
||||
// ensure id is set
|
||||
|
@ -1638,6 +1628,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
|
||||
@Override
|
||||
public ControllerServiceEntity createControllerService(final String groupId, final ControllerServiceDTO controllerServiceDTO) {
|
||||
final String normalizedGroupId = groupId == null ? controllerFacade.getRootGroupId() : groupId;
|
||||
controllerServiceDTO.setParentGroupId(normalizedGroupId);
|
||||
|
||||
final RevisionUpdate<ControllerServiceDTO> snapshot = createComponent(
|
||||
controllerServiceDTO,
|
||||
() -> {
|
||||
|
@ -1645,7 +1638,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
final ControllerServiceNode controllerService = controllerServiceDAO.createControllerService(controllerServiceDTO);
|
||||
|
||||
// TODO - this logic should be part of the controllerServiceDAO
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(normalizedGroupId);
|
||||
group.addControllerService(controllerService);
|
||||
return controllerService;
|
||||
},
|
||||
|
@ -2350,8 +2343,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
final ControllerDTO controllerDTO = new ControllerDTO();
|
||||
controllerDTO.setId(controllerFacade.getRootGroupId());
|
||||
controllerDTO.setInstanceId(controllerFacade.getInstanceId());
|
||||
controllerDTO.setName(controllerFacade.getName());
|
||||
controllerDTO.setComments(controllerFacade.getComments());
|
||||
controllerDTO.setInputPorts(inputPortDtos);
|
||||
controllerDTO.setOutputPorts(outputPortDtos);
|
||||
controllerDTO.setInputPortCount(inputPorts.size());
|
||||
|
@ -2374,29 +2365,13 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ControllerConfigurationDTO getControllerConfiguration() {
|
||||
ControllerConfigurationDTO controllerConfig = new ControllerConfigurationDTO();
|
||||
controllerConfig.setName(controllerFacade.getName());
|
||||
controllerConfig.setComments(controllerFacade.getComments());
|
||||
controllerConfig.setMaxTimerDrivenThreadCount(controllerFacade.getMaxTimerDrivenThreadCount());
|
||||
controllerConfig.setMaxEventDrivenThreadCount(controllerFacade.getMaxEventDrivenThreadCount());
|
||||
|
||||
// get the refresh interval
|
||||
final long refreshInterval = FormatUtils.getTimeDuration(properties.getAutoRefreshInterval(), TimeUnit.SECONDS);
|
||||
controllerConfig.setAutoRefreshIntervalSeconds(refreshInterval);
|
||||
|
||||
final Date now = new Date();
|
||||
controllerConfig.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime()));
|
||||
controllerConfig.setCurrentTime(now);
|
||||
|
||||
// determine the site to site configuration
|
||||
if (isClustered()) {
|
||||
controllerConfig.setSiteToSiteSecure(controllerFacade.isClusterManagerRemoteSiteCommsSecure());
|
||||
} else {
|
||||
controllerConfig.setSiteToSiteSecure(controllerFacade.isRemoteSiteCommsSecure());
|
||||
}
|
||||
|
||||
return controllerConfig;
|
||||
public ControllerConfigurationEntity getControllerConfiguration() {
|
||||
return revisionManager.get(FlowController.class.getSimpleName(), rev -> {
|
||||
final ControllerConfigurationDTO dto = dtoFactory.createControllerConfigurationDto(controllerFacade, properties.getAutoRefreshInterval());
|
||||
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
|
||||
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
|
||||
return entityFactory.createControllerConfigurationEntity(dto, revision, accessPolicy);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -2656,9 +2631,18 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
|
|||
@Override
|
||||
public Set<ControllerServiceEntity> getControllerServices(String groupId) {
|
||||
// TODO - move this logic into the ControllerServiceDAO
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
|
||||
final Set<ControllerServiceNode> serviceNodes = group.getControllerServices(true);
|
||||
final Set<String> serviceIds = serviceNodes.stream().map(service -> service.getIdentifier()).collect(Collectors.toSet());
|
||||
|
||||
final Set<ControllerServiceNode> serviceNodes;
|
||||
final Set<String> serviceIds;
|
||||
if (groupId == null) {
|
||||
// TODO - controller services scoped by the controller
|
||||
serviceNodes = controllerServiceDAO.getControllerServices();
|
||||
serviceIds = serviceNodes.stream().map(service -> service.getIdentifier()).collect(Collectors.toSet());
|
||||
} else {
|
||||
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
|
||||
serviceNodes = group.getControllerServices(true);
|
||||
serviceIds = serviceNodes.stream().map(service -> service.getIdentifier()).collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
return revisionManager.get(serviceIds, () -> {
|
||||
return serviceNodes.stream()
|
||||
|
|
|
@ -16,10 +16,43 @@
|
|||
*/
|
||||
package org.apache.nifi.web.api;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import com.sun.jersey.api.core.ResourceContext;
|
||||
import com.wordnik.swagger.annotations.Api;
|
||||
import com.wordnik.swagger.annotations.ApiOperation;
|
||||
import com.wordnik.swagger.annotations.ApiParam;
|
||||
import com.wordnik.swagger.annotations.ApiResponse;
|
||||
import com.wordnik.swagger.annotations.ApiResponses;
|
||||
import com.wordnik.swagger.annotations.Authorization;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.AccessDeniedException;
|
||||
import org.apache.nifi.authorization.AuthorizationRequest;
|
||||
import org.apache.nifi.authorization.AuthorizationResult;
|
||||
import org.apache.nifi.authorization.AuthorizationResult.Result;
|
||||
import org.apache.nifi.authorization.Authorizer;
|
||||
import org.apache.nifi.authorization.RequestAction;
|
||||
import org.apache.nifi.authorization.resource.ResourceFactory;
|
||||
import org.apache.nifi.authorization.user.NiFiUser;
|
||||
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
||||
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
|
||||
import org.apache.nifi.cluster.manager.NodeResponse;
|
||||
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
|
||||
import org.apache.nifi.cluster.manager.impl.WebClusterManager;
|
||||
import org.apache.nifi.cluster.node.Node;
|
||||
import org.apache.nifi.cluster.protocol.NodeIdentifier;
|
||||
import org.apache.nifi.controller.FlowController;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.NiFiServiceFacade;
|
||||
import org.apache.nifi.web.Revision;
|
||||
import org.apache.nifi.web.api.dto.CounterDTO;
|
||||
import org.apache.nifi.web.api.dto.CountersDTO;
|
||||
import org.apache.nifi.web.api.entity.AuthorityEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
import org.apache.nifi.web.api.entity.CounterEntity;
|
||||
import org.apache.nifi.web.api.entity.CountersEntity;
|
||||
import org.apache.nifi.web.api.entity.Entity;
|
||||
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.ws.rs.Consumes;
|
||||
|
@ -36,41 +69,10 @@ import javax.ws.rs.WebApplicationException;
|
|||
import javax.ws.rs.core.Context;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.nifi.authorization.user.NiFiUser;
|
||||
import org.apache.nifi.authorization.user.NiFiUserUtils;
|
||||
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
|
||||
import org.apache.nifi.cluster.manager.NodeResponse;
|
||||
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
|
||||
import org.apache.nifi.cluster.manager.impl.WebClusterManager;
|
||||
import org.apache.nifi.cluster.node.Node;
|
||||
import org.apache.nifi.cluster.protocol.NodeIdentifier;
|
||||
import org.apache.nifi.util.NiFiProperties;
|
||||
import org.apache.nifi.web.ConfigurationSnapshot;
|
||||
import org.apache.nifi.web.NiFiServiceFacade;
|
||||
import org.apache.nifi.web.Revision;
|
||||
import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
|
||||
import org.apache.nifi.web.api.dto.CounterDTO;
|
||||
import org.apache.nifi.web.api.dto.CountersDTO;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
import org.apache.nifi.web.api.entity.AuthorityEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.CounterEntity;
|
||||
import org.apache.nifi.web.api.entity.CountersEntity;
|
||||
import org.apache.nifi.web.api.entity.Entity;
|
||||
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTasksEntity;
|
||||
import org.apache.nifi.web.api.request.ClientIdParameter;
|
||||
|
||||
import com.sun.jersey.api.core.ResourceContext;
|
||||
import com.wordnik.swagger.annotations.Api;
|
||||
import com.wordnik.swagger.annotations.ApiOperation;
|
||||
import com.wordnik.swagger.annotations.ApiParam;
|
||||
import com.wordnik.swagger.annotations.ApiResponse;
|
||||
import com.wordnik.swagger.annotations.ApiResponses;
|
||||
import com.wordnik.swagger.annotations.Authorization;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* RESTful endpoint for managing a Flow Controller.
|
||||
|
@ -85,12 +87,35 @@ public class ControllerResource extends ApplicationResource {
|
|||
private NiFiServiceFacade serviceFacade;
|
||||
private WebClusterManager clusterManager;
|
||||
private NiFiProperties properties;
|
||||
private Authorizer authorizer;
|
||||
|
||||
private ReportingTaskResource reportingTaskResource;
|
||||
private ControllerServiceResource controllerServiceResource;
|
||||
|
||||
@Context
|
||||
private ResourceContext resourceContext;
|
||||
|
||||
/**
|
||||
* Authorizes access to the flow.
|
||||
*/
|
||||
private void authorizeController(final RequestAction action) {
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
|
||||
final AuthorizationRequest request = new AuthorizationRequest.Builder()
|
||||
.resource(ResourceFactory.getControllerResource())
|
||||
.identity(user.getIdentity())
|
||||
.anonymous(user.isAnonymous())
|
||||
.accessAttempt(true)
|
||||
.action(action)
|
||||
.build();
|
||||
|
||||
final AuthorizationResult result = authorizer.authorize(request);
|
||||
if (!Result.Approved.equals(result.getResult())) {
|
||||
final String message = StringUtils.isNotBlank(result.getExplanation()) ? result.getExplanation() : "Access is denied";
|
||||
throw new AccessDeniedException(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new archive of this flow controller. Note, this is a POST operation that returns a URI that is not representative of the thing that was actually created. The archive that is created
|
||||
* cannot be referenced at a later time, therefore there is no corresponding URI. Instead the request URI is returned.
|
||||
|
@ -311,19 +336,15 @@ public class ControllerResource extends ApplicationResource {
|
|||
}
|
||||
)
|
||||
public Response getControllerConfig() {
|
||||
// TODO
|
||||
// authorizeController(RequestAction.READ);
|
||||
|
||||
// replicate if cluster manager
|
||||
if (properties.isClusterManager()) {
|
||||
return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
|
||||
}
|
||||
|
||||
final ControllerConfigurationDTO controllerConfig = serviceFacade.getControllerConfiguration();
|
||||
|
||||
// create the response entity
|
||||
final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
|
||||
entity.setConfig(controllerConfig);
|
||||
|
||||
// generate the response
|
||||
final ControllerConfigurationEntity entity = serviceFacade.getControllerConfiguration();
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
|
@ -374,31 +395,19 @@ public class ControllerResource extends ApplicationResource {
|
|||
return clusterManager.applyRequest(HttpMethod.PUT, getAbsolutePath(), configEntity, getHeaders()).getResponse();
|
||||
}
|
||||
|
||||
final RevisionDTO revisionDto = configEntity.getRevision();
|
||||
final Revision revision = new Revision(revisionDto.getVersion(), revisionDto.getClientId(), "controller");
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
|
||||
if (expects != null) {
|
||||
return generateContinueResponse().build();
|
||||
}
|
||||
|
||||
final ConfigurationSnapshot<ControllerConfigurationDTO> controllerResponse
|
||||
= serviceFacade.updateControllerConfiguration(revision, configEntity.getConfig());
|
||||
final ControllerConfigurationDTO controllerConfig = controllerResponse.getConfiguration();
|
||||
|
||||
// get the updated revision
|
||||
final RevisionDTO updatedRevision = new RevisionDTO();
|
||||
updatedRevision.setClientId(revision.getClientId());
|
||||
updatedRevision.setVersion(controllerResponse.getVersion());
|
||||
|
||||
// create the response entity
|
||||
final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
|
||||
entity.setRevision(updatedRevision);
|
||||
entity.setConfig(controllerConfig);
|
||||
|
||||
// generate the response
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
final Revision revision = getRevision(configEntity.getRevision(), FlowController.class.getSimpleName());
|
||||
return withWriteLock(
|
||||
serviceFacade,
|
||||
revision,
|
||||
lookup -> {
|
||||
authorizeController(RequestAction.WRITE);
|
||||
},
|
||||
null,
|
||||
() -> {
|
||||
final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getConfig());
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**x
|
||||
|
@ -519,26 +528,27 @@ public class ControllerResource extends ApplicationResource {
|
|||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
}
|
||||
|
||||
// -------------------
|
||||
// controller services
|
||||
// -------------------
|
||||
|
||||
/**
|
||||
* Retrieves all the of reporting tasks in this NiFi.
|
||||
* Creates a new Controller Service.
|
||||
*
|
||||
* @param clientId Optional client id. If the client id is not specified, a
|
||||
* new one will be generated. This value (whether specified or generated) is
|
||||
* included in the response.
|
||||
* @return A reportingTasksEntity.
|
||||
* @param httpServletRequest request
|
||||
* @param controllerServiceEntity A controllerServiceEntity.
|
||||
* @return A controllerServiceEntity.
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@POST
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("reporting-tasks")
|
||||
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
|
||||
@Path("controller-services")
|
||||
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
|
||||
@ApiOperation(
|
||||
value = "Gets all reporting tasks",
|
||||
response = ReportingTasksEntity.class,
|
||||
value = "Creates a new controller service",
|
||||
response = ControllerServiceEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
|
||||
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
|
@ -549,28 +559,50 @@ public class ControllerResource extends ApplicationResource {
|
|||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getReportingTasks(
|
||||
public Response createControllerService(
|
||||
@Context final HttpServletRequest httpServletRequest,
|
||||
@ApiParam(
|
||||
value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
|
||||
value = "The controller service configuration details.",
|
||||
required = true
|
||||
) final ControllerServiceEntity controllerServiceEntity) {
|
||||
|
||||
// replicate if cluster manager
|
||||
if (properties.isClusterManager()) {
|
||||
return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
|
||||
if (controllerServiceEntity == null || controllerServiceEntity.getComponent() == null) {
|
||||
throw new IllegalArgumentException("Controller service details must be specified.");
|
||||
}
|
||||
|
||||
// get all the reporting tasks
|
||||
final Set<ReportingTaskEntity> reportingTasks = serviceFacade.getReportingTasks();
|
||||
reportingTaskResource.populateRemainingReportingTaskEntitiesContent(reportingTasks);
|
||||
if (controllerServiceEntity.getComponent().getId() != null) {
|
||||
throw new IllegalArgumentException("Controller service ID cannot be specified.");
|
||||
}
|
||||
|
||||
// create the response entity
|
||||
final ReportingTasksEntity entity = new ReportingTasksEntity();
|
||||
entity.setReportingTasks(reportingTasks);
|
||||
if (StringUtils.isBlank(controllerServiceEntity.getComponent().getType())) {
|
||||
throw new IllegalArgumentException("The type of controller service to create must be specified.");
|
||||
}
|
||||
|
||||
// generate the response
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
if (properties.isClusterManager()) {
|
||||
return clusterManager.applyRequest(HttpMethod.POST, getAbsolutePath(), controllerServiceEntity, getHeaders()).getResponse();
|
||||
}
|
||||
|
||||
// handle expects request (usually from the cluster manager)
|
||||
final boolean validationPhase = isValidationPhase(httpServletRequest);
|
||||
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
|
||||
// authorize access
|
||||
serviceFacade.authorizeAccess(lookup -> {
|
||||
// TODO - authorize controller access
|
||||
});
|
||||
}
|
||||
if (validationPhase) {
|
||||
return generateContinueResponse().build();
|
||||
}
|
||||
|
||||
// set the processor id as appropriate
|
||||
controllerServiceEntity.getComponent().setId(generateUuid());
|
||||
|
||||
// create the controller service and generate the json
|
||||
final ControllerServiceEntity entity = serviceFacade.createControllerService(null, controllerServiceEntity.getComponent());
|
||||
controllerServiceResource.populateRemainingControllerServiceContent(entity.getComponent());
|
||||
|
||||
// build the response
|
||||
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
|
||||
}
|
||||
|
||||
// setters
|
||||
|
@ -586,8 +618,15 @@ public class ControllerResource extends ApplicationResource {
|
|||
this.reportingTaskResource = reportingTaskResource;
|
||||
}
|
||||
|
||||
public void setControllerServiceResource(ControllerServiceResource controllerServiceResource) {
|
||||
this.controllerServiceResource = controllerServiceResource;
|
||||
}
|
||||
|
||||
public void setProperties(NiFiProperties properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public void setAuthorizer(Authorizer authorizer) {
|
||||
this.authorizer = authorizer;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ import org.apache.nifi.web.api.dto.AboutDTO;
|
|||
import org.apache.nifi.web.api.dto.BannerDTO;
|
||||
import org.apache.nifi.web.api.dto.BulletinBoardDTO;
|
||||
import org.apache.nifi.web.api.dto.BulletinQueryDTO;
|
||||
import org.apache.nifi.web.api.dto.ControllerConfigurationDTO;
|
||||
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
|
||||
import org.apache.nifi.web.api.dto.RevisionDTO;
|
||||
import org.apache.nifi.web.api.dto.flow.FlowDTO;
|
||||
|
@ -81,7 +80,9 @@ import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity;
|
|||
import org.apache.nifi.web.api.entity.ProcessorStatusEntity;
|
||||
import org.apache.nifi.web.api.entity.ProcessorTypesEntity;
|
||||
import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTaskTypesEntity;
|
||||
import org.apache.nifi.web.api.entity.ReportingTasksEntity;
|
||||
import org.apache.nifi.web.api.entity.ScheduleComponentsEntity;
|
||||
import org.apache.nifi.web.api.entity.SearchResultsEntity;
|
||||
import org.apache.nifi.web.api.entity.StatusHistoryEntity;
|
||||
|
@ -141,6 +142,7 @@ public class FlowResource extends ApplicationResource {
|
|||
private TemplateResource templateResource;
|
||||
private ProcessGroupResource processGroupResource;
|
||||
private ControllerServiceResource controllerServiceResource;
|
||||
private ReportingTaskResource reportingTaskResource;
|
||||
|
||||
/**
|
||||
* Populates the remaining fields in the specified process group.
|
||||
|
@ -186,6 +188,9 @@ public class FlowResource extends ApplicationResource {
|
|||
return flowStructure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authorizes access to the flow.
|
||||
*/
|
||||
private void authorizeFlow() {
|
||||
final NiFiUser user = NiFiUserUtils.getNiFiUser();
|
||||
|
||||
|
@ -269,6 +274,56 @@ public class FlowResource extends ApplicationResource {
|
|||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
// -------------------
|
||||
// controller services
|
||||
// -------------------
|
||||
|
||||
/**
|
||||
* Retrieves all the of controller services in this NiFi.
|
||||
*
|
||||
* @return A controllerServicesEntity.
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("controller/controller-services")
|
||||
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
|
||||
@ApiOperation(
|
||||
value = "Gets all controller services",
|
||||
response = ControllerServicesEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
|
||||
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getControllerServicesFromController() {
|
||||
|
||||
// replicate if cluster manager
|
||||
if (properties.isClusterManager()) {
|
||||
return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
|
||||
}
|
||||
|
||||
// get all the controller services
|
||||
final Set<ControllerServiceEntity> controllerServices = serviceFacade.getControllerServices(null);
|
||||
controllerServiceResource.populateRemainingControllerServiceEntitiesContent(controllerServices);
|
||||
|
||||
// create the response entity
|
||||
final ControllerServicesEntity entity = new ControllerServicesEntity();
|
||||
entity.setControllerServices(controllerServices);
|
||||
|
||||
// generate the response
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the of controller services in this NiFi.
|
||||
*
|
||||
|
@ -296,7 +351,7 @@ public class FlowResource extends ApplicationResource {
|
|||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getControllerServices(
|
||||
public Response getControllerServicesFromGroup(
|
||||
@ApiParam(
|
||||
value = "The process group id.",
|
||||
required = true
|
||||
|
@ -320,6 +375,64 @@ public class FlowResource extends ApplicationResource {
|
|||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// reporting-tasks
|
||||
// ---------------
|
||||
|
||||
/**
|
||||
* Retrieves all the of reporting tasks in this NiFi.
|
||||
*
|
||||
* @param clientId Optional client id. If the client id is not specified, a
|
||||
* new one will be generated. This value (whether specified or generated) is
|
||||
* included in the response.
|
||||
* @return A reportingTasksEntity.
|
||||
*/
|
||||
@GET
|
||||
@Consumes(MediaType.WILDCARD)
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("reporting-tasks")
|
||||
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
|
||||
@ApiOperation(
|
||||
value = "Gets all reporting tasks",
|
||||
response = ReportingTasksEntity.class,
|
||||
authorizations = {
|
||||
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
|
||||
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM"),
|
||||
@Authorization(value = "Administrator", type = "ROLE_ADMIN")
|
||||
}
|
||||
)
|
||||
@ApiResponses(
|
||||
value = {
|
||||
@ApiResponse(code = 400, message = "NiFi was unable to complete the request because it was invalid. The request should not be retried without modification."),
|
||||
@ApiResponse(code = 401, message = "Client could not be authenticated."),
|
||||
@ApiResponse(code = 403, message = "Client is not authorized to make this request."),
|
||||
@ApiResponse(code = 409, message = "The request was valid but NiFi was not in the appropriate state to process it. Retrying the same request later may be successful.")
|
||||
}
|
||||
)
|
||||
public Response getReportingTasks(
|
||||
@ApiParam(
|
||||
value = "If the client id is not specified, new one will be generated. This value (whether specified or generated) is included in the response.",
|
||||
required = false
|
||||
)
|
||||
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
|
||||
|
||||
// replicate if cluster manager
|
||||
if (properties.isClusterManager()) {
|
||||
return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
|
||||
}
|
||||
|
||||
// get all the reporting tasks
|
||||
final Set<ReportingTaskEntity> reportingTasks = serviceFacade.getReportingTasks();
|
||||
reportingTaskResource.populateRemainingReportingTaskEntitiesContent(reportingTasks);
|
||||
|
||||
// create the response entity
|
||||
final ReportingTasksEntity entity = new ReportingTasksEntity();
|
||||
entity.setReportingTasks(reportingTasks);
|
||||
|
||||
// generate the response
|
||||
return clusterContext(generateOkResponse(entity)).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the specified process group.
|
||||
*
|
||||
|
@ -358,8 +471,6 @@ public class FlowResource extends ApplicationResource {
|
|||
@PathParam("id") String id,
|
||||
ScheduleComponentsEntity scheduleComponentsEntity) {
|
||||
|
||||
authorizeFlow();
|
||||
|
||||
// ensure the same id is being used
|
||||
if (!id.equals(scheduleComponentsEntity.getId())) {
|
||||
throw new IllegalArgumentException(String.format("The process group id (%s) in the request body does "
|
||||
|
@ -441,6 +552,9 @@ public class FlowResource extends ApplicationResource {
|
|||
serviceFacade,
|
||||
revisions,
|
||||
lookup -> {
|
||||
// ensure access to the flow
|
||||
authorizeFlow();
|
||||
|
||||
// ensure access to every component being scheduled
|
||||
componentsToSchedule.keySet().forEach(componentId -> {
|
||||
final Authorizable connectable = lookup.getConnectable(componentId);
|
||||
|
@ -875,11 +989,9 @@ public class FlowResource extends ApplicationResource {
|
|||
return clusterManager.applyRequest(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).getResponse();
|
||||
}
|
||||
|
||||
final ControllerConfigurationDTO controllerConfig = serviceFacade.getControllerConfiguration();
|
||||
|
||||
// create the about dto
|
||||
final AboutDTO aboutDTO = new AboutDTO();
|
||||
aboutDTO.setTitle(controllerConfig.getName());
|
||||
aboutDTO.setTitle("NiFi"); // TODO - where to load title from
|
||||
aboutDTO.setVersion(properties.getUiTitle());
|
||||
aboutDTO.setUri(generateResourceUri());
|
||||
|
||||
|
@ -1853,6 +1965,10 @@ public class FlowResource extends ApplicationResource {
|
|||
this.controllerServiceResource = controllerServiceResource;
|
||||
}
|
||||
|
||||
public void setReportingTaskResource(ReportingTaskResource reportingTaskResource) {
|
||||
this.reportingTaskResource = reportingTaskResource;
|
||||
}
|
||||
|
||||
public void setAuthorizer(Authorizer authorizer) {
|
||||
this.authorizer = authorizer;
|
||||
}
|
||||
|
|
|
@ -134,6 +134,7 @@ import org.apache.nifi.web.api.dto.status.ProcessorStatusSnapshotDTO;
|
|||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO;
|
||||
import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusSnapshotDTO;
|
||||
import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
|
||||
import org.apache.nifi.web.controller.ControllerFacade;
|
||||
import org.apache.nifi.web.revision.RevisionManager;
|
||||
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
@ -154,6 +155,7 @@ import java.util.Locale;
|
|||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
@ -174,6 +176,22 @@ public final class DtoFactory {
|
|||
private EntityFactory entityFactory;
|
||||
private Authorizer authorizer;
|
||||
|
||||
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade, final String autoRefreshInterval) {
|
||||
final ControllerConfigurationDTO dto = new ControllerConfigurationDTO();
|
||||
dto.setMaxTimerDrivenThreadCount(controllerFacade.getMaxTimerDrivenThreadCount());
|
||||
dto.setMaxEventDrivenThreadCount(controllerFacade.getMaxEventDrivenThreadCount());
|
||||
|
||||
// get the refresh interval
|
||||
final long refreshInterval = FormatUtils.getTimeDuration(autoRefreshInterval, TimeUnit.SECONDS);
|
||||
dto.setAutoRefreshIntervalSeconds(refreshInterval);
|
||||
|
||||
final Date now = new Date();
|
||||
dto.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime()));
|
||||
dto.setCurrentTime(now);
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ActionDTO for the specified Action.
|
||||
*
|
||||
|
@ -1143,6 +1161,7 @@ public final class DtoFactory {
|
|||
public ControllerServiceDTO createControllerServiceDto(final ControllerServiceNode controllerServiceNode) {
|
||||
final ControllerServiceDTO dto = new ControllerServiceDTO();
|
||||
dto.setId(controllerServiceNode.getIdentifier());
|
||||
dto.setParentGroupId(controllerServiceNode.getProcessGroup() == null ? null : controllerServiceNode.getProcessGroup().getIdentifier());
|
||||
dto.setName(controllerServiceNode.getName());
|
||||
dto.setType(controllerServiceNode.getControllerServiceImplementation().getClass().getName());
|
||||
dto.setState(controllerServiceNode.getState().name());
|
||||
|
|
|
@ -24,6 +24,7 @@ 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.entity.ConnectionEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
|
||||
import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity;
|
||||
import org.apache.nifi.web.api.entity.FlowBreadcrumbEntity;
|
||||
|
@ -40,6 +41,19 @@ import org.apache.nifi.web.api.entity.SnippetEntity;
|
|||
|
||||
public final class EntityFactory {
|
||||
|
||||
public ControllerConfigurationEntity createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
|
||||
final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
|
||||
entity.setRevision(revision);
|
||||
if (dto != null) {
|
||||
entity.setAccessPolicy(accessPolicy);
|
||||
// TODO - remove this once contents of ControllerConfigurationEntity is updated
|
||||
// if (accessPolicy != null && accessPolicy.getCanRead()) {
|
||||
entity.setConfig(dto);
|
||||
// }
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
|
||||
public ProcessGroupFlowEntity createProcessGroupFlowEntity(final ProcessGroupFlowDTO dto, final AccessPolicyDTO accessPolicy) {
|
||||
final ProcessGroupFlowEntity entity = new ProcessGroupFlowEntity();
|
||||
entity.setProcessGroupFlow(dto);
|
||||
|
|
|
@ -177,6 +177,7 @@
|
|||
<property name="connectionResource" ref="connectionResource"/>
|
||||
<property name="templateResource" ref="templateResource"/>
|
||||
<property name="controllerServiceResource" ref="controllerServiceResource"/>
|
||||
<property name="reportingTaskResource" ref="reportingTaskResource"/>
|
||||
<property name="processGroupResource" ref="processGroupResource"/>
|
||||
</bean>
|
||||
<bean id="resourceResource" class="org.apache.nifi.web.api.ResourceResource" scope="singleton">
|
||||
|
@ -190,6 +191,8 @@
|
|||
<property name="properties" ref="nifiProperties"/>
|
||||
<property name="clusterManager" ref="clusterManager"/>
|
||||
<property name="reportingTaskResource" ref="reportingTaskResource"/>
|
||||
<property name="controllerServiceResource" ref="controllerServiceResource"/>
|
||||
<property name="authorizer" ref="authorizer"/>
|
||||
</bean>
|
||||
<bean id="siteToSiteResource" class="org.apache.nifi.web.api.SiteToSiteResource" scope="singleton">
|
||||
<property name="serviceFacade" ref="serviceFacade"/>
|
||||
|
|
|
@ -184,7 +184,6 @@ public class AdminAccessControlTest {
|
|||
ControllerConfigurationEntity entity = response.getEntity(ControllerConfigurationEntity.class);
|
||||
Assert.assertNotNull(entity);
|
||||
Assert.assertNotNull(entity.getConfig());
|
||||
Assert.assertEquals("NiFi Flow", entity.getConfig().getName());
|
||||
Assert.assertEquals(10, entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
|
||||
Assert.assertEquals(5, entity.getConfig().getMaxEventDrivenThreadCount().intValue());
|
||||
Assert.assertEquals(30, entity.getConfig().getAutoRefreshIntervalSeconds().intValue());
|
||||
|
|
|
@ -207,7 +207,6 @@ public class DfmAccessControlTest {
|
|||
|
||||
// create the controller configuration
|
||||
ControllerConfigurationDTO controllerConfig = new ControllerConfigurationDTO();
|
||||
controllerConfig.setName("new name");
|
||||
|
||||
// create the revision
|
||||
final RevisionDTO revision = new RevisionDTO();
|
||||
|
@ -229,7 +228,6 @@ public class DfmAccessControlTest {
|
|||
entity = response.getEntity(ControllerConfigurationEntity.class);
|
||||
Assert.assertNotNull(entity);
|
||||
Assert.assertNotNull(entity.getConfig());
|
||||
Assert.assertEquals("new name", entity.getConfig().getName());
|
||||
Assert.assertEquals(10, entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
|
||||
Assert.assertEquals(5, entity.getConfig().getMaxEventDrivenThreadCount().intValue());
|
||||
Assert.assertEquals(30, entity.getConfig().getAutoRefreshIntervalSeconds().intValue());
|
||||
|
|
|
@ -180,7 +180,6 @@ public class ReadOnlyAccessControlTest {
|
|||
ControllerConfigurationEntity entity = response.getEntity(ControllerConfigurationEntity.class);
|
||||
Assert.assertNotNull(entity);
|
||||
Assert.assertNotNull(entity.getConfig());
|
||||
Assert.assertEquals("NiFi Flow", entity.getConfig().getName());
|
||||
Assert.assertEquals(10, entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
|
||||
Assert.assertEquals(5, entity.getConfig().getMaxEventDrivenThreadCount().intValue());
|
||||
Assert.assertEquals(30, entity.getConfig().getAutoRefreshIntervalSeconds().intValue());
|
||||
|
|
|
@ -339,6 +339,7 @@
|
|||
<include>${staging.dir}/js/nf/canvas/nf-queue-listing.js</include>
|
||||
<include>${staging.dir}/js/nf/canvas/nf-component-state.js</include>
|
||||
<include>${staging.dir}/js/nf/canvas/nf-controller-service.js</include>
|
||||
<include>${staging.dir}/js/nf/canvas/nf-controller-services.js</include>
|
||||
<include>${staging.dir}/js/nf/canvas/nf-reporting-task.js</include>
|
||||
<include>${staging.dir}/js/nf/canvas/nf-processor-configuration.js</include>
|
||||
<include>${staging.dir}/js/nf/nf-processor-details.js</include>
|
||||
|
|
|
@ -27,6 +27,7 @@ nf.canvas.script.tags=<script type="text/javascript" src="js/nf/nf-namespace.js?
|
|||
<script type="text/javascript" src="js/nf/canvas/nf-component-state.js?${project.version}"></script>\n\
|
||||
<script type="text/javascript" src="js/nf/canvas/nf-custom-ui.js?${project.version}"></script>\n\
|
||||
<script type="text/javascript" src="js/nf/canvas/nf-controller-service.js?${project.version}"></script>\n\
|
||||
<script type="text/javascript" src="js/nf/canvas/nf-controller-services.js?${project.version}"></script>\n\
|
||||
<script type="text/javascript" src="js/nf/canvas/nf-reporting-task.js?${project.version}"></script>\n\
|
||||
<script type="text/javascript" src="js/nf/canvas/nf-processor-configuration.js?${project.version}"></script>\n\
|
||||
<script type="text/javascript" src="js/nf/nf-processor-details.js?${project.version}"></script>\n\
|
||||
|
|
|
@ -83,6 +83,12 @@
|
|||
<div class="graph-control-content hidden">
|
||||
<div id="operation-buttons">
|
||||
<div>
|
||||
<div id="operate-configure" class="action-button" title="Configuration">
|
||||
<button ng-click="appCtrl.nf.Actions['showConfiguration'](appCtrl.nf.CanvasUtils.getSelection());"
|
||||
ng-disabled="false">
|
||||
<i class="graph-control-action-icon fa fa-gear"></i></button>
|
||||
</div>
|
||||
<div class="button-spacer-large"> </div>
|
||||
<div id="operate-enable" class="action-button" title="Enable">
|
||||
<button ng-click="appCtrl.nf.Actions['enable'](appCtrl.nf.CanvasUtils.getSelection());"
|
||||
ng-disabled="!appCtrl.nf.CanvasUtils.canEnable(appCtrl.nf.CanvasUtils.getSelection());">
|
||||
|
@ -112,7 +118,9 @@
|
|||
ng-disabled="!(appCtrl.nf.Canvas.canWrite() && (appCtrl.nf.CanvasUtils.getSelection().empty() || appCtrl.nf.CanvasUtils.canRead(appCtrl.nf.CanvasUtils.getSelection())));">
|
||||
<i class="graph-control-action-icon icon icon-template"></i></button>
|
||||
</div>
|
||||
<div class="button-spacer-large"> </div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<div id="operate-copy" class="action-button" title="Copy">
|
||||
<button ng-click="appCtrl.nf.Actions['copy'](appCtrl.nf.CanvasUtils.getSelection());"
|
||||
ng-disabled="!appCtrl.nf.CanvasUtils.isCopyable(appCtrl.nf.CanvasUtils.getSelection()) || !appCtrl.nf.CanvasUtils.canRead(appCtrl.nf.CanvasUtils.getSelection());">
|
||||
|
@ -124,9 +132,7 @@
|
|||
ng-disabled="!appCtrl.nf.Clipboard.isCopied()">
|
||||
<i class="graph-control-action-icon fa fa-paste"></i></button>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div style="margin-top: 5px;">
|
||||
<div class="button-spacer-large"> </div>
|
||||
<div id="operate-group" class="action-button" title="Group">
|
||||
<button ng-click="appCtrl.nf.Actions['group'](appCtrl.nf.CanvasUtils.getSelection());"
|
||||
ng-disabled="!appCtrl.nf.CanvasUtils.isDisconnected(appCtrl.nf.CanvasUtils.getSelection()) || !appCtrl.nf.CanvasUtils.canModify(appCtrl.nf.CanvasUtils.getSelection());">
|
||||
|
|
|
@ -15,24 +15,49 @@
|
|||
limitations under the License.
|
||||
--%>
|
||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||
<div id="process-group-configuration" nf-draggable="{containment: 'parent', handle: '.dialog-header'}">
|
||||
<div class="dialog-content">
|
||||
<div class="setting">
|
||||
<div class="setting-name">Name</div>
|
||||
<div class="setting-field">
|
||||
<input type="text" id="process-group-name" name="process-group-name" class="process-group-field"/>
|
||||
<div id="process-group-configuration">
|
||||
<div id="process-group-configuration-header-text" class="settings-header-text">Process Group Configuration</div>
|
||||
<div class="settings-container">
|
||||
<div class="settings-tabs-container">
|
||||
<div id="process-group-configuration-tabs" class="settings-tabs"></div>
|
||||
<div id="process-group-configuration-refresh-button" class="pointer settings-refresh-button" title="Refresh"></div>
|
||||
<div class="settings-last-refreshed-container">
|
||||
Last updated: <span id="process-group-configuration-last-refreshed"></span>
|
||||
</div>
|
||||
<div id="process-group-configuration-loading-container" class="loading-container"></div>
|
||||
<div id="add-process-group-configuration-controller-service" class="add-icon-bg"></div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Id</div>
|
||||
<div class="setting-field">
|
||||
<span id="process-group-id"></span>
|
||||
<div class="settings-tab-background"></div>
|
||||
<div>
|
||||
<div id="general-process-group-configuration-tab-content" class="configuration-tab">
|
||||
<div id="general-process-group-configuration">
|
||||
<div class="setting">
|
||||
<div class="setting-name">Process group name</div>
|
||||
<div class="editable setting-field">
|
||||
<input type="text" id="process-group-name" class="setting-input"/>
|
||||
</div>
|
||||
<div class="read-only setting-field">
|
||||
<span id="read-only-process-group-name"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Process group comments</div>
|
||||
<div class="editable setting-field">
|
||||
<textarea id="process-group-comments" class="setting-input"></textarea>
|
||||
</div>
|
||||
<div class="read-only setting-field">
|
||||
<span id="read-only-process-group-comments"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="editable settings-buttons">
|
||||
<div id="process-group-configuration-save" class="button">Apply</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Comments</div>
|
||||
<div class="setting-field">
|
||||
<textarea cols="30" rows="4" id="process-group-comments" name="process-group-comments" class="process-group-field"></textarea>
|
||||
<div id="process-group-controller-services-tab-content" class="configuration-tab">
|
||||
<div id="process-group-controller-services-table" class="settings-table"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -16,43 +16,22 @@
|
|||
--%>
|
||||
<%@ page contentType="text/html" pageEncoding="UTF-8" session="false" %>
|
||||
<div id="settings">
|
||||
<div id="settings-header-text">NiFi Settings</div>
|
||||
<div id="settings-container">
|
||||
<div id="settings-tabs-container">
|
||||
<div id="settings-tabs"></div>
|
||||
<div id="settings-refresh-button" class="pointer" title="Refresh"></div>
|
||||
<div id="settings-last-refreshed-container">
|
||||
<div id="settings-header-text" class="settings-header-text">NiFi Settings</div>
|
||||
<div class="settings-container">
|
||||
<div class="settings-tabs-container">
|
||||
<div id="settings-tabs" class="settings-tabs"></div>
|
||||
<div id="settings-refresh-button" class="pointer settings-refresh-button" title="Refresh"></div>
|
||||
<div class="settings-last-refreshed-container">
|
||||
Last updated: <span id="settings-last-refreshed"></span>
|
||||
</div>
|
||||
<div id="settings-refresh-required-icon" class="hidden"></div>
|
||||
<div id="settings-loading-container" class="loading-container"></div>
|
||||
<div id="new-service-or-task" class="add-icon-bg"></div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
<div id="settings-tab-background"></div>
|
||||
<div id="settings-tabs-content">
|
||||
<div class="settings-tab-background"></div>
|
||||
<div>
|
||||
<div id="general-settings-tab-content" class="configuration-tab">
|
||||
<div id="general-settings">
|
||||
<div class="setting">
|
||||
<div class="setting-name">Data flow name</div>
|
||||
<div class="editable setting-field">
|
||||
<input type="text" id="data-flow-title-field" name="data-flow-title" class="setting-input"/>
|
||||
<span id="archive-flow-link" class="link">Back-up flow</span>
|
||||
<img class="setting-icon icon-info" src="images/iconInfo.png" alt="Info" title="Archives the flow configuration."/>
|
||||
</div>
|
||||
<div class="read-only setting-field">
|
||||
<span id="read-only-data-flow-title-field"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">Data flow comments</div>
|
||||
<div class="editable setting-field">
|
||||
<textarea id="data-flow-comments-field" name="data-flow-comments" class="setting-input"></textarea>
|
||||
</div>
|
||||
<div class="read-only setting-field">
|
||||
<span id="read-only-data-flow-comments-field"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting">
|
||||
<div class="setting-name">
|
||||
Maximum timer driven thread count
|
||||
|
@ -60,6 +39,8 @@
|
|||
</div>
|
||||
<div class="editable setting-field">
|
||||
<input type="text" id="maximum-timer-driven-thread-count-field" class="setting-input"/>
|
||||
<span id="archive-flow-link" class="link">Back-up flow</span>
|
||||
<img class="setting-icon icon-info" src="images/iconInfo.png" alt="Info" title="Archives the flow configuration."/>
|
||||
</div>
|
||||
<div class="read-only setting-field">
|
||||
<span id="read-only-maximum-timer-driven-thread-count-field"></span>
|
||||
|
@ -77,7 +58,7 @@
|
|||
<span id="read-only-maximum-event-driven-thread-count-field"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="settings-buttons" class="editable">
|
||||
<div class="editable settings-buttons">
|
||||
<div id="settings-save" class="button">Apply</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
|
|
|
@ -14,11 +14,16 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/* flow status styles positioned at the top of the graph */
|
||||
|
||||
#flow-status {
|
||||
height: 32px;
|
||||
height: 33px;
|
||||
background-color: #E3E8EB; /*tint base-color 60%*/
|
||||
border-bottom: 1px solid #aabbc3;
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
|
||||
z-index: 3;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#flow-status .icon {
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
left: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
background-color: #f9fafb;
|
||||
background-size: 14px 14px;
|
||||
background-image: linear-gradient(to right, rgba(229, 235, 237, 1) 1px, transparent 1px), linear-gradient(to bottom, rgba(229, 235, 237, 1) 1px, transparent 1px);
|
||||
z-index: 1;
|
||||
|
@ -64,6 +65,11 @@ g.component rect.body.unauthorized {
|
|||
fill: #f4f6f7;
|
||||
}
|
||||
|
||||
g.component rect.border {
|
||||
stroke: rgba(0,0,0,0.25);
|
||||
stroke-width: 1;
|
||||
}
|
||||
|
||||
g.component rect.border.unauthorized {
|
||||
stroke-width: 1.5;
|
||||
stroke: #ba554a;
|
||||
|
|
|
@ -23,11 +23,15 @@ md-toolbar.md-small {
|
|||
height: 56px;
|
||||
background-color:#AABBC3; /*tint base-color 40%*/
|
||||
min-height: 56px;
|
||||
max-height: 56px; }
|
||||
max-height: 56px;
|
||||
position: relative;
|
||||
z-index: 4;
|
||||
}
|
||||
md-toolbar.md-small .md-toolbar-tools {
|
||||
height: 56px;
|
||||
min-height: 56px;
|
||||
max-height: 56px; }
|
||||
max-height: 56px;
|
||||
}
|
||||
|
||||
#header .icon {
|
||||
font-size:30px;
|
||||
|
|
|
@ -55,12 +55,11 @@
|
|||
}
|
||||
|
||||
div.graph-control {
|
||||
background-color: rgba(249, 250, 251, 0.97); /*tint base-color 96%*/
|
||||
border-top: 1px solid #C7D2D7; /*tint base-color 60%*/
|
||||
border-right: 1px solid #C7D2D7; /*tint base-color 60%*/
|
||||
border-bottom: 1px solid #C7D2D7; /*tint base-color 60%*/
|
||||
border-top-right-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
box-shadow: 0 1px 6px rgba(0,0,0,0.25);
|
||||
background-color: rgba(249, 250, 251, 0.9);
|
||||
border-top: 1px solid #aabbc3;
|
||||
border-right: 1px solid #aabbc3;
|
||||
border-bottom: 1px solid #aabbc3;
|
||||
padding: 10px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
@ -75,9 +74,8 @@ div.graph-control button {
|
|||
height: 24px;
|
||||
width: 24px;
|
||||
line-height: 19px;
|
||||
border-radius: 2px;
|
||||
border: 1px solid #CCDADB; /*tint link-color 80%*/
|
||||
background-color: rgba(249, 250, 251, 0.97);
|
||||
background-color: rgba(249,250,251,1);
|
||||
color: #004849;
|
||||
}
|
||||
|
||||
|
@ -186,8 +184,9 @@ rect.birdseye-brush {
|
|||
#breadcrumbs {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
background-color: rgba(249, 250, 251, 0.97); /*tint base-color 96%*/
|
||||
border-top: 1px solid #C7D2D7; /*tint base-color 60%*/
|
||||
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.25);
|
||||
background-color: rgba(249, 250, 251, 0.9);
|
||||
border-top: 1px solid #aabbc3;
|
||||
color: #598599;
|
||||
z-index: 3;
|
||||
height: 31px;
|
||||
|
|
|
@ -14,17 +14,64 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#process-group-configuration {
|
||||
z-index: 1301;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
display: none;
|
||||
width: 400px;
|
||||
height: 320px;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.process-group-field {
|
||||
width: 369px;
|
||||
#add-process-group-configuration-controller-service {
|
||||
float: right;
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
margin-top: 4px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
textarea.process-group-field {
|
||||
/* settings tabs */
|
||||
|
||||
#process-group-configuration-tabs {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#process-group-configuration-refresh-button {
|
||||
height: 24px;
|
||||
width: 26px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#process-group-configuration-loading-container {
|
||||
float: left;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: transparent;
|
||||
margin-top: 4px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
|
||||
#process-group-configuration-last-refreshed {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* general */
|
||||
|
||||
#general-process-group-configuration {
|
||||
margin-top: -190px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#general-process-group-configuration input, #general-process-group-configuration textarea {
|
||||
font-size: 11px !important;
|
||||
font-family: Verdana;
|
||||
width: 350px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#process-group-comments {
|
||||
height: 100px;
|
||||
}
|
|
@ -25,13 +25,13 @@
|
|||
padding: 20px;
|
||||
}
|
||||
|
||||
#settings-header-text {
|
||||
div.settings-header-text {
|
||||
height: 35px;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#settings-container {
|
||||
div.settings-container {
|
||||
margin-top: 18px;
|
||||
}
|
||||
|
||||
|
@ -45,11 +45,11 @@
|
|||
|
||||
/* settings tabs */
|
||||
|
||||
#settings-tabs-container {
|
||||
div.settings-tabs-container {
|
||||
border-bottom: 2px solid #666;
|
||||
}
|
||||
|
||||
#settings-tabs {
|
||||
div.settings-tabs {
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@
|
|||
border-right: 1px solid #666;
|
||||
}
|
||||
|
||||
#settings-tab-background {
|
||||
div.settings-tab-background {
|
||||
height: 200px;
|
||||
margin-top: 1px;
|
||||
background-color: transparent;
|
||||
|
@ -86,7 +86,7 @@
|
|||
filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr=#dddddd, endColorstr=#ffffff);
|
||||
}
|
||||
|
||||
#settings div.configuration-tab {
|
||||
#settings div.configuration-tab, #process-group-configuration div.configuration-tab {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -105,13 +105,13 @@ span.sorted {
|
|||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#settings-refresh-button {
|
||||
div.settings-refresh-button {
|
||||
height: 24px;
|
||||
width: 26px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#settings-last-refreshed-container {
|
||||
div.settings-last-refreshed-container {
|
||||
float: left;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
|
@ -134,15 +134,6 @@ span.sorted {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#settings-refresh-required-icon {
|
||||
float: left;
|
||||
margin-top: 4px;
|
||||
margin-left: 3px;
|
||||
width: 18px;
|
||||
height: 16px;
|
||||
background-image: url(../images/iconAlert.png);
|
||||
}
|
||||
|
||||
/* general */
|
||||
|
||||
#general-settings {
|
||||
|
@ -150,23 +141,19 @@ span.sorted {
|
|||
margin-left: 10px;
|
||||
}
|
||||
|
||||
#general-settings input, #general-settings textarea {
|
||||
#general-settings input {
|
||||
font-size: 11px !important;
|
||||
font-family: Verdana;
|
||||
width: 350px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
#data-flow-comments-field {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
#settings-buttons {
|
||||
margin-left: 304px;
|
||||
div.settings-buttons {
|
||||
margin-left: 310px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#settings-save {
|
||||
div.settings-buttons div.button {
|
||||
float: left;
|
||||
}
|
||||
|
||||
|
|
|
@ -1108,36 +1108,43 @@
|
|||
};
|
||||
|
||||
var goToControllerService = function (property) {
|
||||
// close the dialog
|
||||
var dialog = table.closest('.dialog');
|
||||
if (dialog.hasClass('modal')) {
|
||||
dialog.modal('hide');
|
||||
} else {
|
||||
dialog.hide();
|
||||
}
|
||||
|
||||
$.Deferred(function (deferred) {
|
||||
if ($('#settings').is(':visible')) {
|
||||
deferred.resolve();
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: '../nifi-api/controller-services/' + encodeURIComponent(property.value),
|
||||
dataType: 'json'
|
||||
}).done(function (controllerServiceEntity) {
|
||||
// close the dialog
|
||||
var dialog = table.closest('.dialog');
|
||||
if (dialog.hasClass('modal')) {
|
||||
dialog.modal('hide');
|
||||
} else {
|
||||
// reload the settings and show
|
||||
nf.Settings.loadSettings().done(function () {
|
||||
nf.Settings.showSettings();
|
||||
deferred.resolve();
|
||||
});
|
||||
dialog.hide();
|
||||
}
|
||||
}).done(function () {
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
|
||||
// select the desired service
|
||||
var row = controllerServiceData.getRowById(property.value);
|
||||
controllerServiceGrid.setSelectedRows([row]);
|
||||
controllerServiceGrid.scrollRowIntoView(row);
|
||||
|
||||
// select the controller services tab
|
||||
$('#settings-tabs').find('li:eq(1)').click();
|
||||
});
|
||||
var controllerService = controllerServiceEntity.component;
|
||||
$.Deferred(function (deferred) {
|
||||
if (nf.Common.isDefinedAndNotNull(controllerService.parentGroupId)) {
|
||||
nf.ProcessGroupConfiguration.showConfiguration(controllerService.parentGroupId).done(function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
if ($('#settings').is(':visible')) {
|
||||
deferred.resolve();
|
||||
} else {
|
||||
// reload the settings and show
|
||||
nf.Settings.showSettings().done(function () {
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
}
|
||||
}).done(function () {
|
||||
if (nf.Common.isDefinedAndNotNull(controllerService.parentGroupId)) {
|
||||
nf.ProcessGroupConfiguration.selectControllerService(property.value);
|
||||
} else {
|
||||
nf.Settings.selectControllerService(property.value);
|
||||
}
|
||||
});
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
// initialize the grid
|
||||
|
@ -1580,13 +1587,15 @@
|
|||
var propertyTableContainer = $(this);
|
||||
var options = propertyTableContainer.data('options');
|
||||
|
||||
// clear the property table container
|
||||
clear(propertyTableContainer);
|
||||
|
||||
// clear any existing new property dialogs
|
||||
if (nf.Common.isDefinedAndNotNull(options.dialogContainer)) {
|
||||
$(options.dialogContainer).children('div.new-property-dialog').remove();
|
||||
$(options.dialogContainer).children('div.new-inline-controller-service-dialog').remove();
|
||||
if (nf.Common.isDefinedAndNotNull(options)) {
|
||||
// clear the property table container
|
||||
clear(propertyTableContainer);
|
||||
|
||||
// clear any existing new property dialogs
|
||||
if (nf.Common.isDefinedAndNotNull(options.dialogContainer)) {
|
||||
$(options.dialogContainer).children('div.new-property-dialog').remove();
|
||||
$(options.dialogContainer).children('div.new-inline-controller-service-dialog').remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
|
|
@ -128,9 +128,7 @@ nf.ng.Canvas.GlobalMenuCtrl = function (serviceProvider) {
|
|||
* Launch the settings shell.
|
||||
*/
|
||||
launch: function () {
|
||||
nf.Settings.loadSettings().done(function () {
|
||||
nf.Settings.showSettings();
|
||||
});
|
||||
nf.Settings.showSettings();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -118,32 +118,6 @@ nf.ng.Canvas.HeaderCtrl = function (serviceProvider, toolboxCtrl, globalMenuCtrl
|
|||
this.globalMenuCtrl.init();
|
||||
this.flowStatusCtrl.init();
|
||||
this.loginCtrl.init();
|
||||
},
|
||||
|
||||
/**
|
||||
* Reloads and clears any warnings.
|
||||
*/
|
||||
reloadAndClearWarnings: function () {
|
||||
nf.Canvas.reload().done(function () {
|
||||
// update component visibility
|
||||
nf.Canvas.View.updateVisibility();
|
||||
|
||||
// refresh the birdseye
|
||||
nf.Birdseye.refresh();
|
||||
|
||||
// hide the refresh link on the canvas
|
||||
$('#stats-last-refreshed').removeClass('alert');
|
||||
$('#refresh-required-container').hide();
|
||||
|
||||
// hide the refresh link on the settings
|
||||
$('#settings-last-refreshed').removeClass('alert');
|
||||
$('#settings-refresh-required-icon').hide();
|
||||
}).fail(function () {
|
||||
nf.Dialog.showOkDialog({
|
||||
dialogContent: 'Unable to refresh the current group.',
|
||||
overlayBackground: true
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -691,13 +691,16 @@ nf.Actions = (function () {
|
|||
* @param {selection} selection Selection of the component to be configured
|
||||
*/
|
||||
showConfiguration: function (selection) {
|
||||
if (selection.size() === 1) {
|
||||
if (selection.empty()) {
|
||||
nf.ProcessGroupConfiguration.showConfiguration(nf.Canvas.getGroupId());
|
||||
} else if (selection.size() === 1) {
|
||||
var selectionData = selection.datum();
|
||||
if (nf.CanvasUtils.isProcessor(selection)) {
|
||||
nf.ProcessorConfiguration.showConfiguration(selection);
|
||||
} else if (nf.CanvasUtils.isLabel(selection)) {
|
||||
nf.LabelConfiguration.showConfiguration(selection);
|
||||
} else if (nf.CanvasUtils.isProcessGroup(selection)) {
|
||||
nf.ProcessGroupConfiguration.showConfiguration(selection);
|
||||
nf.ProcessGroupConfiguration.showConfiguration(selectionData.id);
|
||||
} else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
|
||||
nf.RemoteProcessGroupConfiguration.showConfiguration(selection);
|
||||
} else if (nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection)) {
|
||||
|
@ -710,12 +713,14 @@ nf.Actions = (function () {
|
|||
|
||||
// Defines an action for showing component details (like configuration but read only).
|
||||
showDetails: function (selection) {
|
||||
if (selection.size() === 1) {
|
||||
if (selection.empty()) {
|
||||
nf.ProcessGroupDetails.showConfiguration(nf.Canvas.getGroupId());
|
||||
} else if (selection.size() === 1) {
|
||||
var selectionData = selection.datum();
|
||||
if (nf.CanvasUtils.isProcessor(selection)) {
|
||||
nf.ProcessorDetails.showDetails(nf.Canvas.getGroupId(), selectionData.id);
|
||||
} else if (nf.CanvasUtils.isProcessGroup(selection)) {
|
||||
nf.ProcessGroupDetails.showDetails(selection);
|
||||
nf.ProcessGroupDetails.showConfiguration(selectionData.id);
|
||||
} else if (nf.CanvasUtils.isRemoteProcessGroup(selection)) {
|
||||
nf.RemoteProcessGroupDetails.showDetails(selection);
|
||||
} else if (nf.CanvasUtils.isInputPort(selection) || nf.CanvasUtils.isOutputPort(selection)) {
|
||||
|
|
|
@ -113,7 +113,6 @@ nf.Canvas = (function () {
|
|||
var groupName = null;
|
||||
var accessPolicy = null;
|
||||
var parentGroupId = null;
|
||||
var secureSiteToSite = false;
|
||||
var clustered = false;
|
||||
var svg = null;
|
||||
var canvas = null;
|
||||
|
@ -267,33 +266,45 @@ nf.Canvas = (function () {
|
|||
|
||||
// filter for drop shadow
|
||||
var filter = defs.append('filter')
|
||||
.attr('id', 'component-drop-shadow');
|
||||
.attr({
|
||||
'id': 'component-drop-shadow',
|
||||
'height': '140%',
|
||||
'y': '-20%'
|
||||
});
|
||||
|
||||
// blur
|
||||
filter.append('feGaussianBlur')
|
||||
.attr('in', 'SourceAlpha')
|
||||
.attr('stdDeviation', 2)
|
||||
.attr('result', 'blur');
|
||||
.attr({
|
||||
'in': 'SourceAlpha',
|
||||
'stdDeviation': 3,
|
||||
'result': 'blur'
|
||||
});
|
||||
|
||||
// offset
|
||||
filter.append('feOffset')
|
||||
.attr('in', 'blur')
|
||||
.attr('dx', 0)
|
||||
.attr('dy', 1)
|
||||
.attr('result', 'offsetBlur');
|
||||
.attr({
|
||||
'in': 'blur',
|
||||
'dx': 0,
|
||||
'dy': 1,
|
||||
'result': 'offsetBlur'
|
||||
});
|
||||
|
||||
// color/opacity
|
||||
filter.append('feFlood')
|
||||
.attr('flood-color', '#000000')
|
||||
.attr('flood-opacity', 0.25)
|
||||
.attr('result', 'offsetColor');
|
||||
.attr({
|
||||
'flood-color': '#000000',
|
||||
'flood-opacity': 0.4,
|
||||
'result': 'offsetColor'
|
||||
});
|
||||
|
||||
// combine
|
||||
filter.append('feComposite')
|
||||
.attr('in', 'offsetColor')
|
||||
.attr('in2', 'offsetBlur')
|
||||
.attr('operator', 'in')
|
||||
.attr('result', 'offsetColorBlur');
|
||||
.attr({
|
||||
'in': 'offsetColor',
|
||||
'in2': 'offsetBlur',
|
||||
'operator': 'in',
|
||||
'result': 'offsetColorBlur'
|
||||
});
|
||||
|
||||
// stack the effect under the source graph
|
||||
var feMerge = filter.append('feMerge');
|
||||
|
@ -512,7 +523,6 @@ nf.Canvas = (function () {
|
|||
if (e.target === window) {
|
||||
updateGraphSize();
|
||||
updateFlowStatusContainerSize();
|
||||
nf.Settings.resetTableSize();
|
||||
}
|
||||
}).on('keydown', function (evt) {
|
||||
// if a dialog is open, disable canvas shortcuts
|
||||
|
@ -819,9 +829,6 @@ nf.Canvas = (function () {
|
|||
// get the auto refresh interval
|
||||
var autoRefreshIntervalSeconds = parseInt(configDetails.autoRefreshIntervalSeconds, 10);
|
||||
|
||||
// initialize whether site to site is secure
|
||||
secureSiteToSite = configDetails.siteToSiteSecure;
|
||||
|
||||
// init storage
|
||||
nf.Storage.init();
|
||||
|
||||
|
@ -890,13 +897,6 @@ nf.Canvas = (function () {
|
|||
return clustered === true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns whether site to site communications is secure.
|
||||
*/
|
||||
isSecureSiteToSite: function () {
|
||||
return secureSiteToSite;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the group id.
|
||||
*
|
||||
|
|
|
@ -112,12 +112,13 @@ nf.ControllerService = (function () {
|
|||
/**
|
||||
* Reloads the specified controller service. It's referencing and referenced
|
||||
* components are NOT reloaded.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {string} id
|
||||
*/
|
||||
var reloadControllerService = function (id) {
|
||||
var reloadControllerService = function (serviceTable, id) {
|
||||
// get the table and update the row accordingly
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
var controllerServiceEntity = controllerServiceData.getItemById(id);
|
||||
|
||||
|
@ -135,18 +136,19 @@ nf.ControllerService = (function () {
|
|||
url: controllerServiceEntity.component.uri,
|
||||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
renderControllerService(response);
|
||||
renderControllerService(serviceTable, response);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders the specified controller service.
|
||||
*
|
||||
*
|
||||
* @param {object} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
*/
|
||||
var renderControllerService = function (controllerServiceEntity) {
|
||||
var renderControllerService = function (serviceTable, controllerServiceEntity) {
|
||||
// get the table and update the row accordingly
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
var currentControllerServiceEntity = controllerServiceData.getItemById(controllerServiceEntity.id);
|
||||
controllerServiceData.updateItem(controllerServiceEntity.id, $.extend({
|
||||
|
@ -157,22 +159,24 @@ nf.ControllerService = (function () {
|
|||
/**
|
||||
* Reloads the specified controller services and all of its referencing
|
||||
* and referenced components.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {type} controllerService
|
||||
*/
|
||||
var reloadControllerServiceAndReferencingComponents = function (controllerService) {
|
||||
reloadControllerService(controllerService.id).done(function(response) {
|
||||
reloadControllerServiceReferences(response.component);
|
||||
var reloadControllerServiceAndReferencingComponents = function (serviceTable, controllerService) {
|
||||
reloadControllerService(serviceTable, controllerService.id).done(function(response) {
|
||||
reloadControllerServiceReferences(serviceTable, response.component);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Reloads components that reference this controller service as well as
|
||||
* other services that this controller service references.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerService
|
||||
*/
|
||||
var reloadControllerServiceReferences = function (controllerService) {
|
||||
var reloadControllerServiceReferences = function (serviceTable, controllerService) {
|
||||
// reload all dependent processors if they are currently visible
|
||||
$.each(controllerService.referencingComponents, function (_, referencingComponentEntity) {
|
||||
// ensure we can read the referencing component prior to reloading
|
||||
|
@ -210,7 +214,7 @@ nf.ControllerService = (function () {
|
|||
}
|
||||
} else {
|
||||
// reload the referencing services
|
||||
reloadControllerService(reference.id);
|
||||
reloadControllerService(serviceTable, reference.id);
|
||||
|
||||
// update the current state of this service
|
||||
var referencingComponentState = $('div.' + reference.id + '-state');
|
||||
|
@ -220,14 +224,14 @@ nf.ControllerService = (function () {
|
|||
|
||||
// consider it's referencing components if appropriate
|
||||
if (reference.referenceCycle === false) {
|
||||
reloadControllerServiceReferences(reference);
|
||||
reloadControllerServiceReferences(serviceTable, reference);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// see if this controller service references another controller service
|
||||
// in order to update the referenced service referencing components
|
||||
nf.ControllerService.reloadReferencedServices(controllerService);
|
||||
nf.ControllerService.reloadReferencedServices(serviceTable, controllerService);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -361,11 +365,12 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Adds the specified reference for this controller service.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {jQuery} referenceContainer
|
||||
* @param {array} referencingComponents
|
||||
*/
|
||||
var createReferencingComponents = function (referenceContainer, referencingComponents) {
|
||||
var createReferencingComponents = function (serviceTable, referenceContainer, referencingComponents) {
|
||||
if (nf.Common.isEmpty(referencingComponents)) {
|
||||
referenceContainer.append('<div class="unset">No referencing components.</div>');
|
||||
return;
|
||||
|
@ -427,7 +432,7 @@ nf.ControllerService = (function () {
|
|||
processors.append(processorItem);
|
||||
} else if (referencingComponent.referenceType === 'ControllerService') {
|
||||
var serviceLink = $('<span class="referencing-component-name link"></span>').text(referencingComponent.name).on('click', function () {
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
|
||||
// select the selected row
|
||||
|
@ -443,12 +448,12 @@ nf.ControllerService = (function () {
|
|||
var referencingServiceReferencesContainer = $('<div class="referencing-component-references hidden"></div>');
|
||||
var serviceTwist = $('<div class="service expansion-button collapsed pointer"></div>').on('click', function() {
|
||||
if (serviceTwist.hasClass('collapsed')) {
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
var referencingService = controllerServiceData.getItemById(referencingComponent.id);
|
||||
|
||||
// create the markup for the references
|
||||
createReferencingComponents(referencingServiceReferencesContainer, referencingService.referencingComponents);
|
||||
createReferencingComponents(serviceTable, referencingServiceReferencesContainer, referencingService.referencingComponents);
|
||||
} else {
|
||||
referencingServiceReferencesContainer.empty();
|
||||
}
|
||||
|
@ -572,12 +577,13 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Sets whether the specified controller service is enabled.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
* @param {boolean} enabled
|
||||
* @param {function} pollCondition
|
||||
*/
|
||||
var setEnabled = function (controllerServiceEntity, enabled, pollCondition) {
|
||||
var setEnabled = function (serviceTable, controllerServiceEntity, enabled, pollCondition) {
|
||||
// build the request entity
|
||||
var updateControllerServiceEntity = {
|
||||
'revision': nf.Client.getRevision(controllerServiceEntity),
|
||||
|
@ -594,7 +600,7 @@ nf.ControllerService = (function () {
|
|||
dataType: 'json',
|
||||
contentType: 'application/json'
|
||||
}).done(function (response) {
|
||||
renderControllerService(response);
|
||||
renderControllerService(serviceTable, response);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
|
||||
// wait until the polling of each service finished
|
||||
|
@ -663,12 +669,13 @@ nf.ControllerService = (function () {
|
|||
/**
|
||||
* Updates the scheduled state of the processors/reporting tasks referencing
|
||||
* the specified controller service.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
* @param {boolean} running
|
||||
* @param {function} pollCondition
|
||||
*/
|
||||
var updateReferencingSchedulableComponents = function (controllerServiceEntity, running, pollCondition) {
|
||||
var updateReferencingSchedulableComponents = function (serviceTable, controllerServiceEntity, running, pollCondition) {
|
||||
var referenceEntity = {
|
||||
'id': controllerServiceEntity.id,
|
||||
'state': running ? 'RUNNING' : 'STOPPED',
|
||||
|
@ -705,7 +712,7 @@ nf.ControllerService = (function () {
|
|||
var services = getReferencingControllerServiceIds(controllerServiceEntity.component);
|
||||
|
||||
// get the controller service grid
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
|
||||
// start polling for each controller service
|
||||
|
@ -933,12 +940,13 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Updates the referencing services with the specified state.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
* @param {boolean} enabled
|
||||
* @param {function} pollCondition
|
||||
*/
|
||||
var updateReferencingServices = function (controllerServiceEntity, enabled, pollCondition) {
|
||||
var updateReferencingServices = function (serviceTable, controllerServiceEntity, enabled, pollCondition) {
|
||||
// build the reference entity
|
||||
var referenceEntity = {
|
||||
'id': controllerServiceEntity.id,
|
||||
|
@ -972,7 +980,7 @@ nf.ControllerService = (function () {
|
|||
var services = getReferencingControllerServiceIds(controllerServiceEntity.component);
|
||||
|
||||
// get the controller service grid
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
|
||||
// start polling for each controller service
|
||||
|
@ -1003,14 +1011,14 @@ nf.ControllerService = (function () {
|
|||
*
|
||||
* @argument {object} controllerService The controller service to disable
|
||||
*/
|
||||
var showDisableControllerServiceDialog = function (controllerService) {
|
||||
var showDisableControllerServiceDialog = function (serviceTable, controllerService) {
|
||||
// populate the disable controller service dialog
|
||||
$('#disable-controller-service-id').text(controllerService.id);
|
||||
$('#disable-controller-service-name').text(controllerService.name);
|
||||
|
||||
// load the controller referencing components list
|
||||
var referencingComponentsContainer = $('#disable-controller-service-referencing-components');
|
||||
createReferencingComponents(referencingComponentsContainer, controllerService.referencingComponents);
|
||||
createReferencingComponents(serviceTable, referencingComponentsContainer, controllerService.referencingComponents);
|
||||
|
||||
var hasUnauthorized = false;
|
||||
$.each(controllerService.referencingComponents, function (_, referencingComponent) {
|
||||
|
@ -1026,7 +1034,9 @@ nf.ControllerService = (function () {
|
|||
buttons.push({
|
||||
buttonText: 'Disable',
|
||||
handler: {
|
||||
click: disableHandler
|
||||
click: function () {
|
||||
disableHandler(serviceTable);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1051,20 +1061,36 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Shows the dialog for enabling a controller service.
|
||||
*
|
||||
*
|
||||
* @param {object} serviceTable
|
||||
* @param {object} controllerService
|
||||
*/
|
||||
var showEnableControllerServiceDialog = function (controllerService) {
|
||||
var showEnableControllerServiceDialog = function (serviceTable, controllerService) {
|
||||
// populate the disable controller service dialog
|
||||
$('#enable-controller-service-id').text(controllerService.id);
|
||||
$('#enable-controller-service-name').text(controllerService.name);
|
||||
|
||||
// load the controller referencing components list
|
||||
var referencingComponentsContainer = $('#enable-controller-service-referencing-components');
|
||||
createReferencingComponents(referencingComponentsContainer, controllerService.referencingComponents);
|
||||
createReferencingComponents(serviceTable, referencingComponentsContainer, controllerService.referencingComponents);
|
||||
|
||||
// build the button model
|
||||
var buttons = [{
|
||||
buttonText: 'Enable',
|
||||
handler: {
|
||||
click: function () {
|
||||
enableHandler(serviceTable);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
handler: {
|
||||
click: closeModal
|
||||
}
|
||||
}];
|
||||
|
||||
// show the dialog
|
||||
$('#enable-controller-service-dialog').modal('show');
|
||||
$('#enable-controller-service-dialog').modal('setButtonModel', buttons).modal('show');
|
||||
|
||||
// load the bulletins
|
||||
queryBulletins([controllerService.id]).done(function(response) {
|
||||
|
@ -1084,9 +1110,11 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Handles the disable action of the disable controller service dialog.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
var disableHandler = function() {
|
||||
var disableDialog = $(this);
|
||||
var disableHandler = function(serviceTable) {
|
||||
var disableDialog = $('#disable-controller-service-dialog');
|
||||
var canceled = false;
|
||||
|
||||
// only provide a cancel option
|
||||
|
@ -1107,7 +1135,7 @@ nf.ControllerService = (function () {
|
|||
|
||||
// get the controller service
|
||||
var controllerServiceId = $('#disable-controller-service-id').text();
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
var controllerServiceEntity = controllerServiceData.getItemById(controllerServiceId);
|
||||
var controllerService = controllerServiceEntity.component;
|
||||
|
@ -1133,7 +1161,7 @@ nf.ControllerService = (function () {
|
|||
|
||||
$.Deferred(function (deferred) {
|
||||
// stop all referencing schedulable components
|
||||
var stopped = updateReferencingSchedulableComponents(controllerServiceEntity, false, continuePolling);
|
||||
var stopped = updateReferencingSchedulableComponents(serviceTable, controllerServiceEntity, false, continuePolling);
|
||||
|
||||
// once everything has stopped
|
||||
stopped.done(function () {
|
||||
|
@ -1141,7 +1169,7 @@ nf.ControllerService = (function () {
|
|||
var disableReferencingServices = $('#disable-referencing-services').addClass('ajax-loading');
|
||||
|
||||
// disable all referencing services
|
||||
var disabled = updateReferencingServices(controllerServiceEntity, false, continuePolling);
|
||||
var disabled = updateReferencingServices(serviceTable, controllerServiceEntity, false, continuePolling);
|
||||
|
||||
// everything is disabled
|
||||
disabled.done(function () {
|
||||
|
@ -1149,7 +1177,7 @@ nf.ControllerService = (function () {
|
|||
var disableControllerService = $('#disable-controller-service').addClass('ajax-loading');
|
||||
|
||||
// disable this service
|
||||
setEnabled(controllerServiceEntity, false, continuePolling).done(function () {
|
||||
setEnabled(serviceTable, controllerServiceEntity, false, continuePolling).done(function () {
|
||||
deferred.resolve();
|
||||
disableControllerService.removeClass('ajax-loading').addClass('ajax-complete');
|
||||
}).fail(function () {
|
||||
|
@ -1165,7 +1193,7 @@ nf.ControllerService = (function () {
|
|||
disableReferencingSchedulable.removeClass('ajax-loading').addClass('ajax-error');
|
||||
});
|
||||
}).always(function () {
|
||||
reloadControllerServiceAndReferencingComponents(controllerService);
|
||||
reloadControllerServiceAndReferencingComponents(serviceTable, controllerService);
|
||||
setCloseButton();
|
||||
|
||||
// inform the user if the action was canceled
|
||||
|
@ -1181,14 +1209,16 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Handles the enable action of the enable controller service dialog.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
var enableHandler = function() {
|
||||
var enableDialog = $(this);
|
||||
var enableHandler = function(serviceTable) {
|
||||
var enableDialog = $('#enable-controller-service-dialog');
|
||||
var canceled = false;
|
||||
|
||||
// get the controller service
|
||||
var controllerServiceId = $('#enable-controller-service-id').text();
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
var controllerServiceEntity = controllerServiceData.getItemById(controllerServiceId);
|
||||
var controllerService = controllerServiceEntity.component;
|
||||
|
@ -1256,7 +1286,7 @@ nf.ControllerService = (function () {
|
|||
|
||||
$.Deferred(function (deferred) {
|
||||
// enable this controller service
|
||||
var enable = setEnabled(controllerServiceEntity, true, continuePolling);
|
||||
var enable = setEnabled(serviceTable, controllerServiceEntity, true, continuePolling);
|
||||
|
||||
if (scope === config.serviceAndReferencingComponents) {
|
||||
// once the service is enabled, activate all referencing components
|
||||
|
@ -1265,7 +1295,7 @@ nf.ControllerService = (function () {
|
|||
var enableReferencingServices = $('#enable-referencing-services').addClass('ajax-loading');
|
||||
|
||||
// enable the referencing services
|
||||
var servicesEnabled = updateReferencingServices(controllerServiceEntity, true, continuePolling);
|
||||
var servicesEnabled = updateReferencingServices(serviceTable, controllerServiceEntity, true, continuePolling);
|
||||
|
||||
// once all the referencing services are enbled
|
||||
servicesEnabled.done(function () {
|
||||
|
@ -1273,7 +1303,7 @@ nf.ControllerService = (function () {
|
|||
var enableReferencingSchedulable = $('#enable-referencing-schedulable').addClass('ajax-loading');
|
||||
|
||||
// start all referencing schedulable components
|
||||
updateReferencingSchedulableComponents(controllerServiceEntity, true, continuePolling).done(function() {
|
||||
updateReferencingSchedulableComponents(serviceTable, controllerServiceEntity, true, continuePolling).done(function() {
|
||||
deferred.resolve();
|
||||
enableReferencingSchedulable.removeClass('ajax-loading').addClass('ajax-complete');
|
||||
}).fail(function () {
|
||||
|
@ -1298,7 +1328,7 @@ nf.ControllerService = (function () {
|
|||
});
|
||||
}
|
||||
}).always(function () {
|
||||
reloadControllerServiceAndReferencingComponents(controllerService);
|
||||
reloadControllerServiceAndReferencingComponents(serviceTable, controllerService);
|
||||
setCloseButton();
|
||||
|
||||
// inform the user if the action was canceled
|
||||
|
@ -1331,8 +1361,10 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Goes to a service configuration from the property table.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
var goToServiceFromProperty = function () {
|
||||
var goToServiceFromProperty = function (serviceTable) {
|
||||
return $.Deferred(function (deferred) {
|
||||
// close all fields currently being edited
|
||||
$('#controller-service-properties').propertytable('saveRow');
|
||||
|
@ -1348,7 +1380,7 @@ nf.ControllerService = (function () {
|
|||
},
|
||||
yesHandler: function () {
|
||||
var controllerServiceEntity = $('#controller-service-configuration').data('controllerServiceDetails');
|
||||
saveControllerService(controllerServiceEntity).done(function () {
|
||||
saveControllerService(serviceTable, controllerServiceEntity).done(function () {
|
||||
deferred.resolve();
|
||||
}).fail(function () {
|
||||
deferred.reject();
|
||||
|
@ -1361,7 +1393,7 @@ nf.ControllerService = (function () {
|
|||
}).promise();
|
||||
};
|
||||
|
||||
var saveControllerService = function (controllerServiceEntity) {
|
||||
var saveControllerService = function (serviceTable, controllerServiceEntity) {
|
||||
// marshal the settings and properties and update the controller service
|
||||
var updatedControllerService = marshalDetails();
|
||||
|
||||
|
@ -1391,11 +1423,11 @@ nf.ControllerService = (function () {
|
|||
contentType: 'application/json'
|
||||
}).done(function (response) {
|
||||
// reload the controller service
|
||||
renderControllerService(response);
|
||||
renderControllerService(serviceTable, response);
|
||||
|
||||
// reload all previously referenced controller services
|
||||
$.each(previouslyReferencedServiceIds, function(_, oldServiceReferenceId) {
|
||||
reloadControllerService(oldServiceReferenceId);
|
||||
reloadControllerService(serviceTable, oldServiceReferenceId);
|
||||
});
|
||||
}).fail(handleControllerServiceConfigurationError);
|
||||
} else {
|
||||
|
@ -1480,7 +1512,7 @@ nf.ControllerService = (function () {
|
|||
});
|
||||
|
||||
// initialize the conroller service configuration dialog
|
||||
$('#controller-service-configuration').data('mode', config.edit).modal({
|
||||
$('#controller-service-configuration').modal({
|
||||
headerText: 'Configure Controller Service',
|
||||
overlayBackground: false,
|
||||
handler: {
|
||||
|
@ -1506,15 +1538,6 @@ nf.ControllerService = (function () {
|
|||
}
|
||||
});
|
||||
|
||||
// initialize the property table
|
||||
$('#controller-service-properties').propertytable({
|
||||
readOnly: false,
|
||||
groupId: nf.Canvas.getGroupId(),
|
||||
dialogContainer: '#new-controller-service-property-container',
|
||||
descriptorDeferred: getControllerServicePropertyDescriptor,
|
||||
goToServiceDeferred: goToServiceFromProperty
|
||||
});
|
||||
|
||||
// initialize the disable service dialog
|
||||
$('#disable-controller-service-dialog').modal({
|
||||
headerText: 'Disable Controller Service',
|
||||
|
@ -1543,19 +1566,6 @@ nf.ControllerService = (function () {
|
|||
nf.Common.cleanUpTooltips(referencingComponents, 'div.referencing-component-state');
|
||||
nf.Common.cleanUpTooltips(referencingComponents, 'div.referencing-component-bulletins');
|
||||
referencingComponents.css('border-width', '0').empty();
|
||||
|
||||
// reset dialog
|
||||
disableDialog.modal('setButtonModel', [{
|
||||
buttonText: 'Disable',
|
||||
handler: {
|
||||
click: disableHandler
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
handler: {
|
||||
click: closeModal
|
||||
}
|
||||
}]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1577,17 +1587,6 @@ nf.ControllerService = (function () {
|
|||
$('#enable-controller-service-dialog').modal({
|
||||
headerText: 'Enable Controller Service',
|
||||
overlayBackground: false,
|
||||
buttons: [{
|
||||
buttonText: 'Enable',
|
||||
handler: {
|
||||
click: enableHandler
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
handler: {
|
||||
click: closeModal
|
||||
}
|
||||
}],
|
||||
handler: {
|
||||
close: function() {
|
||||
var enableDialog = $(this);
|
||||
|
@ -1613,19 +1612,6 @@ nf.ControllerService = (function () {
|
|||
nf.Common.cleanUpTooltips(referencingComponents, 'div.referencing-component-state');
|
||||
nf.Common.cleanUpTooltips(referencingComponents, 'div.referencing-component-bulletins');
|
||||
referencingComponents.css('border-width', '0').empty();
|
||||
|
||||
// reset dialog
|
||||
enableDialog.modal('setButtonModel', [{
|
||||
buttonText: 'Enable',
|
||||
handler: {
|
||||
click: enableHandler
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
handler: {
|
||||
click: closeModal
|
||||
}
|
||||
}]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -1633,23 +1619,26 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Shows the configuration dialog for the specified controller service.
|
||||
*
|
||||
*
|
||||
* @argument {jQuery} serviceTable The controller service table
|
||||
* @argument {object} controllerServiceEntity The controller service
|
||||
*/
|
||||
showConfiguration: function (controllerServiceEntity) {
|
||||
showConfiguration: function (serviceTable, controllerServiceEntity) {
|
||||
var controllerServiceDialog = $('#controller-service-configuration');
|
||||
if (controllerServiceDialog.data('mode') === config.readOnly) {
|
||||
if (controllerServiceDialog.data('mode') !== config.edit) {
|
||||
// update the visibility
|
||||
$('#controller-service-configuration .controller-service-read-only').hide();
|
||||
$('#controller-service-configuration .controller-service-editable').show();
|
||||
|
||||
|
||||
// initialize the property table
|
||||
$('#controller-service-properties').propertytable('destroy').propertytable({
|
||||
readOnly: false,
|
||||
groupId: nf.Canvas.getGroupId(),
|
||||
dialogContainer: '#new-controller-service-property-container',
|
||||
descriptorDeferred: getControllerServicePropertyDescriptor,
|
||||
goToServiceDeferred: goToServiceFromProperty
|
||||
goToServiceDeferred: function () {
|
||||
return goToServiceFromProperty(serviceTable);
|
||||
}
|
||||
});
|
||||
|
||||
// update the mode
|
||||
|
@ -1692,7 +1681,7 @@ nf.ControllerService = (function () {
|
|||
var referenceContainer = $('#controller-service-referencing-components');
|
||||
|
||||
// load the controller referencing components list
|
||||
createReferencingComponents(referenceContainer, controllerService.referencingComponents);
|
||||
createReferencingComponents(serviceTable, referenceContainer, controllerService.referencingComponents);
|
||||
|
||||
var buttons = [{
|
||||
buttonText: 'Apply',
|
||||
|
@ -1702,8 +1691,8 @@ nf.ControllerService = (function () {
|
|||
$('#controller-service-properties').propertytable('saveRow');
|
||||
|
||||
// save the controller service
|
||||
saveControllerService(controllerServiceEntity).done(function (response) {
|
||||
reloadControllerServiceReferences(response.component);
|
||||
saveControllerService(serviceTable, controllerServiceEntity).done(function (response) {
|
||||
reloadControllerServiceReferences(serviceTable, response.component);
|
||||
|
||||
// close the details panel
|
||||
controllerServiceDialog.modal('hide');
|
||||
|
@ -1735,7 +1724,7 @@ nf.ControllerService = (function () {
|
|||
// show the custom ui
|
||||
nf.CustomUi.showCustomUi($('#controller-service-id').text(), controllerService.customUiUrl, true).done(function () {
|
||||
// once the custom ui is closed, reload the controller service
|
||||
reloadControllerServiceAndReferencingComponents(controllerService);
|
||||
reloadControllerServiceAndReferencingComponents(serviceTable, controllerService);
|
||||
|
||||
// show the settings
|
||||
nf.Settings.showSettings();
|
||||
|
@ -1753,7 +1742,7 @@ nf.ControllerService = (function () {
|
|||
overlayBackground: false,
|
||||
noHandler: openCustomUi,
|
||||
yesHandler: function () {
|
||||
saveControllerService(controllerServiceEntity).done(function () {
|
||||
saveControllerService(serviceTable, controllerServiceEntity).done(function () {
|
||||
// open the custom ui
|
||||
openCustomUi();
|
||||
});
|
||||
|
@ -1784,12 +1773,13 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Shows the controller service details in a read only dialog.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
*/
|
||||
showDetails: function(controllerServiceEntity) {
|
||||
showDetails: function(serviceTable, controllerServiceEntity) {
|
||||
var controllerServiceDialog = $('#controller-service-configuration');
|
||||
if (controllerServiceDialog.data('mode') === config.edit) {
|
||||
if (controllerServiceDialog.data('mode') !== config.readOnly) {
|
||||
// update the visibility
|
||||
$('#controller-service-configuration .controller-service-read-only').show();
|
||||
$('#controller-service-configuration .controller-service-editable').hide();
|
||||
|
@ -1839,7 +1829,7 @@ nf.ControllerService = (function () {
|
|||
var referenceContainer = $('#controller-service-referencing-components');
|
||||
|
||||
// load the controller referencing components list
|
||||
createReferencingComponents(referenceContainer, controllerService.referencingComponents);
|
||||
createReferencingComponents(serviceTable, referenceContainer, controllerService.referencingComponents);
|
||||
|
||||
var buttons = [{
|
||||
buttonText: 'Ok',
|
||||
|
@ -1888,41 +1878,45 @@ nf.ControllerService = (function () {
|
|||
|
||||
/**
|
||||
* Enables the specified controller service.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
*/
|
||||
enable: function(controllerServiceEntity) {
|
||||
showEnableControllerServiceDialog(controllerServiceEntity.component);
|
||||
enable: function(serviceTable, controllerServiceEntity) {
|
||||
showEnableControllerServiceDialog(serviceTable, controllerServiceEntity.component);
|
||||
},
|
||||
|
||||
/**
|
||||
* Disables the specified controller service.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
*/
|
||||
disable: function(controllerServiceEntity) {
|
||||
showDisableControllerServiceDialog(controllerServiceEntity.component);
|
||||
disable: function(serviceTable, controllerServiceEntity) {
|
||||
showDisableControllerServiceDialog(serviceTable, controllerServiceEntity.component);
|
||||
},
|
||||
|
||||
/**
|
||||
* Reloads the services that the specified comonent references. This is
|
||||
* necessary because the specified component state is reflected in the
|
||||
* referenced service referencing components.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} component
|
||||
*/
|
||||
reloadReferencedServices: function(component) {
|
||||
reloadReferencedServices: function(serviceTable, component) {
|
||||
$.each(getReferencedServices(component), function (_, referencedServiceId) {
|
||||
reloadControllerService(referencedServiceId);
|
||||
reloadControllerService(serviceTable, referencedServiceId);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes the specified controller service.
|
||||
*
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceEntity
|
||||
*/
|
||||
remove: function(controllerServiceEntity) {
|
||||
remove: function(serviceTable, controllerServiceEntity) {
|
||||
// prompt for removal?
|
||||
|
||||
var revision = nf.Client.getRevision(controllerServiceEntity);
|
||||
|
@ -1935,12 +1929,12 @@ nf.ControllerService = (function () {
|
|||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
// remove the service
|
||||
var controllerServiceGrid = $('#controller-services-table').data('gridInstance');
|
||||
var controllerServiceGrid = serviceTable.data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
controllerServiceData.deleteItem(controllerServiceEntity.id);
|
||||
|
||||
// reload the as necessary
|
||||
reloadControllerServiceReferences(controllerServiceEntity.component);
|
||||
reloadControllerServiceReferences(serviceTable, controllerServiceEntity.component);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -0,0 +1,883 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* global nf, Slick, d3 */
|
||||
|
||||
nf.ControllerServices = (function () {
|
||||
|
||||
var dblClick = null;
|
||||
var initialized = false;
|
||||
|
||||
var config = {
|
||||
filterText: 'Filter',
|
||||
styles: {
|
||||
filterList: 'filter-list'
|
||||
},
|
||||
urls: {
|
||||
api: '../nifi-api',
|
||||
controllerServiceTypes: '../nifi-api/flow/controller-service-types'
|
||||
}
|
||||
};
|
||||
|
||||
var gridOptions = {
|
||||
forceFitColumns: true,
|
||||
enableTextSelectionOnCells: true,
|
||||
enableCellNavigation: true,
|
||||
enableColumnReorder: false,
|
||||
autoEdit: false,
|
||||
multiSelect: false
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the text out of the filter field. If the filter field doesn't
|
||||
* have any text it will contain the text 'filter list' so this method
|
||||
* accounts for that.
|
||||
*/
|
||||
var getControllerServiceTypeFilterText = function () {
|
||||
var filterText = '';
|
||||
var filterField = $('#controller-service-type-filter');
|
||||
if (!filterField.hasClass(config.styles.filterList)) {
|
||||
filterText = filterField.val();
|
||||
}
|
||||
return filterText;
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters the processor type table.
|
||||
*/
|
||||
var applyControllerServiceTypeFilter = function () {
|
||||
// get the dataview
|
||||
var controllerServiceTypesGrid = $('#controller-service-types-table').data('gridInstance');
|
||||
|
||||
// ensure the grid has been initialized
|
||||
if (nf.Common.isDefinedAndNotNull(controllerServiceTypesGrid)) {
|
||||
var controllerServiceTypesData = controllerServiceTypesGrid.getData();
|
||||
|
||||
// update the search criteria
|
||||
controllerServiceTypesData.setFilterArgs({
|
||||
searchString: getControllerServiceTypeFilterText()
|
||||
});
|
||||
controllerServiceTypesData.refresh();
|
||||
|
||||
// update the selection if possible
|
||||
if (controllerServiceTypesData.getLength() > 0) {
|
||||
controllerServiceTypesGrid.setSelectedRows([0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the selected controller service.
|
||||
*/
|
||||
var clearSelectedControllerService = function () {
|
||||
$('#controller-service-type-description').text('');
|
||||
$('#controller-service-type-name').text('');
|
||||
$('#selected-controller-service-name').text('');
|
||||
$('#selected-controller-service-type').text('');
|
||||
$('#controller-service-description-container').hide();
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the selected controller service type.
|
||||
*/
|
||||
var clearControllerServiceSelection = function () {
|
||||
// clear the selected row
|
||||
clearSelectedControllerService();
|
||||
|
||||
// clear the active cell the it can be reselected when its included
|
||||
var controllerServiceTypesGrid = $('#controller-service-types-table').data('gridInstance');
|
||||
controllerServiceTypesGrid.resetActiveCell();
|
||||
};
|
||||
|
||||
/**
|
||||
* Performs the filtering.
|
||||
*
|
||||
* @param {object} item The item subject to filtering
|
||||
* @param {object} args Filter arguments
|
||||
* @returns {Boolean} Whether or not to include the item
|
||||
*/
|
||||
var filterControllerServiceTypes = function (item, args) {
|
||||
// determine if the item matches the filter
|
||||
var matchesFilter = matchesRegex(item, args);
|
||||
|
||||
// determine if the row matches the selected tags
|
||||
var matchesTags = true;
|
||||
if (matchesFilter) {
|
||||
var tagFilters = $('#controller-service-tag-cloud').tagcloud('getSelectedTags');
|
||||
var hasSelectedTags = tagFilters.length > 0;
|
||||
if (hasSelectedTags) {
|
||||
matchesTags = matchesSelectedTags(tagFilters, item['tags']);
|
||||
}
|
||||
}
|
||||
|
||||
// determine if this row should be visible
|
||||
var matches = matchesFilter && matchesTags;
|
||||
|
||||
// if this row is currently selected and its being filtered
|
||||
if (matches === false && $('#selected-controller-service-type').text() === item['type']) {
|
||||
clearControllerServiceSelection();
|
||||
}
|
||||
|
||||
return matches;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the item matches the filter.
|
||||
*
|
||||
* @param {object} item The item to filter
|
||||
* @param {object} args The filter criteria
|
||||
* @returns {boolean} Whether the item matches the filter
|
||||
*/
|
||||
var matchesRegex = function (item, args) {
|
||||
if (args.searchString === '') {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// perform the row filtering
|
||||
var filterExp = new RegExp(args.searchString, 'i');
|
||||
} catch (e) {
|
||||
// invalid regex
|
||||
return false;
|
||||
}
|
||||
|
||||
// determine if the item matches the filter
|
||||
var matchesLabel = item['label'].search(filterExp) >= 0;
|
||||
var matchesTags = item['tags'].search(filterExp) >= 0;
|
||||
return matchesLabel || matchesTags;
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the specified tags match all the tags selected by the user.
|
||||
*
|
||||
* @argument {string[]} tagFilters The tag filters
|
||||
* @argument {string} tags The tags to test
|
||||
*/
|
||||
var matchesSelectedTags = function (tagFilters, tags) {
|
||||
var selectedTags = [];
|
||||
$.each(tagFilters, function (_, filter) {
|
||||
selectedTags.push(filter);
|
||||
});
|
||||
|
||||
// normalize the tags
|
||||
var normalizedTags = tags.toLowerCase();
|
||||
|
||||
var matches = true;
|
||||
$.each(selectedTags, function (i, selectedTag) {
|
||||
if (normalizedTags.indexOf(selectedTag) === -1) {
|
||||
matches = false;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return matches;
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds the currently selected controller service.
|
||||
*
|
||||
* @param {string} controllerServicesUri
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
var addSelectedControllerService = function (controllerServicesUri, serviceTable) {
|
||||
var selectedServiceType = $('#selected-controller-service-type').text();
|
||||
|
||||
// ensure something was selected
|
||||
if (selectedServiceType === '') {
|
||||
nf.Dialog.showOkDialog({
|
||||
dialogContent: 'The type of controller service to create must be selected.',
|
||||
overlayBackground: false
|
||||
});
|
||||
} else {
|
||||
addControllerService(controllerServicesUri, serviceTable, selectedServiceType);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds a new controller service of the specified type.
|
||||
*
|
||||
* @param {string} controllerServicesUri
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {string} controllerServiceType
|
||||
*/
|
||||
var addControllerService = function (controllerServicesUri, serviceTable, controllerServiceType) {
|
||||
// build the controller service entity
|
||||
var controllerServiceEntity = {
|
||||
'component': {
|
||||
'type': controllerServiceType
|
||||
}
|
||||
};
|
||||
|
||||
// add the new controller service
|
||||
var addService = $.ajax({
|
||||
type: 'POST',
|
||||
url: controllerServicesUri,
|
||||
data: JSON.stringify(controllerServiceEntity),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json'
|
||||
}).done(function (controllerServiceEntity) {
|
||||
// add the item
|
||||
var controllerServicesGrid = serviceTable.data('gridInstance');
|
||||
var controllerServicesData = controllerServicesGrid.getData();
|
||||
controllerServicesData.addItem(controllerServiceEntity);
|
||||
|
||||
// resort
|
||||
controllerServicesData.reSort();
|
||||
controllerServicesGrid.invalidate();
|
||||
|
||||
// select the new controller service
|
||||
var row = controllerServicesData.getRowById(controllerServiceEntity.id);
|
||||
controllerServicesGrid.setSelectedRows([row]);
|
||||
controllerServicesGrid.scrollRowIntoView(row);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
|
||||
// hide the dialog
|
||||
$('#new-controller-service-dialog').modal('hide');
|
||||
|
||||
return addService;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the new controller service dialog.
|
||||
*/
|
||||
var initNewControllerServiceDialog = function () {
|
||||
// define the function for filtering the list
|
||||
$('#controller-service-type-filter').focus(function () {
|
||||
if ($(this).hasClass(config.styles.filterList)) {
|
||||
$(this).removeClass(config.styles.filterList).val('');
|
||||
}
|
||||
}).blur(function () {
|
||||
if ($(this).val() === '') {
|
||||
$(this).addClass(config.styles.filterList).val(config.filterText);
|
||||
}
|
||||
}).addClass(config.styles.filterList).val(config.filterText);
|
||||
|
||||
// initialize the processor type table
|
||||
var controllerServiceTypesColumns = [
|
||||
{id: 'type', name: 'Type', field: 'label', sortable: false, resizable: true},
|
||||
{id: 'tags', name: 'Tags', field: 'tags', sortable: false, resizable: true}
|
||||
];
|
||||
|
||||
// initialize the dataview
|
||||
var controllerServiceTypesData = new Slick.Data.DataView({
|
||||
inlineFilters: false
|
||||
});
|
||||
controllerServiceTypesData.setItems([]);
|
||||
controllerServiceTypesData.setFilterArgs({
|
||||
searchString: getControllerServiceTypeFilterText()
|
||||
});
|
||||
controllerServiceTypesData.setFilter(filterControllerServiceTypes);
|
||||
|
||||
// initialize the grid
|
||||
var controllerServiceTypesGrid = new Slick.Grid('#controller-service-types-table', controllerServiceTypesData, controllerServiceTypesColumns, gridOptions);
|
||||
controllerServiceTypesGrid.setSelectionModel(new Slick.RowSelectionModel());
|
||||
controllerServiceTypesGrid.registerPlugin(new Slick.AutoTooltips());
|
||||
controllerServiceTypesGrid.setSortColumn('type', true);
|
||||
controllerServiceTypesGrid.onSelectedRowsChanged.subscribe(function (e, args) {
|
||||
if ($.isArray(args.rows) && args.rows.length === 1) {
|
||||
var controllerServiceTypeIndex = args.rows[0];
|
||||
var controllerServiceType = controllerServiceTypesGrid.getDataItem(controllerServiceTypeIndex);
|
||||
|
||||
// set the controller service type description
|
||||
if (nf.Common.isDefinedAndNotNull(controllerServiceType)) {
|
||||
if (nf.Common.isBlank(controllerServiceType.description)) {
|
||||
$('#controller-service-type-description').attr('title', '').html('<span class="unset">No description specified</span>');
|
||||
} else {
|
||||
$('#controller-service-type-description').html(controllerServiceType.description).ellipsis();
|
||||
}
|
||||
|
||||
// populate the dom
|
||||
$('#controller-service-type-name').text(controllerServiceType.label).ellipsis();
|
||||
$('#selected-controller-service-name').text(controllerServiceType.label);
|
||||
$('#selected-controller-service-type').text(controllerServiceType.type);
|
||||
|
||||
// show the selected controller service
|
||||
$('#controller-service-description-container').show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// wire up the dataview to the grid
|
||||
controllerServiceTypesData.onRowCountChanged.subscribe(function (e, args) {
|
||||
controllerServiceTypesGrid.updateRowCount();
|
||||
controllerServiceTypesGrid.render();
|
||||
|
||||
// update the total number of displayed processors
|
||||
$('#displayed-controller-service-types').text(args.current);
|
||||
});
|
||||
controllerServiceTypesData.onRowsChanged.subscribe(function (e, args) {
|
||||
controllerServiceTypesGrid.invalidateRows(args.rows);
|
||||
controllerServiceTypesGrid.render();
|
||||
});
|
||||
controllerServiceTypesData.syncGridSelection(controllerServiceTypesGrid, true);
|
||||
|
||||
// hold onto an instance of the grid
|
||||
$('#controller-service-types-table').data('gridInstance', controllerServiceTypesGrid);
|
||||
|
||||
// load the available controller services
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: config.urls.controllerServiceTypes,
|
||||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
var id = 0;
|
||||
var tags = [];
|
||||
|
||||
// begin the update
|
||||
controllerServiceTypesData.beginUpdate();
|
||||
|
||||
// go through each controller service type
|
||||
$.each(response.controllerServiceTypes, function (i, documentedType) {
|
||||
// add the documented type
|
||||
controllerServiceTypesData.addItem({
|
||||
id: id++,
|
||||
label: nf.Common.substringAfterLast(documentedType.type, '.'),
|
||||
type: documentedType.type,
|
||||
description: nf.Common.escapeHtml(documentedType.description),
|
||||
tags: documentedType.tags.join(', ')
|
||||
});
|
||||
|
||||
// count the frequency of each tag for this type
|
||||
$.each(documentedType.tags, function (i, tag) {
|
||||
tags.push(tag.toLowerCase());
|
||||
});
|
||||
});
|
||||
|
||||
// end the udpate
|
||||
controllerServiceTypesData.endUpdate();
|
||||
|
||||
// set the total number of processors
|
||||
$('#total-controller-service-types, #displayed-controller-service-types').text(response.controllerServiceTypes.length);
|
||||
|
||||
// create the tag cloud
|
||||
$('#controller-service-tag-cloud').tagcloud({
|
||||
tags: tags,
|
||||
select: applyControllerServiceTypeFilter,
|
||||
remove: applyControllerServiceTypeFilter
|
||||
});
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
|
||||
// initialize the controller service dialog
|
||||
$('#new-controller-service-dialog').modal({
|
||||
headerText: 'Add Controller Service',
|
||||
overlayBackground: false,
|
||||
handler: {
|
||||
close: function () {
|
||||
// clear the selected row
|
||||
clearSelectedControllerService();
|
||||
|
||||
// clear any filter strings
|
||||
$('#controller-service-type-filter').addClass(config.styles.filterList).val(config.filterText);
|
||||
|
||||
// clear the tagcloud
|
||||
$('#controller-service-tag-cloud').tagcloud('clearSelectedTags');
|
||||
|
||||
// reset the filter
|
||||
applyControllerServiceTypeFilter();
|
||||
|
||||
// unselect any current selection
|
||||
var controllerServiceTypesGrid = $('#controller-service-types-table').data('gridInstance');
|
||||
controllerServiceTypesGrid.setSelectedRows([]);
|
||||
controllerServiceTypesGrid.resetActiveCell();
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatter for the name column.
|
||||
*
|
||||
* @param {type} row
|
||||
* @param {type} cell
|
||||
* @param {type} value
|
||||
* @param {type} columnDef
|
||||
* @param {type} dataContext
|
||||
* @returns {String}
|
||||
*/
|
||||
var nameFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
if (!dataContext.accessPolicy.canRead) {
|
||||
return '<span class="blank">' + dataContext.id + '</span>';
|
||||
}
|
||||
|
||||
return dataContext.component.name;
|
||||
};
|
||||
|
||||
/**
|
||||
* Formatter for the type column.
|
||||
*
|
||||
* @param {type} row
|
||||
* @param {type} cell
|
||||
* @param {type} value
|
||||
* @param {type} columnDef
|
||||
* @param {type} dataContext
|
||||
* @returns {String}
|
||||
*/
|
||||
var typeFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
if (!dataContext.accessPolicy.canRead) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return nf.Common.substringAfterLast(dataContext.component.type, '.');
|
||||
};
|
||||
|
||||
/**
|
||||
* Sorts the specified data using the specified sort details.
|
||||
*
|
||||
* @param {object} sortDetails
|
||||
* @param {object} data
|
||||
*/
|
||||
var sort = function (sortDetails, data) {
|
||||
// defines a function for sorting
|
||||
var comparer = function (a, b) {
|
||||
if (sortDetails.columnId === 'moreDetails') {
|
||||
var aBulletins = 0;
|
||||
if (!nf.Common.isEmpty(a.bulletins)) {
|
||||
aBulletins = a.bulletins.length;
|
||||
}
|
||||
var bBulletins = 0;
|
||||
if (!nf.Common.isEmpty(b.bulletins)) {
|
||||
bBulletins = b.bulletins.length;
|
||||
}
|
||||
return aBulletins - bBulletins;
|
||||
} else if (sortDetails.columnId === 'type') {
|
||||
var aType = nf.Common.isDefinedAndNotNull(a[sortDetails.columnId]) ? nf.Common.substringAfterLast(a[sortDetails.columnId], '.') : '';
|
||||
var bType = nf.Common.isDefinedAndNotNull(b[sortDetails.columnId]) ? nf.Common.substringAfterLast(b[sortDetails.columnId], '.') : '';
|
||||
return aType === bType ? 0 : aType > bType ? 1 : -1;
|
||||
} else if (sortDetails.columnId === 'state') {
|
||||
var aState = 'Invalid';
|
||||
if (nf.Common.isEmpty(a.validationErrors)) {
|
||||
aState = nf.Common.isDefinedAndNotNull(a[sortDetails.columnId]) ? a[sortDetails.columnId] : '';
|
||||
}
|
||||
var bState = 'Invalid';
|
||||
if (nf.Common.isEmpty(b.validationErrors)) {
|
||||
bState = nf.Common.isDefinedAndNotNull(b[sortDetails.columnId]) ? b[sortDetails.columnId] : '';
|
||||
}
|
||||
return aState === bState ? 0 : aState > bState ? 1 : -1;
|
||||
} else {
|
||||
var aString = nf.Common.isDefinedAndNotNull(a[sortDetails.columnId]) ? a[sortDetails.columnId] : '';
|
||||
var bString = nf.Common.isDefinedAndNotNull(b[sortDetails.columnId]) ? b[sortDetails.columnId] : '';
|
||||
return aString === bString ? 0 : aString > bString ? 1 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
// perform the sort
|
||||
data.sort(comparer, sortDetails.sortAsc);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the controller services tab.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
var initControllerServices = function (serviceTable) {
|
||||
// more details formatter
|
||||
var moreControllerServiceDetails = function (row, cell, value, columnDef, dataContext) {
|
||||
if (!dataContext.accessPolicy.canRead) {
|
||||
return '';
|
||||
}
|
||||
|
||||
var markup = '<img src="images/iconDetails.png" title="View Details" class="pointer view-controller-service" style="margin-top: 5px; float: left;" />';
|
||||
|
||||
// always include a button to view the usage
|
||||
markup += '<img src="images/iconUsage.png" title="Usage" class="pointer controller-service-usage" style="margin-left: 6px; margin-top: 3px; float: left;" />';
|
||||
|
||||
var hasErrors = !nf.Common.isEmpty(dataContext.component.validationErrors);
|
||||
var hasBulletins = !nf.Common.isEmpty(dataContext.component.bulletins);
|
||||
|
||||
if (hasErrors) {
|
||||
markup += '<img src="images/iconAlert.png" class="has-errors" style="margin-top: 4px; margin-left: 3px; float: left;" />';
|
||||
}
|
||||
|
||||
if (hasBulletins) {
|
||||
markup += '<img src="images/iconBulletin.png" class="has-bulletins" style="margin-top: 5px; margin-left: 5px; float: left;"/>';
|
||||
}
|
||||
|
||||
if (hasErrors || hasBulletins) {
|
||||
markup += '<span class="hidden row-id">' + nf.Common.escapeHtml(dataContext.id) + '</span>';
|
||||
}
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
||||
var controllerServiceStateFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
if (!dataContext.accessPolicy.canRead) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// determine the appropriate label
|
||||
var icon = '', label = '';
|
||||
if (!nf.Common.isEmpty(dataContext.component.validationErrors)) {
|
||||
icon = 'invalid';
|
||||
label = 'Invalid';
|
||||
} else {
|
||||
if (dataContext.component.state === 'DISABLED') {
|
||||
icon = 'disabled';
|
||||
label = 'Disabled';
|
||||
} else if (dataContext.component.state === 'DISABLING') {
|
||||
icon = 'disabled';
|
||||
label = 'Disabling';
|
||||
} else if (dataContext.component.state === 'ENABLED') {
|
||||
icon = 'enabled';
|
||||
label = 'Enabled';
|
||||
} else if (dataContext.component.state === 'ENABLING') {
|
||||
icon = 'enabled';
|
||||
label = 'Enabling';
|
||||
}
|
||||
}
|
||||
|
||||
// format the markup
|
||||
var formattedValue = '<div class="' + icon + '" style="margin-top: 3px;"></div>';
|
||||
return formattedValue + '<div class="status-text" style="margin-top: 2px; margin-left: 4px; float: left;">' + label + '</div>';
|
||||
};
|
||||
|
||||
var controllerServiceActionFormatter = function (row, cell, value, columnDef, dataContext) {
|
||||
var markup = '';
|
||||
|
||||
if (dataContext.accessPolicy.canRead && dataContext.accessPolicy.canWrite) {
|
||||
if (dataContext.component.state === 'ENABLED' || dataContext.component.state === 'ENABLING') {
|
||||
markup += '<img src="images/iconDisable.png" title="Disable" class="pointer disable-controller-service" style="margin-top: 2px;" />';
|
||||
} else if (dataContext.component.state === 'DISABLED') {
|
||||
markup += '<img src="images/iconEdit.png" title="Edit" class="pointer edit-controller-service" style="margin-top: 2px;" />';
|
||||
|
||||
// if there are no validation errors allow enabling
|
||||
if (nf.Common.isEmpty(dataContext.component.validationErrors)) {
|
||||
markup += '<img src="images/iconEnable.png" title="Enable" class="pointer enable-controller-service" style="margin-top: 2px; margin-left: 3px;"/>';
|
||||
}
|
||||
|
||||
markup += '<img src="images/iconDelete.png" title="Remove" class="pointer delete-controller-service" style="margin-top: 2px; margin-left: 3px;" />';
|
||||
}
|
||||
|
||||
if (dataContext.component.persistsState === true) {
|
||||
markup += '<img src="images/iconViewState.png" title="View State" class="pointer view-state-controller-service" style="margin-top: 2px; margin-left: 3px;" />';
|
||||
}
|
||||
}
|
||||
|
||||
return markup;
|
||||
};
|
||||
|
||||
// define the column model for the controller services table
|
||||
var controllerServicesColumns = [
|
||||
{id: 'moreDetails', name: ' ', resizable: false, formatter: moreControllerServiceDetails, sortable: true, width: 90, maxWidth: 90, toolTip: 'Sorts based on presence of bulletins'},
|
||||
{id: 'name', name: 'Name', formatter: nameFormatter, sortable: true, resizable: true},
|
||||
{id: 'type', name: 'Type', formatter: typeFormatter, sortable: true, resizable: true},
|
||||
{id: 'state', name: 'State', formatter: controllerServiceStateFormatter, sortable: true, resizeable: true}
|
||||
];
|
||||
|
||||
// action column should always be last
|
||||
controllerServicesColumns.push({id: 'actions', name: ' ', resizable: false, formatter: controllerServiceActionFormatter, sortable: false, width: 90, maxWidth: 90});
|
||||
|
||||
// initialize the dataview
|
||||
var controllerServicesData = new Slick.Data.DataView({
|
||||
inlineFilters: false
|
||||
});
|
||||
controllerServicesData.setItems([]);
|
||||
|
||||
// initialize the sort
|
||||
sort({
|
||||
columnId: 'name',
|
||||
sortAsc: true
|
||||
}, controllerServicesData);
|
||||
|
||||
// initialize the grid
|
||||
var controllerServicesGrid = new Slick.Grid(serviceTable, controllerServicesData, controllerServicesColumns, gridOptions);
|
||||
controllerServicesGrid.setSelectionModel(new Slick.RowSelectionModel());
|
||||
controllerServicesGrid.registerPlugin(new Slick.AutoTooltips());
|
||||
controllerServicesGrid.setSortColumn('name', true);
|
||||
controllerServicesGrid.onSort.subscribe(function (e, args) {
|
||||
sort({
|
||||
columnId: args.sortCol.field,
|
||||
sortAsc: args.sortAsc
|
||||
}, controllerServicesData);
|
||||
});
|
||||
|
||||
// configure a click listener
|
||||
controllerServicesGrid.onClick.subscribe(function (e, args) {
|
||||
var target = $(e.target);
|
||||
|
||||
// get the service at this row
|
||||
var controllerServiceEntity = controllerServicesData.getItem(args.row);
|
||||
|
||||
// determine the desired action
|
||||
if (controllerServicesGrid.getColumns()[args.cell].id === 'actions') {
|
||||
if (target.hasClass('edit-controller-service')) {
|
||||
nf.ControllerService.showConfiguration(serviceTable, controllerServiceEntity);
|
||||
} else if (target.hasClass('enable-controller-service')) {
|
||||
nf.ControllerService.enable(serviceTable, controllerServiceEntity);
|
||||
} else if (target.hasClass('disable-controller-service')) {
|
||||
nf.ControllerService.disable(serviceTable, controllerServiceEntity);
|
||||
} else if (target.hasClass('delete-controller-service')) {
|
||||
nf.ControllerService.remove(serviceTable, controllerServiceEntity);
|
||||
} else if (target.hasClass('view-state-controller-service')) {
|
||||
nf.ComponentState.showState(controllerServiceEntity.component, controllerServiceEntity.state === 'DISABLED');
|
||||
}
|
||||
} else if (controllerServicesGrid.getColumns()[args.cell].id === 'moreDetails') {
|
||||
if (target.hasClass('view-controller-service')) {
|
||||
nf.ControllerService.showDetails(serviceTable, controllerServiceEntity);
|
||||
} else if (target.hasClass('controller-service-usage')) {
|
||||
// close the settings dialog
|
||||
$('#shell-close-button').click();
|
||||
|
||||
// open the documentation for this controller service
|
||||
nf.Shell.showPage('../nifi-docs/documentation?' + $.param({
|
||||
select: nf.Common.substringAfterLast(controllerServiceEntity.component.type, '.')
|
||||
})).done(function() {
|
||||
nf.Settings.showSettings();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// wire up the dataview to the grid
|
||||
controllerServicesData.onRowCountChanged.subscribe(function (e, args) {
|
||||
controllerServicesGrid.updateRowCount();
|
||||
controllerServicesGrid.render();
|
||||
});
|
||||
controllerServicesData.onRowsChanged.subscribe(function (e, args) {
|
||||
controllerServicesGrid.invalidateRows(args.rows);
|
||||
controllerServicesGrid.render();
|
||||
});
|
||||
controllerServicesData.syncGridSelection(controllerServicesGrid, true);
|
||||
|
||||
// hold onto an instance of the grid
|
||||
serviceTable.data('gridInstance', controllerServicesGrid).on('mouseenter', 'div.slick-cell', function (e) {
|
||||
var errorIcon = $(this).find('img.has-errors');
|
||||
if (errorIcon.length && !errorIcon.data('qtip')) {
|
||||
var serviceId = $(this).find('span.row-id').text();
|
||||
|
||||
// get the service item
|
||||
var controllerServiceEntity = controllerServicesData.getItemById(serviceId);
|
||||
|
||||
// format the errors
|
||||
var tooltip = nf.Common.formatUnorderedList(controllerServiceEntity.component.validationErrors);
|
||||
|
||||
// show the tooltip
|
||||
if (nf.Common.isDefinedAndNotNull(tooltip)) {
|
||||
errorIcon.qtip($.extend({
|
||||
content: tooltip,
|
||||
position: {
|
||||
target: 'mouse',
|
||||
viewport: $(window),
|
||||
adjust: {
|
||||
x: 8,
|
||||
y: 8,
|
||||
method: 'flipinvert flipinvert'
|
||||
}
|
||||
}
|
||||
}, nf.Common.config.tooltipConfig));
|
||||
}
|
||||
}
|
||||
|
||||
var bulletinIcon = $(this).find('img.has-bulletins');
|
||||
if (bulletinIcon.length && !bulletinIcon.data('qtip')) {
|
||||
var taskId = $(this).find('span.row-id').text();
|
||||
|
||||
// get the task item
|
||||
var controllerServiceEntity = controllerServicesData.getItemById(taskId);
|
||||
|
||||
// format the tooltip
|
||||
var bulletins = nf.Common.getFormattedBulletins(controllerServiceEntity.component.bulletins);
|
||||
var tooltip = nf.Common.formatUnorderedList(bulletins);
|
||||
|
||||
// show the tooltip
|
||||
if (nf.Common.isDefinedAndNotNull(tooltip)) {
|
||||
bulletinIcon.qtip($.extend({}, nf.Common.config.tooltipConfig, {
|
||||
content: tooltip,
|
||||
position: {
|
||||
target: 'mouse',
|
||||
viewport: $(window),
|
||||
adjust: {
|
||||
x: 8,
|
||||
y: 8,
|
||||
method: 'flipinvert flipinvert'
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads the controller services.
|
||||
*
|
||||
* @param {string} controllerServicesUri
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
var loadControllerServices = function (controllerServicesUri, serviceTable) {
|
||||
return $.ajax({
|
||||
type: 'GET',
|
||||
url: controllerServicesUri,
|
||||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
var services = [];
|
||||
$.each(response.controllerServices, function (_, service) {
|
||||
services.push($.extend({
|
||||
bulletins: []
|
||||
}, service));
|
||||
});
|
||||
|
||||
nf.Common.cleanUpTooltips(serviceTable, 'img.has-errors');
|
||||
nf.Common.cleanUpTooltips(serviceTable, 'img.has-bulletins');
|
||||
|
||||
var controllerServicesGrid = serviceTable.data('gridInstance');
|
||||
var controllerServicesData = controllerServicesGrid.getData();
|
||||
|
||||
// update the controller services
|
||||
controllerServicesData.setItems(services);
|
||||
controllerServicesData.reSort();
|
||||
controllerServicesGrid.invalidate();
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Initializes the status page.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
init: function (serviceTable) {
|
||||
if (!initialized) {
|
||||
// initialize the new controller service dialog
|
||||
initNewControllerServiceDialog();
|
||||
|
||||
// don't run this again
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
// initialize the controller service table
|
||||
initControllerServices(serviceTable);
|
||||
},
|
||||
|
||||
/**
|
||||
* Prompts for a new controller service.
|
||||
*
|
||||
* @param {string} controllerServicesUri
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
promptNewControllerService: function (controllerServicesUri, serviceTable) {
|
||||
// update the keyhandler
|
||||
$('#controller-service-type-filter').off('keyup').on('keyup', function (e) {
|
||||
var code = e.keyCode ? e.keyCode : e.which;
|
||||
if (code === $.ui.keyCode.ENTER) {
|
||||
addSelectedControllerService(controllerServicesUri, serviceTable);
|
||||
} else {
|
||||
applyControllerServiceTypeFilter();
|
||||
}
|
||||
});
|
||||
|
||||
// update the button model and show the dialog
|
||||
$('#new-controller-service-dialog').modal('setButtonModel', [{
|
||||
buttonText: 'Add',
|
||||
handler: {
|
||||
click: function () {
|
||||
addSelectedControllerService(controllerServicesUri, serviceTable);
|
||||
}
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
handler: {
|
||||
click: function () {
|
||||
$(this).modal('hide');
|
||||
}
|
||||
}
|
||||
}]).modal('show');
|
||||
|
||||
var controllerServiceTypesGrid = $('#controller-service-types-table').data('gridInstance');
|
||||
|
||||
// remove previous dbl click handler
|
||||
if (dblClick !== null) {
|
||||
controllerServiceTypesGrid.onDblClick.unsubscribe(dblClick);
|
||||
}
|
||||
|
||||
// update the dbl click handler and subsrcibe
|
||||
dblClick = function(e, args) {
|
||||
var controllerServiceType = controllerServiceTypesGrid.getDataItem(args.row);
|
||||
addControllerService(controllerServicesUri, serviceTable, controllerServiceType.type);
|
||||
};
|
||||
controllerServiceTypesGrid.onDblClick.subscribe(dblClick);
|
||||
|
||||
// reset the canvas size after the dialog is shown
|
||||
if (nf.Common.isDefinedAndNotNull(controllerServiceTypesGrid)) {
|
||||
controllerServiceTypesGrid.setSelectedRows([0]);
|
||||
controllerServiceTypesGrid.resizeCanvas();
|
||||
}
|
||||
|
||||
// set the initial focus
|
||||
$('#controller-service-type-filter').focus();
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the size of the grid based on its container's current size.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
resetTableSize: function (serviceTable) {
|
||||
var controllerServicesGrid = serviceTable.data('gridInstance');
|
||||
if (nf.Common.isDefinedAndNotNull(controllerServicesGrid)) {
|
||||
controllerServicesGrid.resizeCanvas();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Loads the settings.
|
||||
*
|
||||
* @param {string} controllerServicesUri
|
||||
* @param {jQuery} serviceTable
|
||||
*/
|
||||
loadControllerServices: function (controllerServicesUri, serviceTable) {
|
||||
return loadControllerServices(controllerServicesUri, serviceTable);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the controller service and reporting task bulletins in their respective tables.
|
||||
*
|
||||
* @param {jQuery} serviceTable
|
||||
* @param {object} controllerServiceBulletins
|
||||
*/
|
||||
setBulletins: function(serviceTable, controllerServiceBulletins) {
|
||||
// controller services
|
||||
var controllerServicesGrid = serviceTable.data('gridInstance');
|
||||
var controllerServicesData = controllerServicesGrid.getData();
|
||||
controllerServicesData.beginUpdate();
|
||||
|
||||
// if there are some bulletins process them
|
||||
if (!nf.Common.isEmpty(controllerServiceBulletins)) {
|
||||
var controllerServiceBulletinsBySource = d3.nest()
|
||||
.key(function(d) { return d.sourceId; })
|
||||
.map(controllerServiceBulletins, d3.map);
|
||||
|
||||
controllerServiceBulletinsBySource.forEach(function(sourceId, sourceBulletins) {
|
||||
var controllerService = controllerServicesData.getItemById(sourceId);
|
||||
if (nf.Common.isDefinedAndNotNull(controllerService)) {
|
||||
controllerServicesData.updateItem(sourceId, $.extend(controllerService, {
|
||||
bulletins: sourceBulletins
|
||||
}));
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// if there are no bulletins clear all
|
||||
var controllerServices = controllerServicesData.getItems();
|
||||
$.each(controllerServices, function(_, controllerService) {
|
||||
controllerServicesData.updateItem(controllerService.id, $.extend(controllerService, {
|
||||
bulletins: []
|
||||
}));
|
||||
});
|
||||
}
|
||||
controllerServicesData.endUpdate();
|
||||
}
|
||||
};
|
||||
}());
|
|
@ -19,88 +19,271 @@
|
|||
|
||||
nf.ProcessGroupConfiguration = (function () {
|
||||
|
||||
var config = {
|
||||
filterText: 'Filter',
|
||||
styles: {
|
||||
filterList: 'filter-list'
|
||||
},
|
||||
urls: {
|
||||
api: '../nifi-api'
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the general tab.
|
||||
*/
|
||||
var initGeneral = function () {
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the controller services table.
|
||||
*
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
*/
|
||||
var getControllerServicesTable = function () {
|
||||
return $('#process-group-controller-services-table');
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves the configuration for the specified group.
|
||||
*
|
||||
* @param version
|
||||
* @param groupId
|
||||
*/
|
||||
var saveConfiguration = function (version, groupId) {
|
||||
// build the entity
|
||||
var entity = {
|
||||
'revision': nf.Client.getRevision({
|
||||
'revision': {
|
||||
'version': version
|
||||
}
|
||||
}),
|
||||
'component': {
|
||||
'id': groupId,
|
||||
'name': $('#process-group-name').val(),
|
||||
'comments': $('#process-group-comments').val()
|
||||
}
|
||||
};
|
||||
|
||||
// update the selected component
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(entity),
|
||||
url: config.urls.api + '/process-groups/' + encodeURIComponent(groupId),
|
||||
dataType: 'json',
|
||||
contentType: 'application/json'
|
||||
}).done(function (response) {
|
||||
// refresh the process group if necessary
|
||||
if (response.accessPolicy.canRead && response.component.parentGroupId === nf.Canvas.getGroupId()) {
|
||||
nf.ProcessGroup.set(response);
|
||||
}
|
||||
|
||||
// show the result dialog
|
||||
nf.Dialog.showOkDialog({
|
||||
dialogContent: 'Process group configuration successfully saved.',
|
||||
overlayBackground: false
|
||||
});
|
||||
|
||||
// update the click listener for the updated revision
|
||||
$('#process-group-configuration-save').off('click').on('click', function () {
|
||||
saveConfiguration(response.revision.version, groupId);
|
||||
});
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads the configuration for the specified process group.
|
||||
*
|
||||
* @param {string} groupId
|
||||
*/
|
||||
var loadConfiguration = function (groupId) {
|
||||
var setUnauthorizedText = function () {
|
||||
$('#read-only-process-group-name').addClass('unset').text('Unauthorized');
|
||||
$('#read-only-process-group-comments').addClass('unset').text('Unauthorized');
|
||||
};
|
||||
|
||||
var setEditable = function (editable) {
|
||||
if (editable) {
|
||||
$('#process-group-configuration div.editable').show();
|
||||
$('#process-group-configuration div.read-only').hide();
|
||||
$('#process-group-configuration-save').show();
|
||||
} else {
|
||||
$('#process-group-configuration div.editable').hide();
|
||||
$('#process-group-configuration div.read-only').show();
|
||||
$('#process-group-configuration-save').hide();
|
||||
}
|
||||
};
|
||||
|
||||
var processGroup = $.Deferred(function (deferred) {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: config.urls.api + '/process-groups/' + encodeURIComponent(groupId),
|
||||
dataType: 'json'
|
||||
}).done(function (response) {
|
||||
if (response.accessPolicy.canWrite) {
|
||||
var processGroup = response.component;
|
||||
|
||||
// populate the process group settings
|
||||
$('#process-group-id').text(processGroup.id);
|
||||
$('#process-group-name').removeClass('unset').val(processGroup.name);
|
||||
$('#process-group-comments').removeClass('unset').val(processGroup.comments);
|
||||
|
||||
setEditable(true);
|
||||
|
||||
// register the click listener for the save button
|
||||
$('#process-group-configuration-save').off('click').on('click', function () {
|
||||
saveConfiguration(response.revision.version, processGroupResponse.id);
|
||||
});
|
||||
} else {
|
||||
if (response.accessPolicy.canRead) {
|
||||
// populate the process group settings
|
||||
$('#read-only-process-group-name').removeClass('unset').text(response.component.name);
|
||||
$('#read-only-process-group-comments').removeClass('unset').text(response.component.comments);
|
||||
} else {
|
||||
setUnauthorizedText();
|
||||
}
|
||||
|
||||
setEditable(false);
|
||||
}
|
||||
deferred.resolve();
|
||||
}).fail(function (xhr, status, error) {
|
||||
if (xhr.status === 403) {
|
||||
setUnauthorizedText();
|
||||
setEditable(false);
|
||||
deferred.resolve();
|
||||
} else {
|
||||
deferred.reject(xhr, status, error);
|
||||
}
|
||||
});
|
||||
}).promise();
|
||||
|
||||
// load the controller services
|
||||
var controllerServicesUri = config.urls.api + '/flow/process-groups/' + encodeURIComponent(groupId) + '/controller-services';
|
||||
var controllerServices = nf.ControllerServices.loadControllerServices(controllerServicesUri, getControllerServicesTable());
|
||||
|
||||
// wait for everything to complete
|
||||
return $.when(processGroup, controllerServices).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
/**
|
||||
* Shows the process group configuration.
|
||||
*/
|
||||
var showConfiguration = function () {
|
||||
// show the configuration dialog
|
||||
nf.Shell.showContent('#process-group-configuration').done(function () {
|
||||
reset();
|
||||
});
|
||||
|
||||
// adjust the table size
|
||||
nf.ProcessGroupConfiguration.resetTableSize();
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets the process group configuration dialog.
|
||||
*/
|
||||
var reset = function () {
|
||||
// reset button state
|
||||
$('#process-group-configuration-save').mouseout();
|
||||
|
||||
// reset the fields
|
||||
$('#process-group-name').val('');
|
||||
$('#process-group-comments').val('');
|
||||
};
|
||||
|
||||
return {
|
||||
/**
|
||||
* Initializes the settings page.
|
||||
*/
|
||||
init: function () {
|
||||
$('#process-group-configuration').modal({
|
||||
headerText: 'Configure Process Group',
|
||||
overlayBackground: true,
|
||||
buttons: [{
|
||||
buttonText: 'Apply',
|
||||
handler: {
|
||||
click: function () {
|
||||
// get the process group data to reference the uri
|
||||
var processGroupId = $('#process-group-id').text();
|
||||
var processGroupData = d3.select('#id-' + processGroupId).datum();
|
||||
|
||||
// build the entity
|
||||
var entity = {
|
||||
'revision': nf.Client.getRevision(processGroupData),
|
||||
'component': {
|
||||
'id': processGroupId,
|
||||
'name': $('#process-group-name').val(),
|
||||
'comments': $('#process-group-comments').val()
|
||||
}
|
||||
};
|
||||
// initialize the process group configuration tabs
|
||||
$('#process-group-configuration-tabs').tabbs({
|
||||
tabStyle: 'settings-tab',
|
||||
selectedTabStyle: 'settings-selected-tab',
|
||||
tabs: [{
|
||||
name: 'General',
|
||||
tabContentId: 'general-process-group-configuration-tab-content'
|
||||
}, {
|
||||
name: 'Controller Services',
|
||||
tabContentId: 'process-group-controller-services-tab-content'
|
||||
}],
|
||||
select: function () {
|
||||
var tab = $(this).text();
|
||||
if (tab === 'General') {
|
||||
$('#add-process-group-configuration-controller-service').hide();
|
||||
} else {
|
||||
$('#add-process-group-configuration-controller-service').show();
|
||||
|
||||
// update the selected component
|
||||
$.ajax({
|
||||
type: 'PUT',
|
||||
data: JSON.stringify(entity),
|
||||
url: processGroupData.component.uri,
|
||||
dataType: 'json',
|
||||
contentType: 'application/json'
|
||||
}).done(function (response) {
|
||||
// refresh the process group
|
||||
nf.ProcessGroup.set(response);
|
||||
|
||||
// close the details panel
|
||||
$('#process-group-configuration').modal('hide');
|
||||
}).fail(function (xhr, status, error) {
|
||||
// close the details panel
|
||||
$('#process-group-configuration').modal('hide');
|
||||
|
||||
// handle the error
|
||||
nf.Common.handleAjaxError(xhr, status, error);
|
||||
});
|
||||
// update the tooltip on the button
|
||||
$('#add-process-group-configuration-controller-service').attr('title', function () {
|
||||
if (tab === 'Controller Services') {
|
||||
return 'Create a new controller service';
|
||||
}
|
||||
}
|
||||
}, {
|
||||
buttonText: 'Cancel',
|
||||
handler: {
|
||||
click: function () {
|
||||
$('#process-group-configuration').modal('hide');
|
||||
}
|
||||
}
|
||||
}],
|
||||
handler: {
|
||||
close: function () {
|
||||
// clear the process group details
|
||||
$('#process-group-id').text('');
|
||||
$('#process-group-name').val('');
|
||||
$('#process-group-comments').val('');
|
||||
});
|
||||
|
||||
// resize the table
|
||||
nf.ProcessGroupConfiguration.resetTableSize();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// settings refresh button...
|
||||
nf.Common.addHoverEffect('#process-group-configuration-refresh-button', 'button-refresh', 'button-refresh-hover');
|
||||
|
||||
// handle window resizing
|
||||
$(window).on('resize', function (e) {
|
||||
nf.ProcessGroupConfiguration.resetTableSize();
|
||||
});
|
||||
|
||||
// initialize each tab
|
||||
initGeneral();
|
||||
nf.ControllerServices.init(getControllerServicesTable());
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows the details for the specified selection.
|
||||
*
|
||||
* @argument {selection} selection The selection
|
||||
* Update the size of the grid based on its container's current size.
|
||||
*/
|
||||
showConfiguration: function (selection) {
|
||||
// if the specified selection is a processor, load its properties
|
||||
if (nf.CanvasUtils.isProcessGroup(selection)) {
|
||||
var selectionData = selection.datum();
|
||||
resetTableSize: function () {
|
||||
nf.ControllerServices.resetTableSize(getControllerServicesTable());
|
||||
},
|
||||
|
||||
// populate the process group settings
|
||||
$('#process-group-id').text(selectionData.id);
|
||||
$('#process-group-name').val(selectionData.component.name);
|
||||
$('#process-group-comments').val(selectionData.component.comments);
|
||||
/**
|
||||
* Shows the settings dialog.
|
||||
*/
|
||||
showConfiguration: function (groupId) {
|
||||
// update the click listener
|
||||
$('#process-group-configuration-refresh-button').off('click').on('click', function () {
|
||||
loadConfiguration(groupId).done(showConfiguration);
|
||||
});
|
||||
|
||||
// show the details
|
||||
$('#process-group-configuration').modal('show');
|
||||
}
|
||||
// update the new controller service click listener
|
||||
$('#add-process-group-configuration-controller-service').off('click').on('click', function () {
|
||||
var selectedTab = $('#process-group-configuration-tabs li.settings-selected-tab').text();
|
||||
if (selectedTab === 'Controller Services') {
|
||||
var controllerServicesUri = config.urls.api + '/process-groups/' + encodeURIComponent(groupId) + '/controller-services';
|
||||
nf.ControllerServices.promptNewControllerService(controllerServicesUri, getControllerServicesTable());
|
||||
}
|
||||
});
|
||||
|
||||
// load the configuration
|
||||
return loadConfiguration(groupId).done(showConfiguration);
|
||||
},
|
||||
|
||||
/**
|
||||
* Selects the specified controller service.
|
||||
*
|
||||
* @param {string} controllerServiceId
|
||||
*/
|
||||
selectControllerService: function (controllerServiceId) {
|
||||
var controllerServiceGrid = getControllerServicesTable().data('gridInstance');
|
||||
var controllerServiceData = controllerServiceGrid.getData();
|
||||
|
||||
// select the desired service
|
||||
var row = controllerServiceData.getRowById(controllerServiceId);
|
||||
controllerServiceGrid.setSelectedRows([row]);
|
||||
controllerServiceGrid.scrollRowIntoView(row);
|
||||
|
||||
// select the controller services tab
|
||||
$('#process-group-configuration-tabs').find('li:eq(1)').click();
|
||||
}
|
||||
};
|
||||
}());
|
|
@ -24,6 +24,15 @@ nf.ReportingTask = (function () {
|
|||
readOnly: 'read-only'
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the controller services table.
|
||||
*
|
||||
* @returns {*|jQuery|HTMLElement}
|
||||
*/
|
||||
var getControllerServicesTable = function () {
|
||||
return $('#controller-services-table');
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle any expected reporting task configuration errors.
|
||||
*
|
||||
|
@ -205,7 +214,7 @@ nf.ReportingTask = (function () {
|
|||
}).done(function (response) {
|
||||
// update the task
|
||||
renderReportingTask(response);
|
||||
nf.ControllerService.reloadReferencedServices(response.component);
|
||||
nf.ControllerService.reloadReferencedServices(getControllerServicesTable(), response.component);
|
||||
}).fail(nf.Common.handleAjaxError);
|
||||
};
|
||||
|
||||
|
@ -464,7 +473,7 @@ nf.ReportingTask = (function () {
|
|||
// save the reporting task
|
||||
saveReportingTask(reportingTaskEntity).done(function (response) {
|
||||
// reload the reporting task
|
||||
nf.ControllerService.reloadReferencedServices(response.component);
|
||||
nf.ControllerService.reloadReferencedServices(getControllerServicesTable(), response.component);
|
||||
|
||||
// close the details panel
|
||||
$('#reporting-task-configuration').modal('hide');
|
||||
|
@ -497,7 +506,7 @@ nf.ReportingTask = (function () {
|
|||
nf.CustomUi.showCustomUi($('#reporting-task-id').text(), reportingTask.customUiUrl, true).done(function () {
|
||||
// once the custom ui is closed, reload the reporting task
|
||||
nf.ReportingTask.reload(reportingTaskEntity.id).done(function (response) {
|
||||
nf.ControllerService.reloadReferencedServices(response.reportingTask);
|
||||
nf.ControllerService.reloadReferencedServices(getControllerServicesTable(), response.reportingTask);
|
||||
});
|
||||
|
||||
// show the settings
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -337,8 +337,8 @@ nf.Common = (function () {
|
|||
return;
|
||||
}
|
||||
|
||||
// status code 400, 404, and 409 are expected response codes for common errors.
|
||||
if (xhr.status === 400 || xhr.status === 404 || xhr.status === 409) {
|
||||
// status code 400, 403, 404, and 409 are expected response codes for common errors.
|
||||
if (xhr.status === 400 || xhr.status === 403 || xhr.status === 404 || xhr.status === 409) {
|
||||
nf.Dialog.showOkDialog({
|
||||
dialogContent: nf.Common.escapeHtml(xhr.responseText),
|
||||
overlayBackground: false
|
||||
|
@ -360,14 +360,7 @@ nf.Common = (function () {
|
|||
} else if (xhr.status === 401) {
|
||||
$('#message-title').text('Unauthorized');
|
||||
if ($.trim(xhr.responseText) === '') {
|
||||
$('#message-content').text('Authorization is required to use this NiFi.');
|
||||
} else {
|
||||
$('#message-content').text(xhr.responseText);
|
||||
}
|
||||
} else if (xhr.status === 403) {
|
||||
$('#message-title').text('Access Denied');
|
||||
if ($.trim(xhr.responseText) === '') {
|
||||
$('#message-content').text('Unable to authorize you to use this NiFi.');
|
||||
$('#message-content').text('Authentication is required to use this NiFi.');
|
||||
} else {
|
||||
$('#message-content').text(xhr.responseText);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue