NIFI-1554: - Updating cluster detection to support access through the flow resource. - Using the correct resource when authorizing a root group port during site to site.

This closes #579.

Signed-off-by: Bryan Bende <bbende@apache.org>
This commit is contained in:
Matt Gilman 2016-06-24 16:29:00 -04:00 committed by Bryan Bende
parent 8da571d6d6
commit 82268afb0d
5 changed files with 81 additions and 102 deletions

View File

@ -33,6 +33,7 @@ public class FlowConfigurationDTO {
private Date currentTime;
private Integer timeOffset;
private Boolean isClustered;
/**
* @return interval in seconds between the automatic NiFi refresh requests. This value is read only
@ -77,4 +78,18 @@ public class FlowConfigurationDTO {
public void setTimeOffset(Integer timeOffset) {
this.timeOffset = timeOffset;
}
/**
* @return whether this NiFi instance is clustered
*/
@ApiModelProperty(
value = "Whether this NiFi instance is clustered."
)
public Boolean getClustered() {
return isClustered;
}
public void setClustered(Boolean clustered) {
isClustered = clustered;
}
}

View File

@ -16,14 +16,12 @@
*/
package org.apache.nifi.remote;
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;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.ResourceFactory;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.components.ValidationResult;
import org.apache.nifi.connectable.ConnectableType;
import org.apache.nifi.controller.AbstractPort;
@ -344,16 +342,6 @@ public class StandardRootGroupPort extends AbstractPort implements RootGroupPort
}
}
@Override
public Authorizable getParentAuthorizable() {
return null;
}
@Override
public Resource getResource() {
return ResourceFactory.getSiteToSiteResource(getIdentifier(), getName());
}
@Override
public PortAuthorizationResult checkUserAuthorization(final String dn) {
if (!secure) {
@ -367,8 +355,17 @@ public class StandardRootGroupPort extends AbstractPort implements RootGroupPort
return new StandardPortAuthorizationResult(false, "User DN is not known");
}
// attempt to authorize the specified user
final AuthorizationResult result = checkAuthorization(authorizer, RequestAction.WRITE, new NiFiUser(dn));
// build the request
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(dn)
.anonymous(false)
.accessAttempt(true)
.action(RequestAction.WRITE)
.resource(ResourceFactory.getSiteToSiteResource(getIdentifier(), getName()))
.build();
// perform the authorization
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
final String message = String.format("%s authorization failed for user %s because %s", this, dn, result.getExplanation());
logger.warn(message);

View File

@ -58,7 +58,6 @@ import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
@ -441,24 +440,6 @@ public class ControllerResource extends ApplicationResource {
// cluster
// -------
/**
* Returns a 200 OK response to indicate this is a valid cluster endpoint.
*
* @return An OK response with an empty entity body.
*/
@HEAD
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.WILDCARD)
@Path("cluster")
public Response getClusterHead() {
// TODO - remove once cluster detection is part of /flow
if (isConnectedToCluster()) {
return Response.ok().build();
} else {
return Response.status(Response.Status.NOT_FOUND).entity("NiFi instance is not clustered").build();
}
}
/**
* Gets the contents of this NiFi cluster. This includes all nodes and their status.
*

View File

@ -282,6 +282,10 @@ public class FlowResource extends ApplicationResource {
}
final FlowConfigurationEntity entity = serviceFacade.getFlowConfiguration();
// include details about cluster state
entity.getFlowConfiguration().setClustered(isConnectedToCluster());
return clusterContext(generateOkResponse(entity)).build();
}

View File

@ -815,24 +815,6 @@ nf.Canvas = (function () {
dataType: 'json'
});
// create the deferred cluster request
var isClusteredRequest = $.Deferred(function (deferred) {
$.ajax({
type: 'HEAD',
url: config.urls.cluster
}).done(function (response, status, xhr) {
clustered = true;
deferred.resolve(response, status, xhr);
}).fail(function (xhr, status, error) {
if (xhr.status === 404) {
clustered = false;
deferred.resolve('', 'success', xhr);
} else {
deferred.reject(xhr, status, error);
}
});
}).promise();
// ensure the config requests are loaded
$.when(configXhr, userXhr, clientXhr).done(function (configResult, loginResult, aboutResult) {
var configResponse = configResult[0];
@ -844,65 +826,65 @@ nf.Canvas = (function () {
// get the config details
var configDetails = configResponse.flowConfiguration;
// when both request complete, load the application
isClusteredRequest.done(function () {
// get the auto refresh interval
var autoRefreshIntervalSeconds = parseInt(configDetails.autoRefreshIntervalSeconds, 10);
// update the clustered flag
clustered = configDetails.clustered;
// init storage
nf.Storage.init();
// get the auto refresh interval
var autoRefreshIntervalSeconds = parseInt(configDetails.autoRefreshIntervalSeconds, 10);
// initialize the application
initCanvas();
nf.Canvas.View.init();
nf.ContextMenu.init();
nf.ng.Bridge.injector.get('headerCtrl').init();
nf.Settings.init();
nf.Actions.init();
nf.QueueListing.init();
nf.ComponentState.init();
// init storage
nf.Storage.init();
// initialize the component behaviors
nf.Draggable.init();
nf.Selectable.init();
nf.Connectable.init();
// initialize the application
initCanvas();
nf.Canvas.View.init();
nf.ContextMenu.init();
nf.ng.Bridge.injector.get('headerCtrl').init();
nf.Settings.init();
nf.Actions.init();
nf.QueueListing.init();
nf.ComponentState.init();
// initialize the chart
nf.StatusHistory.init(configDetails.timeOffset);
// initialize the component behaviors
nf.Draggable.init();
nf.Selectable.init();
nf.Connectable.init();
// initialize the birdseye
nf.Birdseye.init();
// initialize the chart
nf.StatusHistory.init(configDetails.timeOffset);
// initialize components
nf.ConnectionConfiguration.init();
nf.ControllerService.init();
nf.ReportingTask.init();
nf.ProcessorConfiguration.init();
nf.ProcessGroupConfiguration.init();
nf.RemoteProcessGroupConfiguration.init();
nf.RemoteProcessGroupPorts.init();
nf.PortConfiguration.init();
nf.LabelConfiguration.init();
nf.ProcessorDetails.init();
nf.ProcessGroupDetails.init();
nf.PortDetails.init();
nf.ConnectionDetails.init();
nf.RemoteProcessGroupDetails.init();
nf.GoTo.init();
nf.Graph.init().done(function () {
nf.ng.Bridge.injector.get('graphControlsCtrl').init();
// initialize the birdseye
nf.Birdseye.init();
// determine the split between the polling
var pollingSplit = autoRefreshIntervalSeconds / 2;
// initialize components
nf.ConnectionConfiguration.init();
nf.ControllerService.init();
nf.ReportingTask.init();
nf.ProcessorConfiguration.init();
nf.ProcessGroupConfiguration.init();
nf.RemoteProcessGroupConfiguration.init();
nf.RemoteProcessGroupPorts.init();
nf.PortConfiguration.init();
nf.LabelConfiguration.init();
nf.ProcessorDetails.init();
nf.ProcessGroupDetails.init();
nf.PortDetails.init();
nf.ConnectionDetails.init();
nf.RemoteProcessGroupDetails.init();
nf.GoTo.init();
nf.Graph.init().done(function () {
nf.ng.Bridge.injector.get('graphControlsCtrl').init();
// register the polling
setTimeout(function () {
startPolling(autoRefreshIntervalSeconds);
}, pollingSplit * 1000);
// determine the split between the polling
var pollingSplit = autoRefreshIntervalSeconds / 2;
// hide the splash screen
nf.Canvas.hideSplash();
}).fail(nf.Common.handleAjaxError);
// register the polling
setTimeout(function () {
startPolling(autoRefreshIntervalSeconds);
}, pollingSplit * 1000);
// hide the splash screen
nf.Canvas.hideSplash();
}).fail(nf.Common.handleAjaxError);
}).fail(nf.Common.handleAjaxError);
}).fail(nf.Common.handleAjaxError);