NIFI-2035: Verify existence of source and destination when creating a connection

Signed-off-by: Yolanda M. Davis <ymdavis@apache.org>

This closes #690
This commit is contained in:
Mark Payne 2016-06-20 14:55:08 -04:00 committed by Yolanda M. Davis
parent 7a7165152e
commit cda4310ad8
2 changed files with 36 additions and 2 deletions

View File

@ -35,6 +35,7 @@ import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.controller.Snippet;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.ResourceNotFoundException;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
@ -109,8 +110,6 @@ public class ProcessGroupResource extends ApplicationResource {
private static final Logger logger = LoggerFactory.getLogger(ProcessGroupResource.class);
private static final String VERBOSE = "false";
@Context
private ResourceContext resourceContext;
@ -1530,10 +1529,17 @@ public class ProcessGroupResource extends ApplicationResource {
// ensure write access to the source
final Authorizable source = lookup.getConnectable(connection.getSource().getId());
if (source == null) {
throw new ResourceNotFoundException("Cannot find source component with ID [" + connection.getSource().getId() + "]");
}
source.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
// ensure write access to the destination
final Authorizable destination = lookup.getConnectable(connection.getDestination().getId());
if (destination == null) {
throw new ResourceNotFoundException("Cannot find destination component with ID [" + connection.getDestination().getId() + "]");
}
destination.authorize(authorizer, RequestAction.WRITE, NiFiUserUtils.getNiFiUser());
});
}

View File

@ -378,6 +378,34 @@ public class StandardConnectionDAO extends ComponentDAO implements ConnectionDAO
if (!validationErrors.isEmpty()) {
throw new ValidationException(validationErrors);
}
// Ensure that both the source and the destination for the connection exist.
// In the case that the source or destination is a port in a Remote Process Group,
// this is necessary because the ports can change in the background. It may still be
// possible for a port to disappear between the 'verify' stage and the creation stage,
// but this prevents the case where some nodes already know about the port while other
// nodes in the cluster do not. This is a more common case, as users may try to connect
// to the port as soon as the port is created.
final ConnectableDTO sourceDto = connectionDTO.getSource();
if (sourceDto == null || sourceDto.getId() == null) {
throw new IllegalArgumentException("Cannot create connection without specifying source");
}
final ConnectableDTO destinationDto = connectionDTO.getDestination();
if (destinationDto == null || destinationDto.getId() == null) {
throw new IllegalArgumentException("Cannot create connection without specifying destination");
}
final ProcessGroup rootGroup = flowController.getGroup(flowController.getRootGroupId());
final Connectable sourceConnectable = rootGroup.findConnectable(sourceDto.getId());
if (sourceConnectable == null) {
throw new IllegalArgumentException("The specified source for the connection does not exist");
}
final Connectable destinationConnectable = rootGroup.findConnectable(destinationDto.getId());
if (destinationConnectable == null) {
throw new IllegalArgumentException("The specified destination for the connection does not exist");
}
}
private void verifyList(final FlowFileQueue queue) {