- Addressing access controls for the Controller resource.
- Addressing access controls for RAW site to site clients.
- Addressing access controls for downloading content (from provenance and queue).
- Addressing access controls for accessing queues.
- Addressing access controls for cluster endpoints.
- Addressing access controls for counter endpoints.
- Removing redundant authorization calls.
NIFI-2044:
- Requiring revision when creating components.
- Requiring component creation over POST requests.
NIFI-1901
- Continuing to restore access control tests.
- Converting access control tests to itegration tests.
- Restoring contrib check to travis build.
- This closes #567
This commit is contained in:
Matt Gilman 2016-06-23 15:55:18 -04:00
Родитель f0662a24ef
Коммит f0811ca45a
103 изменённых файлов: 2802 добавлений и 5671 удалений

Просмотреть файл

@ -14,4 +14,4 @@ before_install:
- sed -e "s/^\\(127\\.0\\.0\\.1.*\\)/\\1 $(hostname | cut -c1-63)/" /etc/hosts | sudo tee /etc/hosts
- sed -i.bak -e 's|https://nexus.codehaus.org/snapshots/|https://oss.sonatype.org/content/repositories/codehaus-snapshots/|g' ~/.m2/settings.xml
script: mvn clean install -T4
script: mvn clean install -Pcontrib-check

Просмотреть файл

@ -17,7 +17,6 @@
package org.apache.nifi.web;
import java.io.Serializable;
import java.util.Objects;
/**
* A model object representing a revision. Equality is defined as matching
@ -46,15 +45,17 @@ public class Revision implements Serializable {
*/
private final String componentId;
@Deprecated
public Revision(Long revision, String clientId) {
this(revision, clientId, "root"); // TODO: remove this constructor. This is to bridge the gap right now
}
public Revision(Long version, String clientId, String componentId) {
if (version == null) {
throw new IllegalArgumentException("The revision must be specified.");
}
if (componentId == null) {
throw new IllegalArgumentException("The componentId must be specified.");
}
public Revision(Long revision, String clientId, String componentId) {
this.version = revision;
this.version = version;
this.clientId = clientId;
this.componentId = Objects.requireNonNull(componentId);
this.componentId = componentId;
}
public String getClientId() {
@ -69,6 +70,16 @@ public class Revision implements Serializable {
return componentId;
}
/**
* Returns a new Revision that has the same Client ID and Component ID as this one
* but with a larger version
*
* @return the updated Revision
*/
public Revision incrementRevision(final String clientId) {
return new Revision(version + 1, clientId, componentId);
}
@Override
public boolean equals(final Object obj) {
if (obj == null) {

Просмотреть файл

@ -0,0 +1,61 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
*
*/
public class TestRevision {
@Test(expected = IllegalArgumentException.class)
public void testNullVersion() throws Exception {
new Revision(null, "client-id", "component-id");
}
@Test(expected = IllegalArgumentException.class)
public void testNullComponentId() throws Exception {
new Revision(0l, "client-id", null);
}
@Test
public void testIncrementRevision() throws Exception {
final String clientId = "client-id";
final String componentId = "component-id";
final Revision revision = new Revision(0l, clientId, componentId);
final Revision updatedRevision = revision.incrementRevision(clientId);
assertEquals(1, updatedRevision.getVersion().longValue());
assertEquals(clientId, updatedRevision.getClientId());
assertEquals(componentId, updatedRevision.getComponentId());
}
@Test
public void testIncrementRevisionNewClient() throws Exception {
final String clientId = "client-id";
final String newClientId = "new-client-id";
final String componentId = "component-id";
final Revision revision = new Revision(0l, clientId, componentId);
final Revision updatedRevision = revision.incrementRevision(newClientId);
assertEquals(1, updatedRevision.getVersion().longValue());
assertEquals(newClientId, updatedRevision.getClientId());
assertEquals(componentId, updatedRevision.getComponentId());
}
}

Просмотреть файл

@ -69,6 +69,10 @@
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-nar-utils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-properties</artifactId>
</dependency>
</dependencies>
</project>

Просмотреть файл

@ -17,26 +17,18 @@
package org.apache.nifi.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
/**
* Details for the controller configuration.
*/
@XmlType(name = "config")
@XmlType(name = "controllerConfiguration")
public class ControllerConfigurationDTO {
private Integer maxTimerDrivenThreadCount;
private Integer maxEventDrivenThreadCount;
private Long autoRefreshIntervalSeconds;
private Date currentTime;
private Integer timeOffset;
/**
* @return maximum number of timer driven threads this NiFi has available
*/
@ -64,48 +56,4 @@ public class ControllerConfigurationDTO {
public void setMaxEventDrivenThreadCount(Integer maxEventDrivenThreadCount) {
this.maxEventDrivenThreadCount = maxEventDrivenThreadCount;
}
/**
* @return interval in seconds between the automatic NiFi refresh requests. This value is read only
*/
@ApiModelProperty(
value = "The interval in seconds between the automatic NiFi refresh requests.",
readOnly = true
)
public Long getAutoRefreshIntervalSeconds() {
return autoRefreshIntervalSeconds;
}
public void setAutoRefreshIntervalSeconds(Long autoRefreshIntervalSeconds) {
this.autoRefreshIntervalSeconds = autoRefreshIntervalSeconds;
}
/**
* @return current time on the server
*/
@XmlJavaTypeAdapter(TimeAdapter.class)
@ApiModelProperty(
value = "The current time on the system."
)
public Date getCurrentTime() {
return currentTime;
}
public void setCurrentTime(Date currentTime) {
this.currentTime = currentTime;
}
/**
* @return time offset of the server
*/
@ApiModelProperty(
value = "The time offset of the system."
)
public Integer getTimeOffset() {
return timeOffset;
}
public void setTimeOffset(Integer timeOffset) {
this.timeOffset = timeOffset;
}
}

Просмотреть файл

@ -0,0 +1,80 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web.api.dto;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
/**
* Details for the controller configuration.
*/
@XmlType(name = "flowConfiguration")
public class FlowConfigurationDTO {
private Long autoRefreshIntervalSeconds;
private Date currentTime;
private Integer timeOffset;
/**
* @return interval in seconds between the automatic NiFi refresh requests. This value is read only
*/
@ApiModelProperty(
value = "The interval in seconds between the automatic NiFi refresh requests.",
readOnly = true
)
public Long getAutoRefreshIntervalSeconds() {
return autoRefreshIntervalSeconds;
}
public void setAutoRefreshIntervalSeconds(Long autoRefreshIntervalSeconds) {
this.autoRefreshIntervalSeconds = autoRefreshIntervalSeconds;
}
/**
* @return current time on the server
*/
@XmlJavaTypeAdapter(TimeAdapter.class)
@ApiModelProperty(
value = "The current time on the system."
)
public Date getCurrentTime() {
return currentTime;
}
public void setCurrentTime(Date currentTime) {
this.currentTime = currentTime;
}
/**
* @return time offset of the server
*/
@ApiModelProperty(
value = "The time offset of the system."
)
public Integer getTimeOffset() {
return timeOffset;
}
public void setTimeOffset(Integer timeOffset) {
this.timeOffset = timeOffset;
}
}

Просмотреть файл

@ -70,7 +70,8 @@ public class RevisionDTO {
* @return The user that last modified the flow
*/
@ApiModelProperty(
value = "The user that last modified the flow."
value = "The user that last modified the flow.",
readOnly = true
)
public String getLastModifier() {
return lastModifier;

Просмотреть файл

@ -20,8 +20,11 @@ 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;
import org.apache.nifi.web.api.dto.util.TimeAdapter;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
import java.util.Date;
/**
* 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.
@ -29,7 +32,8 @@ import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement(name = "controllerConfigurationEntity")
public class ControllerConfigurationEntity extends Entity {
private ControllerConfigurationDTO config;
private Date currentTime;
private ControllerConfigurationDTO controllerConfiguration;
private RevisionDTO revision;
private AccessPolicyDTO accessPolicy;
@ -59,12 +63,12 @@ public class ControllerConfigurationEntity extends Entity {
@ApiModelProperty(
value = "The controller configuration."
)
public ControllerConfigurationDTO getConfig() {
return config;
public ControllerConfigurationDTO getControllerConfiguration() {
return controllerConfiguration;
}
public void setConfig(ControllerConfigurationDTO config) {
this.config = config;
public void setControllerConfiguration(ControllerConfigurationDTO controllerConfiguration) {
this.controllerConfiguration = controllerConfiguration;
}
/**
@ -82,4 +86,19 @@ public class ControllerConfigurationEntity extends Entity {
public void setAccessPolicy(AccessPolicyDTO accessPolicy) {
this.accessPolicy = accessPolicy;
}
/**
* @return current time on the server
*/
@XmlJavaTypeAdapter(TimeAdapter.class)
@ApiModelProperty(
value = "The current time on the system."
)
public Date getCurrentTime() {
return currentTime;
}
public void setCurrentTime(Date currentTime) {
this.currentTime = currentTime;
}
}

Просмотреть файл

@ -0,0 +1,48 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web.api.entity;
import com.wordnik.swagger.annotations.ApiModelProperty;
import org.apache.nifi.web.api.dto.FlowConfigurationDTO;
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 FlowConfigurationDTO.
*/
@XmlRootElement(name = "flowConfigurationEntity")
public class FlowConfigurationEntity extends Entity {
private FlowConfigurationDTO flowConfiguration;
/**
* The FlowConfigurationDTO that is being serialized.
*
* @return The FlowConfigurationDTO object
*/
@ApiModelProperty(
value = "The controller configuration."
)
public FlowConfigurationDTO getFlowConfiguration() {
return flowConfiguration;
}
public void setFlowConfiguration(FlowConfigurationDTO flowConfiguration) {
this.flowConfiguration = flowConfiguration;
}
}

Просмотреть файл

@ -65,18 +65,30 @@ public interface Authorizable {
* @return is authorized
*/
default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
return checkAuthorization(authorizer, action, NiFiUserUtils.getNiFiUser());
}
/**
* Returns the result of an authorization request for the specified user for the specified action on the specified
* resource. This method does not imply the user is directly attempting to access the specified resource. If the user is
* attempting a direct access use Authorizable.authorize().
*
* @param authorizer authorizer
* @param action action
* @param user user
* @return is authorized
*/
default AuthorizationResult checkAuthorization(Authorizer authorizer, RequestAction action, NiFiUser user) {
// TODO - include user details context
// build the request
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(false)
.action(action)
.resource(getResource())
.build();
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(false)
.action(action)
.resource(getResource())
.build();
// perform the authorization
final AuthorizationResult result = authorizer.authorize(request);

Просмотреть файл

@ -169,6 +169,18 @@ public final class ResourceFactory {
}
};
private final static Resource COUNTERS_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
return ResourceType.Counters.getValue();
}
@Override
public String getName() {
return "Counters";
}
};
private final static Resource PROVENANCE_RESOURCE = new Resource() {
@Override
public String getIdentifier() {
@ -436,6 +448,15 @@ public final class ResourceFactory {
return PROCESS_GROUP_RESOURCE;
}
/**
* Gets the Resource for accessing the Counters..
*
* @return The resource for accessing the Controller
*/
public static Resource getCountersResource() {
return COUNTERS_RESOURCE;
}
/**
* Gets the Resource for accessing provenance. Access to this Resource allows the user to access data provenance. However, additional authorization
* is required based on the component that generated the event and the attributes of the event.
@ -528,6 +549,29 @@ public final class ResourceFactory {
return USER_RESOURCE;
}
/**
* Gets a Resource for performing site to site on a port.
*
* @param identifier The identifier of the component being accessed
* @param name The name of the component being accessed
* @return The resource
*/
public static Resource getSiteToSiteResource(final String identifier, final String name) {
Objects.requireNonNull(identifier, "The component identifier must be specified.");
return new Resource() {
@Override
public String getIdentifier() {
return String.format("%s/%s", ResourceType.SiteToSite.getValue(), identifier);
}
@Override
public String getName() {
return name;
}
};
}
/**
* Gets the {@link Resource} for accessing {@link AccessPolicy}s.
* @return The policies resource

Просмотреть файл

@ -38,6 +38,7 @@ public enum ResourceType {
System("/system"),
Template("/templates"),
Token("/token"),
Counters("/counters"),
User("/users");
final String value;

Просмотреть файл

@ -35,10 +35,6 @@ public class NiFiUser implements Serializable {
this(identity, identity, null);
}
public NiFiUser(String identity, String userName) {
this(identity, userName, null);
}
public NiFiUser(String identity, NiFiUser chain) {
this(identity, identity, chain);
}

Просмотреть файл

@ -30,7 +30,7 @@ import java.util.Map;
import java.util.Set;
public class ReportingTasksEndpointMerger implements EndpointResponseMerger {
public static final String REPORTING_TASKS_URI = "/nifi-api/controller/reporting-tasks";
public static final String REPORTING_TASKS_URI = "/nifi-api/flow/reporting-tasks";
@Override
public boolean canHandle(URI uri, String method) {

Просмотреть файл

@ -17,12 +17,6 @@
package org.apache.nifi.web.revision;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.nifi.web.Revision;
/**
* <p>
* A task that is responsible for updating some component(s).
@ -35,30 +29,4 @@ public interface UpdateRevisionTask<T> {
* @return the updated revisions for the components
*/
RevisionUpdate<T> update();
/**
* Returns a new Revision that has the same Client ID and Component ID as the given one
* but with a larger version
*
* @param revision the revision to update
* @return the updated Revision
*/
default Revision incrementRevision(Revision revision) {
return new Revision(revision.getVersion() + 1, revision.getClientId(), revision.getComponentId());
}
/**
* Returns a Collection of Revisions that contains an updated version of all Revisions passed in
*
* @param revisions the Revisions to update
* @return a Collection of all Revisions that are passed in
*/
default Collection<Revision> incrementRevisions(Revision... revisions) {
final List<Revision> updated = new ArrayList<>(revisions.length);
for (final Revision revision : revisions) {
updated.add(incrementRevision(revision));
}
return updated;
}
}

Просмотреть файл

@ -16,14 +16,7 @@
*/
package org.apache.nifi.controller;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.io.IOUtils;
import org.apache.nifi.admin.service.AuditService;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.cluster.protocol.StandardDataFlow;
@ -31,6 +24,8 @@ import org.apache.nifi.controller.repository.FlowFileEventRepository;
import org.apache.nifi.controller.serialization.FlowSerializationException;
import org.apache.nifi.controller.serialization.FlowSerializer;
import org.apache.nifi.controller.serialization.StandardFlowSerializer;
import org.apache.nifi.encrypt.StringEncryptor;
import org.apache.nifi.events.VolatileBulletinRepository;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.api.dto.ConnectableDTO;
import org.apache.nifi.web.api.dto.ConnectionDTO;
@ -41,15 +36,20 @@ import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO;
import org.apache.nifi.web.revision.RevisionManager;
import org.apache.commons.io.IOUtils;
import org.apache.nifi.encrypt.StringEncryptor;
import org.apache.nifi.events.VolatileBulletinRepository;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
/**
*/
@Ignore

Просмотреть файл

@ -16,27 +16,6 @@
*/
package org.apache.nifi.controller.scheduling;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import org.apache.commons.io.FileUtils;
import org.apache.nifi.admin.service.AuditService;
import org.apache.nifi.annotation.lifecycle.OnScheduled;
@ -71,6 +50,27 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
/**
* Validate Processor's life-cycle operation within the context of
* {@link FlowController} and {@link StandardProcessScheduler}

Просмотреть файл

@ -16,7 +16,14 @@
*/
package org.apache.nifi.remote;
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;
@ -72,6 +79,7 @@ public class StandardRootGroupPort extends AbstractPort implements RootGroupPort
private final ProcessScheduler processScheduler;
private final boolean secure;
private final Authorizer authorizer;
@SuppressWarnings("unused")
private final BulletinRepository bulletinRepository;
private final EventReporter eventReporter;
@ -336,6 +344,16 @@ 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) {
@ -349,7 +367,15 @@ public class StandardRootGroupPort extends AbstractPort implements RootGroupPort
return new StandardPortAuthorizationResult(false, "User DN is not known");
}
// TODO - Replace with call to Authorizer to authorize site to site data transfer
// attempt to authorize the specified user
final AuthorizationResult result = checkAuthorization(authorizer, RequestAction.WRITE, new NiFiUser(dn));
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);
eventReporter.reportEvent(Severity.WARNING, CATEGORY, message);
return new StandardPortAuthorizationResult(false, message);
}
return new StandardPortAuthorizationResult(true, "User is Authorized");
}

Просмотреть файл

@ -24,6 +24,7 @@ import javax.servlet.http.HttpServletRequest;
*/
public class HttpServletConfigurationRequestContext extends HttpServletRequestContext implements NiFiWebConfigurationRequestContext {
private static final String ID_PARAM = "id";
private static final String CLIENT_ID_PARAM = "clientId";
private static final String REVISION_PARAM = "revision";
@ -36,7 +37,7 @@ public class HttpServletConfigurationRequestContext extends HttpServletRequestCo
/**
* @return the revision retrieved from the request parameters with keys
* equal to "clientId" and "revision".
* equal to "clientId", "revision", and "id".
*/
@Override
public Revision getRevision() {
@ -49,8 +50,9 @@ public class HttpServletConfigurationRequestContext extends HttpServletRequestCo
}
final String clientId = request.getParameter(CLIENT_ID_PARAM);
final String componentId = request.getParameter(ID_PARAM);
return new Revision(revision, clientId);
return new Revision(revision, clientId, componentId);
}
}

Просмотреть файл

@ -49,7 +49,7 @@
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<artifactId>maven-failsafe-plugin</artifactId>
<configuration>
<argLine>-Xms512m -Xmx512m</argLine>
<forkCount>1</forkCount>

Просмотреть файл

@ -24,6 +24,13 @@ import org.apache.nifi.controller.Snippet;
public interface AuthorizableLookup {
/**
* Get the authorizable Controller.
*
* @return authorizable
*/
Authorizable getController();
/**
* Get the authorizable Processor.
*

Просмотреть файл

@ -73,6 +73,7 @@ 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.FlowConfigurationEntity;
import org.apache.nifi.web.api.entity.FlowEntity;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity;
@ -289,6 +290,13 @@ public interface NiFiServiceFacade {
*/
ControllerConfigurationEntity getControllerConfiguration();
/**
* Gets the configuration for the flow.
*
* @return Flow configuration transfer object
*/
FlowConfigurationEntity getFlowConfiguration();
/**
* Updates the configuration for this controller.
*
@ -447,11 +455,12 @@ public interface NiFiServiceFacade {
/**
* Creates a new Processor.
*
* @param revision revision
* @param groupId Group id
* @param processorDTO The processor DTO
* @return The new processor DTO
*/
ProcessorEntity createProcessor(String groupId, ProcessorDTO processorDTO);
ProcessorEntity createProcessor(Revision revision, String groupId, ProcessorDTO processorDTO);
/**
* Gets the Processor transfer object for the specified id.
@ -508,7 +517,7 @@ public interface NiFiServiceFacade {
* @param processorDTO The processorDTO
* @return The updated processor
*/
UpdateResult<ProcessorEntity> updateProcessor(Revision revision, ProcessorDTO processorDTO);
ProcessorEntity updateProcessor(Revision revision, ProcessorDTO processorDTO);
/**
* Verifies the specified processor can be removed.
@ -565,11 +574,12 @@ public interface NiFiServiceFacade {
/**
* Creates a new Relationship target.
*
* @param revision revision
* @param groupId group
* @param connectionDTO The Connection DTO
* @return The Connection DTO
*/
ConnectionEntity createConnection(String groupId, ConnectionDTO connectionDTO);
ConnectionEntity createConnection(Revision revision, String groupId, ConnectionDTO connectionDTO);
/**
* Determines if this connection can be listed.
@ -600,7 +610,7 @@ public interface NiFiServiceFacade {
* @param connectionDTO The Connection DTO
* @return The Connection DTO
*/
UpdateResult<ConnectionEntity> updateConnection(Revision revision, ConnectionDTO connectionDTO);
ConnectionEntity updateConnection(Revision revision, ConnectionDTO connectionDTO);
/**
* Determines if this connection can be removed.
@ -690,11 +700,12 @@ public interface NiFiServiceFacade {
/**
* Creates a new input port.
*
* @param revision revision
* @param groupId The id of the group this port should be create in
* @param inputPortDTO The input PortDTO
* @return snapshot
*/
PortEntity createInputPort(String groupId, PortDTO inputPortDTO);
PortEntity createInputPort(Revision revision, String groupId, PortDTO inputPortDTO);
/**
* Gets an input port.
@ -732,9 +743,9 @@ public interface NiFiServiceFacade {
*
* @param revision Revision to compare with current base revision
* @param inputPortDTO The input PortDTO
* @return snapshort
* @return snapshot
*/
UpdateResult<PortEntity> updateInputPort(Revision revision, PortDTO inputPortDTO);
PortEntity updateInputPort(Revision revision, PortDTO inputPortDTO);
/**
* Determines if the input port could be deleted.
@ -758,11 +769,12 @@ public interface NiFiServiceFacade {
/**
* Creates a new output port.
*
* @param revision revision
* @param groupId The id of the group this port should be create in
* @param outputPortDTO The output PortDTO
* @return snapshot
*/
PortEntity createOutputPort( String groupId, PortDTO outputPortDTO);
PortEntity createOutputPort(Revision revision, String groupId, PortDTO outputPortDTO);
/**
* Gets an output port.
@ -802,7 +814,7 @@ public interface NiFiServiceFacade {
* @param outputPortDTO The output PortDTO
* @return snapshot
*/
UpdateResult<PortEntity> updateOutputPort(Revision revision, PortDTO outputPortDTO);
PortEntity updateOutputPort(Revision revision, PortDTO outputPortDTO);
/**
* Determines if the output port could be deleted.
@ -838,11 +850,12 @@ public interface NiFiServiceFacade {
/**
* Creates a new process group.
*
* @param revision revision
* @param parentGroupId The id of the parent group
* @param processGroupDTO The ProcessGroupDTO
* @return snapshot
*/
ProcessGroupEntity createProcessGroup(String parentGroupId, ProcessGroupDTO processGroupDTO);
ProcessGroupEntity createProcessGroup(Revision revision, String parentGroupId, ProcessGroupDTO processGroupDTO);
/**
* Returns the process group.
@ -886,7 +899,7 @@ public interface NiFiServiceFacade {
* @param processGroupDTO The ProcessGroupDTO
* @return snapshot
*/
UpdateResult<ProcessGroupEntity> updateProcessGroup(Revision revision, ProcessGroupDTO processGroupDTO);
ProcessGroupEntity updateProcessGroup(Revision revision, ProcessGroupDTO processGroupDTO);
/**
* Verifies the specified process group can be removed.
@ -910,11 +923,12 @@ public interface NiFiServiceFacade {
/**
* Creates a new remote process group.
*
* @param revision revision
* @param groupId The id of the parent group
* @param remoteProcessGroupDTO The RemoteProcessGroupDTO
* @return snapshot
*/
RemoteProcessGroupEntity createRemoteProcessGroup(String groupId, RemoteProcessGroupDTO remoteProcessGroupDTO);
RemoteProcessGroupEntity createRemoteProcessGroup(Revision revision, String groupId, RemoteProcessGroupDTO remoteProcessGroupDTO);
/**
* Gets a remote process group.
@ -978,7 +992,7 @@ public interface NiFiServiceFacade {
* @param remoteProcessGroupDTO The RemoteProcessGroupDTO
* @return snapshot
*/
UpdateResult<RemoteProcessGroupEntity> updateRemoteProcessGroup(Revision revision, RemoteProcessGroupDTO remoteProcessGroupDTO);
RemoteProcessGroupEntity updateRemoteProcessGroup(Revision revision, RemoteProcessGroupDTO remoteProcessGroupDTO);
/**
* Updates the specified remote process groups input port.
@ -1022,11 +1036,12 @@ public interface NiFiServiceFacade {
/**
* Creates a funnel.
*
* @param revision revision
* @param groupId group
* @param funnelDTO funnel
* @return The funnel DTO
*/
FunnelEntity createFunnel(String groupId, FunnelDTO funnelDTO);
FunnelEntity createFunnel(Revision revision, String groupId, FunnelDTO funnelDTO);
/**
* Gets the specified funnel.
@ -1045,13 +1060,13 @@ public interface NiFiServiceFacade {
Set<FunnelEntity> getFunnels(String groupId);
/**
* Updates the specified label.
* Updates the specified funnel.
*
* @param revision Revision to compare with current base revision
* @param funnelDTO The funnel DTO
* @return The funnel DTO
*/
UpdateResult<FunnelEntity> updateFunnel(Revision revision, FunnelDTO funnelDTO);
FunnelEntity updateFunnel(Revision revision, FunnelDTO funnelDTO);
/**
* Verifies the specified funnel can be deleted.
@ -1145,11 +1160,12 @@ public interface NiFiServiceFacade {
/**
* Creates a label.
*
* @param revision revision
* @param groupId group
* @param labelDTO The label DTO
* @return The label DTO
*/
LabelEntity createLabel(String groupId, LabelDTO labelDTO);
LabelEntity createLabel(Revision revision, String groupId, LabelDTO labelDTO);
/**
* Gets the specified label.
@ -1174,7 +1190,7 @@ public interface NiFiServiceFacade {
* @param labelDTO The label DTO
* @return The label DTO
*/
UpdateResult<LabelEntity> updateLabel(Revision revision, LabelDTO labelDTO);
LabelEntity updateLabel(Revision revision, LabelDTO labelDTO);
/**
* Deletes the specified label.
@ -1210,7 +1226,7 @@ public interface NiFiServiceFacade {
* @param userDTO The user DTO
* @return The user transfer object
*/
UpdateResult<UserEntity> updateUser(Revision revision, UserDTO userDTO);
UserEntity updateUser(Revision revision, UserDTO userDTO);
/**
* Deletes the specified user.
@ -1245,7 +1261,7 @@ public interface NiFiServiceFacade {
* @param userGroupDTO The user group DTO
* @return The user group transfer object
*/
UpdateResult<UserGroupEntity> updateUserGroup(Revision revision, UserGroupDTO userGroupDTO);
UserGroupEntity updateUserGroup(Revision revision, UserGroupDTO userGroupDTO);
/**
* Deletes the specified user group.
@ -1279,7 +1295,7 @@ public interface NiFiServiceFacade {
* @param accessPolicyDTO The access policy DTO
* @return The access policy transfer object
*/
UpdateResult<AccessPolicyEntity> updateAccessPolicy(Revision revision, AccessPolicyDTO accessPolicyDTO);
AccessPolicyEntity updateAccessPolicy(Revision revision, AccessPolicyDTO accessPolicyDTO);
/**
* Deletes the specified access policy.
@ -1295,11 +1311,12 @@ public interface NiFiServiceFacade {
/**
* Creates a controller service.
*
* @param revision revision
* @param groupId the ID of the Process Group to add the Controller Service to
* @param controllerServiceDTO The controller service DTO
* @return The controller service DTO
*/
ControllerServiceEntity createControllerService(String groupId, ControllerServiceDTO controllerServiceDTO);
ControllerServiceEntity createControllerService(Revision revision, String groupId, ControllerServiceDTO controllerServiceDTO);
/**
* Gets all controller services that belong to the given group and its parent/ancestor groups
@ -1347,13 +1364,13 @@ public interface NiFiServiceFacade {
Map<String, Revision> referenceRevisions, String controllerServiceId, ScheduledState scheduledState, ControllerServiceState controllerServiceState);
/**
* Updates the specified label.
* Updates the specified controller service.
*
* @param revision Revision to compare with current base revision
* @param controllerServiceDTO The controller service DTO
* @return The controller service DTO
*/
UpdateResult<ControllerServiceEntity> updateControllerService(Revision revision, ControllerServiceDTO controllerServiceDTO);
ControllerServiceEntity updateControllerService(Revision revision, ControllerServiceDTO controllerServiceDTO);
/**
* Deletes the specified label.
@ -1393,10 +1410,11 @@ public interface NiFiServiceFacade {
/**
* Creates a reporting task.
*
* @param revision revision
* @param reportingTaskDTO The reporting task DTO
* @return The reporting task DTO
*/
ReportingTaskEntity createReportingTask(ReportingTaskDTO reportingTaskDTO);
ReportingTaskEntity createReportingTask(Revision revision, ReportingTaskDTO reportingTaskDTO);
/**
* Gets all reporting tasks.
@ -1429,7 +1447,7 @@ public interface NiFiServiceFacade {
* @param reportingTaskDTO The reporting task DTO
* @return The reporting task DTO
*/
UpdateResult<ReportingTaskEntity> updateReportingTask(Revision revision, ReportingTaskDTO reportingTaskDTO);
ReportingTaskEntity updateReportingTask(Revision revision, ReportingTaskDTO reportingTaskDTO);
/**
* Deletes the specified reporting task.

Просмотреть файл

@ -66,6 +66,11 @@ class StandardAuthorizableLookup implements AuthorizableLookup {
private TemplateDAO templateDAO;
private AccessPolicyDAO accessPolicyDAO;
@Override
public Authorizable getController() {
return controllerFacade;
}
@Override
public Authorizable getProcessor(final String id) {
return processorDAO.getProcessor(id);

Просмотреть файл

@ -17,15 +17,16 @@
package org.apache.nifi.web;
import com.google.common.collect.Sets;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.action.Action;
import org.apache.nifi.action.Component;
import org.apache.nifi.action.FlowChangeAction;
import org.apache.nifi.action.Operation;
import org.apache.nifi.action.details.FlowChangePurgeDetails;
import org.apache.nifi.admin.service.AuditService;
import org.apache.nifi.admin.service.KeyService;
import org.apache.nifi.authorization.AccessDeniedException;
import org.apache.nifi.authorization.AccessPolicy;
import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.AuthorizationResult.Result;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.Group;
import org.apache.nifi.authorization.RequestAction;
@ -97,6 +98,7 @@ import org.apache.nifi.web.api.dto.DocumentedTypeDTO;
import org.apache.nifi.web.api.dto.DropRequestDTO;
import org.apache.nifi.web.api.dto.DtoFactory;
import org.apache.nifi.web.api.dto.EntityFactory;
import org.apache.nifi.web.api.dto.FlowConfigurationDTO;
import org.apache.nifi.web.api.dto.FlowFileDTO;
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
import org.apache.nifi.web.api.dto.FunnelDTO;
@ -141,6 +143,7 @@ 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;
import org.apache.nifi.web.api.entity.FlowConfigurationEntity;
import org.apache.nifi.web.api.entity.FlowEntity;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.entity.LabelEntity;
@ -184,6 +187,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -240,7 +244,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// administrative services
private AuditService auditService;
private KeyService keyService;
// properties
private NiFiProperties properties;
@ -515,12 +518,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// Write Operations
// -----------------------------------------
@Override
public UpdateResult<AccessPolicyEntity> updateAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
// if access policy does not exist, then create new access policy
if (!accessPolicyDAO.hasAccessPolicy(accessPolicyDTO.getId())) {
return new UpdateResult<>(createAccessPolicy(revision, accessPolicyDTO), false);
}
public AccessPolicyEntity updateAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
final Authorizable accessPolicyAuthorizable = authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDTO.getId());
final RevisionUpdate<AccessPolicyDTO> snapshot = updateComponent(revision,
accessPolicyAuthorizable,
@ -532,16 +530,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
});
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(accessPolicyAuthorizable);
return new UpdateResult<>(entityFactory.createAccessPolicyEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
return entityFactory.createAccessPolicyEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
}
@Override
public UpdateResult<UserEntity> updateUser(final Revision revision, final UserDTO userDTO) {
// if user does not exist, then create new user
if (!userDAO.hasUser(userDTO.getId())) {
return new UpdateResult<>(createUser(revision, userDTO), false);
}
public UserEntity updateUser(final Revision revision, final UserDTO userDTO) {
final Authorizable usersAuthorizable = authorizableLookup.getUsersAuthorizable();
final RevisionUpdate<UserDTO> snapshot = updateComponent(revision,
usersAuthorizable,
@ -549,16 +542,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
user -> dtoFactory.createUserDto(user, user.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet())));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
return new UpdateResult<>(entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
return entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
}
@Override
public UpdateResult<UserGroupEntity> updateUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
// if user group does not exist, then create new user group
if (!userGroupDAO.hasUserGroup(userGroupDTO.getId())) {
return new UpdateResult<>(createUserGroup(revision, userGroupDTO), false);
}
public UserGroupEntity updateUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) {
final Authorizable userGroupsAuthorizable = authorizableLookup.getUserGroupsAuthorizable();
final RevisionUpdate<UserGroupDTO> snapshot = updateComponent(revision,
userGroupsAuthorizable,
@ -566,16 +554,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
userGroup -> dtoFactory.createUserGroupDto(userGroup, userGroup.getUsers().stream().map(userId -> getUser(userId, true)).collect(Collectors.toSet())));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
return new UpdateResult<>(entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
return entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
}
@Override
public UpdateResult<ConnectionEntity> updateConnection(final Revision revision, final ConnectionDTO connectionDTO) {
// if connection does not exist, then create new connection
if (connectionDAO.hasConnection(connectionDTO.getId()) == false) {
return new UpdateResult<>(createConnection(connectionDTO.getParentGroupId(), connectionDTO), true);
}
public ConnectionEntity updateConnection(final Revision revision, final ConnectionDTO connectionDTO) {
final Connection connectionNode = connectionDAO.getConnection(connectionDTO.getId());
final RevisionUpdate<ConnectionDTO> snapshot = updateComponent(
@ -586,16 +569,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(connectionNode);
final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionNode.getIdentifier()));
return new UpdateResult<>(entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status), false);
return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status);
}
@Override
public UpdateResult<ProcessorEntity> updateProcessor(final Revision revision, final ProcessorDTO processorDTO) {
// if processor does not exist, then create new processor
if (processorDAO.hasProcessor(processorDTO.getId()) == false) {
return new UpdateResult<>(createProcessor(processorDTO.getParentGroupId(), processorDTO), true);
}
public ProcessorEntity updateProcessor(final Revision revision, final ProcessorDTO processorDTO) {
// get the component, ensure we have access to it, and perform the update request
final ProcessorNode processorNode = processorDAO.getProcessor(processorDTO.getId());
final RevisionUpdate<ProcessorDTO> snapshot = updateComponent(revision,
@ -606,16 +584,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processorNode);
final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processorNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processorNode.getIdentifier()));
return new UpdateResult<>(entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins), false);
return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
}
@Override
public UpdateResult<LabelEntity> updateLabel(final Revision revision, final LabelDTO labelDTO) {
// if label does not exist, then create new label
if (labelDAO.hasLabel(labelDTO.getId()) == false) {
return new UpdateResult<>(createLabel(labelDTO.getParentGroupId(), labelDTO), false);
}
public LabelEntity updateLabel(final Revision revision, final LabelDTO labelDTO) {
final Label labelNode = labelDAO.getLabel(labelDTO.getId());
final RevisionUpdate<LabelDTO> snapshot = updateComponent(revision,
labelNode,
@ -623,16 +596,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
label -> dtoFactory.createLabelDto(label));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(labelNode);
return new UpdateResult<>(entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
}
@Override
public UpdateResult<FunnelEntity> updateFunnel(final Revision revision, final FunnelDTO funnelDTO) {
// if label does not exist, then create new label
if (funnelDAO.hasFunnel(funnelDTO.getId()) == false) {
return new UpdateResult<>(createFunnel(funnelDTO.getParentGroupId(), funnelDTO), true);
}
public FunnelEntity updateFunnel(final Revision revision, final FunnelDTO funnelDTO) {
final Funnel funnelNode = funnelDAO.getFunnel(funnelDTO.getId());
final RevisionUpdate<FunnelDTO> snapshot = updateComponent(revision,
funnelNode,
@ -640,7 +608,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
funnel -> dtoFactory.createFunnelDto(funnel));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(funnelNode);
return new UpdateResult<>(entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy), false);
return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy);
}
@ -657,7 +625,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
*/
private <D, C> RevisionUpdate<D> updateComponent(final Revision revision, final Authorizable authorizable, final Supplier<C> daoUpdate, final Function<C, D> dtoCreation) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final String userName = NiFiUserUtils.getNiFiUserName();
try {
final RevisionUpdate<D> updatedComponent = revisionManager.updateRevision(new StandardRevisionClaim(revision), user, new UpdateRevisionTask<D>() {
@Override
@ -668,10 +635,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// save updated controller
controllerFacade.save();
final Revision updatedRevision = incrementRevision(revision);
final D dto = dtoCreation.apply(component);
final FlowModification lastModification = new FlowModification(updatedRevision, userName);
final Revision updatedRevision = revisionManager.getRevision(revision.getComponentId()).incrementRevision(revision.getClientId());
final FlowModification lastModification = new FlowModification(updatedRevision, user.getUserName());
return new StandardRevisionUpdate<>(dto, lastModification);
}
});
@ -717,7 +684,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
controllerFacade.save();
// increment the revisions
final Set<Revision> updatedRevisions = revisions.stream().map(revision -> incrementRevision(revision)).collect(Collectors.toSet());
final Set<Revision> updatedRevisions = revisions.stream().map(revision -> {
final Revision currentRevision = revisionManager.getRevision(revision.getComponentId());
return currentRevision.incrementRevision(revision.getClientId());
}).collect(Collectors.toSet());
final SnippetDTO dto = dtoFactory.createSnippetDto(snippet);
return new StandardRevisionUpdate<>(dto, null, updatedRevisions);
@ -731,12 +701,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public UpdateResult<PortEntity> updateInputPort(final Revision revision, final PortDTO inputPortDTO) {
// if input port does not exist, then create new input port
if (inputPortDAO.hasPort(inputPortDTO.getId()) == false) {
return new UpdateResult<>(createInputPort(inputPortDTO.getParentGroupId(), inputPortDTO), true);
}
public PortEntity updateInputPort(final Revision revision, final PortDTO inputPortDTO) {
final Port inputPortNode = inputPortDAO.getPort(inputPortDTO.getId());
final RevisionUpdate<PortDTO> snapshot = updateComponent(revision,
inputPortNode,
@ -746,16 +711,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(inputPortNode);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(inputPortNode.getIdentifier()));
return new UpdateResult<>(entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins), false);
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
}
@Override
public UpdateResult<PortEntity> updateOutputPort(final Revision revision, final PortDTO outputPortDTO) {
// if output port does not exist, then create new output port
if (outputPortDAO.hasPort(outputPortDTO.getId()) == false) {
return new UpdateResult<>(createOutputPort(outputPortDTO.getParentGroupId(), outputPortDTO), true);
}
public PortEntity updateOutputPort(final Revision revision, final PortDTO outputPortDTO) {
final Port outputPortNode = outputPortDAO.getPort(outputPortDTO.getId());
final RevisionUpdate<PortDTO> snapshot = updateComponent(revision,
outputPortNode,
@ -765,16 +725,11 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(outputPortNode);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(outputPortNode.getIdentifier()));
return new UpdateResult<>(entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins), false);
return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, status, bulletins);
}
@Override
public UpdateResult<RemoteProcessGroupEntity> updateRemoteProcessGroup(final Revision revision, final RemoteProcessGroupDTO remoteProcessGroupDTO) {
// if controller reference does not exist, then create new controller reference
if (remoteProcessGroupDAO.hasRemoteProcessGroup(remoteProcessGroupDTO.getId()) == false) {
return new UpdateResult<>(createRemoteProcessGroup(remoteProcessGroupDTO.getParentGroupId(), remoteProcessGroupDTO), true);
}
public RemoteProcessGroupEntity updateRemoteProcessGroup(final Revision revision, final RemoteProcessGroupDTO remoteProcessGroupDTO) {
final RemoteProcessGroup remoteProcessGroupNode = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupDTO.getId());
final RevisionUpdate<RemoteProcessGroupDTO> snapshot = updateComponent(
revision,
@ -786,7 +741,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(remoteProcessGroupNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(remoteProcessGroupNode.getIdentifier()));
return new UpdateResult<>(entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), updateRevision, accessPolicy, status, bulletins), false);
return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), updateRevision, accessPolicy, status, bulletins);
}
@Override
@ -822,16 +777,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public UpdateResult<ProcessGroupEntity> updateProcessGroup(final Revision revision, final ProcessGroupDTO processGroupDTO) {
// if process group does not exist, then create new process group
if (processGroupDAO.hasProcessGroup(processGroupDTO.getId()) == false) {
if (processGroupDTO.getParentGroupId() == null) {
throw new IllegalArgumentException("Unable to create the specified process group since the parent group was not specified.");
} else {
return new UpdateResult<>(createProcessGroup(processGroupDTO.getParentGroupId(), processGroupDTO), true);
}
}
public ProcessGroupEntity updateProcessGroup(final Revision revision, final ProcessGroupDTO processGroupDTO) {
final ProcessGroup processGroupNode = processGroupDAO.getProcessGroup(processGroupDTO.getId());
final RevisionUpdate<ProcessGroupDTO> snapshot = updateComponent(revision,
processGroupNode,
@ -842,7 +788,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification());
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroupNode.getIdentifier()));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroupNode.getIdentifier()));
return new UpdateResult<>(entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, accessPolicy, status, bulletins), false);
return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, accessPolicy, status, bulletins);
}
@Override
@ -859,8 +805,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final Map<String, Revision> updatedRevisions = new HashMap<>();
for (final Revision revision : componentRevisions.values()) {
final Revision currentRevision = revisionManager.getRevision(revision.getComponentId());
final Revision updatedRevision = incrementRevision(currentRevision);
updatedRevisions.put(revision.getComponentId(), updatedRevision);
updatedRevisions.put(revision.getComponentId(), currentRevision.incrementRevision(revision.getClientId()));
}
// gather details for response
@ -887,9 +832,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount());
}
return controllerConfigurationDTO;
},
controller -> dtoFactory.createControllerConfigurationDto(controllerFacade, properties.getAutoRefreshInterval()));
return controllerConfigurationDTO;
},
controller -> dtoFactory.createControllerConfigurationDto(controllerFacade));
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(updatedComponent.getLastModification());
@ -991,17 +936,12 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public DropRequestDTO deleteFlowFileDropRequest(final String connectionId, final String dropRequestId) {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
return dtoFactory.createDropRequestDTO(connectionDAO.deleteFlowFileDropRequest(connectionId, dropRequestId));
}
@Override
public ListingRequestDTO deleteFlowFileListingRequest(final String connectionId, final String listingRequestId) {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
final ListingRequestDTO listRequest = dtoFactory.createListingRequestDTO(connectionDAO.deleteFlowFileListingRequest(connectionId, listingRequestId));
// include whether the source and destination are running
@ -1211,8 +1151,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public ConnectionEntity createConnection(final String groupId, final ConnectionDTO connectionDTO) {
public ConnectionEntity createConnection(final Revision revision, final String groupId, final ConnectionDTO connectionDTO) {
final RevisionUpdate<ConnectionDTO> snapshot = createComponent(
revision,
connectionDTO,
() -> connectionDAO.createConnection(groupId, connectionDTO),
connection -> dtoFactory.createConnectionDto(connection));
@ -1225,17 +1166,12 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public DropRequestDTO createFlowFileDropRequest(final String connectionId, final String dropRequestId) {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
return dtoFactory.createDropRequestDTO(connectionDAO.createFlowFileDropRequest(connectionId, dropRequestId));
}
@Override
public ListingRequestDTO createFlowFileListingRequest(final String connectionId, final String listingRequestId) {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
// create the listing request
final ListingRequestDTO listRequest = dtoFactory.createListingRequestDTO(connectionDAO.createFlowFileListingRequest(connectionId, listingRequestId));
// include whether the source and destination are running
@ -1250,8 +1186,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public ProcessorEntity createProcessor(final String groupId, final ProcessorDTO processorDTO) {
public ProcessorEntity createProcessor(final Revision revision, final String groupId, final ProcessorDTO processorDTO) {
final RevisionUpdate<ProcessorDTO> snapshot = createComponent(
revision,
processorDTO,
() -> processorDAO.createProcessor(groupId, processorDTO),
processor -> dtoFactory.createProcessorDto(processor));
@ -1264,8 +1201,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public LabelEntity createLabel(final String groupId, final LabelDTO labelDTO) {
public LabelEntity createLabel(final Revision revision, final String groupId, final LabelDTO labelDTO) {
final RevisionUpdate<LabelDTO> snapshot = createComponent(
revision,
labelDTO,
() -> labelDAO.createLabel(groupId, labelDTO),
label -> dtoFactory.createLabelDto(label));
@ -1285,32 +1223,39 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
* @param <C> the NiFi Component Type
* @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) {
final String modifier = NiFiUserUtils.getNiFiUserName();
// ensure id is set
if (StringUtils.isBlank(componentDto.getId())) {
componentDto.setId(UUID.randomUUID().toString());
}
private <D, C> RevisionUpdate<D> createComponent(final Revision revision, final ComponentDTO componentDto, final Supplier<C> daoCreation, final Function<C, D> dtoCreation) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final String groupId = componentDto.getParentGroupId();
// read lock on the containing group
return revisionManager.get(groupId, rev -> {
// add the component
final C component = daoCreation.get();
// request claim for component to be created... revision already verified (version == 0)
final RevisionClaim claim = revisionManager.requestClaim(revision, user);
try {
// update revision through revision manager
return revisionManager.updateRevision(claim, user, () -> {
// add the component
final C component = daoCreation.get();
// save the flow
controllerFacade.save();
// save the flow
controllerFacade.save();
final D dto = dtoCreation.apply(component);
final FlowModification lastMod = new FlowModification(new Revision(0L, rev.getClientId(), componentDto.getId()), modifier);
return new StandardRevisionUpdate<D>(dto, lastMod);
final D dto = dtoCreation.apply(component);
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getUserName());
return new StandardRevisionUpdate<D>(dto, lastMod);
});
} finally {
// cancel in case of exception... noop if successful
revisionManager.cancelClaim(revision.getComponentId());
}
});
}
@Override
public FunnelEntity createFunnel(final String groupId, final FunnelDTO funnelDTO) {
public FunnelEntity createFunnel(final Revision revision, final String groupId, final FunnelDTO funnelDTO) {
final RevisionUpdate<FunnelDTO> snapshot = createComponent(
revision,
funnelDTO,
() -> funnelDAO.createFunnel(groupId, funnelDTO),
funnel -> dtoFactory.createFunnelDto(funnel));
@ -1323,9 +1268,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public AccessPolicyEntity createAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) {
final String creator = NiFiUserUtils.getNiFiUserName();
if (revision.getVersion() != 0) {
throw new IllegalArgumentException("The revision must start at 0.");
}
final AccessPolicy newAccessPolicy = accessPolicyDAO.createAccessPolicy(accessPolicyDTO);
final AccessPolicyDTO newAccessPolicyDto = dtoFactory.createAccessPolicyDto(newAccessPolicy,
newAccessPolicy.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()),
@ -1338,9 +1280,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public UserEntity createUser(final Revision revision, final UserDTO userDTO) {
final String creator = NiFiUserUtils.getNiFiUserName();
if (revision.getVersion() != 0) {
throw new IllegalArgumentException("The revision must start at 0.");
}
final User newUser = userDAO.createUser(userDTO);
final UserDTO newUserDto = dtoFactory.createUserDto(newUser, newUser.getGroups().stream().map(userGroupId -> getUserGroup(userGroupId, true)).collect(Collectors.toSet()));
@ -1458,8 +1397,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public PortEntity createInputPort(final String groupId, final PortDTO inputPortDTO) {
public PortEntity createInputPort(final Revision revision, final String groupId, final PortDTO inputPortDTO) {
final RevisionUpdate<PortDTO> snapshot = createComponent(
revision,
inputPortDTO,
() -> inputPortDAO.createPort(groupId, inputPortDTO),
port -> dtoFactory.createPortDto(port));
@ -1472,8 +1412,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public PortEntity createOutputPort(final String groupId, final PortDTO outputPortDTO) {
public PortEntity createOutputPort(final Revision revision, final String groupId, final PortDTO outputPortDTO) {
final RevisionUpdate<PortDTO> snapshot = createComponent(
revision,
outputPortDTO,
() -> outputPortDAO.createPort(groupId, outputPortDTO),
port -> dtoFactory.createPortDto(port));
@ -1486,8 +1427,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public ProcessGroupEntity createProcessGroup(final String parentGroupId, final ProcessGroupDTO processGroupDTO) {
public ProcessGroupEntity createProcessGroup(final Revision revision, final String parentGroupId, final ProcessGroupDTO processGroupDTO) {
final RevisionUpdate<ProcessGroupDTO> snapshot = createComponent(
revision,
processGroupDTO,
() -> processGroupDAO.createProcessGroup(parentGroupId, processGroupDTO),
processGroup -> dtoFactory.createProcessGroupDto(processGroup));
@ -1500,8 +1442,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public RemoteProcessGroupEntity createRemoteProcessGroup(final String groupId, final RemoteProcessGroupDTO remoteProcessGroupDTO) {
public RemoteProcessGroupEntity createRemoteProcessGroup(final Revision revision, final String groupId, final RemoteProcessGroupDTO remoteProcessGroupDTO) {
final RevisionUpdate<RemoteProcessGroupDTO> snapshot = createComponent(
revision,
remoteProcessGroupDTO,
() -> remoteProcessGroupDAO.createRemoteProcessGroup(groupId, remoteProcessGroupDTO),
remoteProcessGroup -> dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup));
@ -1639,49 +1582,60 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
}
@Override
public ControllerServiceEntity createControllerService(final String groupId, final ControllerServiceDTO controllerServiceDTO) {
public ControllerServiceEntity createControllerService(final Revision revision, final String groupId, final ControllerServiceDTO controllerServiceDTO) {
controllerServiceDTO.setParentGroupId(groupId);
final String modifier = NiFiUserUtils.getNiFiUserName();
final NiFiUser user = NiFiUserUtils.getNiFiUser();
// ensure id is set
if (StringUtils.isBlank(controllerServiceDTO.getId())) {
controllerServiceDTO.setId(UUID.randomUUID().toString());
}
// request claim for component to be created... revision already verified (version == 0)
final RevisionClaim claim = revisionManager.requestClaim(revision, user);
final ControllerServiceDTO updatedService;
final RevisionUpdate<ControllerServiceDTO> snapshot;
if (groupId == null) {
// Unfortunately, we can not use the createComponent() method here because createComponent() wants to obtain the read lock
// on the group. The Controller Service may or may not have a Process Group (it won't if it's controller-scoped).
final ControllerServiceNode controllerService = controllerServiceDAO.createControllerService(controllerServiceDTO);
updatedService = dtoFactory.createControllerServiceDto(controllerService);
controllerFacade.save();
} else {
updatedService = revisionManager.get(groupId, new ReadOnlyRevisionCallback<ControllerServiceDTO>() {
@Override
public ControllerServiceDTO withRevision(final Revision groupRevision) {
try {
// update revision through revision manager
snapshot = revisionManager.updateRevision(claim, user, () -> {
// Unfortunately, we can not use the createComponent() method here because createComponent() wants to obtain the read lock
// on the group. The Controller Service may or may not have a Process Group (it won't if it's controller-scoped).
final ControllerServiceNode controllerService = controllerServiceDAO.createControllerService(controllerServiceDTO);
final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(controllerService);
controllerFacade.save();
return dtoFactory.createControllerServiceDto(controllerService);
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getUserName());
return new StandardRevisionUpdate<ControllerServiceDTO>(dto, lastMod);
});
} finally {
// cancel in case of exception... noop if successful
revisionManager.cancelClaim(revision.getComponentId());
}
} else {
snapshot = revisionManager.get(groupId, groupRevision -> {
try {
return revisionManager.updateRevision(claim, user, () -> {
final ControllerServiceNode controllerService = controllerServiceDAO.createControllerService(controllerServiceDTO);
final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(controllerService);
controllerFacade.save();
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getUserName());
return new StandardRevisionUpdate<ControllerServiceDTO>(dto, lastMod);
});
} finally {
// cancel in case of exception... noop if successful
revisionManager.cancelClaim(revision.getComponentId());
}
});
}
final FlowModification lastMod = new FlowModification(new Revision(0L, null, controllerServiceDTO.getId()), modifier);
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerService);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId()));
return entityFactory.createControllerServiceEntity(updatedService, dtoFactory.createRevisionDTO(lastMod), accessPolicy, bulletins);
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
}
@Override
public UpdateResult<ControllerServiceEntity> updateControllerService(final Revision revision, final ControllerServiceDTO controllerServiceDTO) {
// if controller service does not exist, then create new controller service
if (controllerServiceDAO.hasControllerService(controllerServiceDTO.getId()) == false) {
return new UpdateResult<>(createControllerService(controllerServiceDTO.getParentGroupId(), controllerServiceDTO), true);
}
public ControllerServiceEntity updateControllerService(final Revision revision, final ControllerServiceDTO controllerServiceDTO) {
// get the component, ensure we have access to it, and perform the update request
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceDTO.getId());
final RevisionUpdate<ControllerServiceDTO> snapshot = updateComponent(revision,
@ -1691,7 +1645,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerService);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId()));
return new UpdateResult<>(entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins), false);
return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
}
@Override
@ -1705,27 +1659,14 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
new UpdateRevisionTask<ControllerServiceReferencingComponentsEntity>() {
@Override
public RevisionUpdate<ControllerServiceReferencingComponentsEntity> update() {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId);
final ControllerServiceReference reference = controllerService.getReferences();
for (final ConfiguredComponent component : reference.getReferencingComponents()) {
if (component instanceof Authorizable) {
// ensure we can write the referencing components
((Authorizable) component).authorize(authorizer, RequestAction.WRITE);
}
}
final Set<ConfiguredComponent> updated = controllerServiceDAO.updateControllerServiceReferencingComponents(controllerServiceId, scheduledState, controllerServiceState);
final ControllerServiceReference updatedReference = controllerServiceDAO.getControllerService(controllerServiceId).getReferences();
final Map<String, Revision> updatedRevisions = new HashMap<>();
for (final Revision refRevision : referenceRevisions.values()) {
updatedRevisions.put(refRevision.getComponentId(), refRevision);
}
for (final ConfiguredComponent component : updated) {
final Revision currentRevision = revisionManager.getRevision(component.getIdentifier());
final Revision updatedRevision = incrementRevision(currentRevision);
updatedRevisions.put(component.getIdentifier(), updatedRevision);
final Revision requestRevision = referenceRevisions.get(component.getIdentifier());
updatedRevisions.put(component.getIdentifier(), currentRevision.incrementRevision(requestRevision.getClientId()));
}
final ControllerServiceReferencingComponentsEntity entity = createControllerServiceReferencingComponentsEntity(updatedReference, updatedRevisions);
@ -1858,39 +1799,37 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public ReportingTaskEntity createReportingTask(final ReportingTaskDTO reportingTaskDTO) {
final String modifier = NiFiUserUtils.getNiFiUserName();
public ReportingTaskEntity createReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
// ensure id is set
if (StringUtils.isBlank(reportingTaskDTO.getId())) {
reportingTaskDTO.setId(UUID.randomUUID().toString());
}
// request claim for component to be created... revision already verified (version == 0)
final RevisionClaim claim = revisionManager.requestClaim(revision, user);
try {
// update revision through revision manager
final RevisionUpdate<ReportingTaskDTO> snapshot = revisionManager.updateRevision(claim, user, () -> {
// create the reporting task
final ReportingTaskNode reportingTask = reportingTaskDAO.createReportingTask(reportingTaskDTO);
return revisionManager.get(controllerFacade.getInstanceId(), rev -> {
// ensure access to the controller
controllerFacade.authorize(authorizer, RequestAction.WRITE);
// save the update
controllerFacade.save();
// create the reporting task
final ReportingTaskNode reportingTask = reportingTaskDAO.createReportingTask(reportingTaskDTO);
final ReportingTaskDTO dto = dtoFactory.createReportingTaskDto(reportingTask);
final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getUserName());
return new StandardRevisionUpdate<ReportingTaskDTO>(dto, lastMod);
});
// save the update
controllerFacade.save();
final ReportingTaskDTO dto = dtoFactory.createReportingTaskDto(reportingTask);
final FlowModification lastMod = new FlowModification(new Revision(0L, rev.getClientId(), dto.getId()), modifier);
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId());
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(reportingTask);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier()));
return entityFactory.createReportingTaskEntity(dto, dtoFactory.createRevisionDTO(lastMod), accessPolicy, bulletins);
});
return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
} finally {
// cancel in case of exception... noop if successful
revisionManager.cancelClaim(revision.getComponentId());
}
}
@Override
public UpdateResult<ReportingTaskEntity> updateReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) {
// if reporting task does not exist, then create new reporting task
if (reportingTaskDAO.hasReportingTask(reportingTaskDTO.getId()) == false) {
return new UpdateResult<>(createReportingTask(reportingTaskDTO), true);
}
public ReportingTaskEntity updateReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) {
// get the component, ensure we have access to it, and perform the update request
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId());
final RevisionUpdate<ReportingTaskDTO> snapshot = updateComponent(revision,
@ -1900,7 +1839,7 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(reportingTask);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier()));
return new UpdateResult<>(entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins), false);
return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), accessPolicy, bulletins);
}
@Override
@ -2079,9 +2018,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<ConnectionEntity> getConnections(final String groupId) {
return revisionManager.get(groupId, rev -> {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<Connection> connections = connectionDAO.getConnections(groupId);
final Set<String> connectionIds = connections.stream().map(connection -> connection.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(connectionIds, () -> {
@ -2101,8 +2037,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public ConnectionEntity getConnection(final String connectionId) {
return revisionManager.get(connectionId, rev -> {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(connection);
final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionId));
@ -2112,16 +2046,12 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public DropRequestDTO getFlowFileDropRequest(final String connectionId, final String dropRequestId) {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
return dtoFactory.createDropRequestDTO(connectionDAO.getFlowFileDropRequest(connectionId, dropRequestId));
}
@Override
public ListingRequestDTO getFlowFileListingRequest(final String connectionId, final String listingRequestId) {
final Connection connection = connectionDAO.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
final ListingRequestDTO listRequest = dtoFactory.createListingRequestDTO(connectionDAO.getFlowFileListingRequest(connectionId, listingRequestId));
// include whether the source and destination are running
@ -2152,9 +2082,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<ProcessorEntity> getProcessors(final String groupId) {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<ProcessorNode> processors = processorDAO.getProcessors(groupId);
final Set<String> ids = processors.stream().map(proc -> proc.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(ids, () -> {
@ -2219,8 +2146,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public ProcessorEntity getProcessor(final String id) {
return revisionManager.get(id, rev -> {
final ProcessorNode processor = processorDAO.getProcessor(id);
processor.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(id));
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(id));
@ -2396,19 +2321,25 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public ControllerConfigurationEntity getControllerConfiguration() {
return revisionManager.get(FlowController.class.getSimpleName(), rev -> {
final ControllerConfigurationDTO dto = dtoFactory.createControllerConfigurationDto(controllerFacade, properties.getAutoRefreshInterval());
final ControllerConfigurationDTO dto = dtoFactory.createControllerConfigurationDto(controllerFacade);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerFacade);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
return entityFactory.createControllerConfigurationEntity(dto, revision, accessPolicy);
});
}
@Override
public FlowConfigurationEntity getFlowConfiguration() {
final FlowConfigurationDTO dto = dtoFactory.createFlowConfigurationDto(properties.getAutoRefreshInterval());
final FlowConfigurationEntity entity = new FlowConfigurationEntity();
entity.setFlowConfiguration(dto);
return entity;
}
@Override
public AccessPolicyEntity getAccessPolicy(final String accessPolicyId) {
return revisionManager.get(accessPolicyId, rev -> {
final Authorizable accessPolicyAuthorizable = authorizableLookup.getAccessPolicyAuthorizable(accessPolicyId);
accessPolicyAuthorizable.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(accessPolicyAuthorizable);
final AccessPolicy requestedAccessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId);
@ -2424,8 +2355,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public UserEntity getUser(final String userId, final boolean prune) {
return revisionManager.get(userId, rev -> {
final Authorizable usersAuthorizable = authorizableLookup.getUsersAuthorizable();
usersAuthorizable.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
final User user = userDAO.getUser(userId);
@ -2439,8 +2368,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private UserEntity getUserPruned(final String userId) {
return revisionManager.get(userId, rev -> {
final Authorizable usersAuthorizable = authorizableLookup.getUsersAuthorizable();
usersAuthorizable.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(usersAuthorizable);
final User user = userDAO.getUser(userId);
@ -2452,8 +2379,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public UserGroupEntity getUserGroup(final String userGroupId, final boolean prune) {
return revisionManager.get(userGroupId, rev -> {
final Authorizable userGroupsAuthorizable = authorizableLookup.getUserGroupsAuthorizable();
userGroupsAuthorizable.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
@ -2466,8 +2391,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
private UserGroupEntity getUserGroupPruned(final String userGroupId) {
return revisionManager.get(userGroupId, rev -> {
final Authorizable userGroupsAuthorizable = authorizableLookup.getUserGroupsAuthorizable();
userGroupsAuthorizable.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(userGroupsAuthorizable);
final Group userGroup = userGroupDAO.getUserGroup(userGroupId);
@ -2477,9 +2400,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<LabelEntity> getLabels(final String groupId) {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<Label> labels = labelDAO.getLabels(groupId);
final Set<String> ids = labels.stream().map(label -> label.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(ids, () -> {
@ -2497,8 +2417,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public LabelEntity getLabel(final String labelId) {
return revisionManager.get(labelId, rev -> {
final Label label = labelDAO.getLabel(labelId);
label.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(label);
return entityFactory.createLabelEntity(dtoFactory.createLabelDto(label), revision, accessPolicy);
@ -2507,9 +2425,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<FunnelEntity> getFunnels(final String groupId) {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<Funnel> funnels = funnelDAO.getFunnels(groupId);
final Set<String> funnelIds = funnels.stream().map(funnel -> funnel.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(funnelIds, () -> {
@ -2527,8 +2442,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public FunnelEntity getFunnel(final String funnelId) {
return revisionManager.get(funnelId, rev -> {
final Funnel funnel = funnelDAO.getFunnel(funnelId);
funnel.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(funnel);
return entityFactory.createFunnelEntity(dtoFactory.createFunnelDto(funnel), revision, accessPolicy);
@ -2537,9 +2450,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<PortEntity> getInputPorts(final String groupId) {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<Port> inputPorts = inputPortDAO.getPorts(groupId);
final Set<String> portIds = inputPorts.stream().map(port -> port.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(portIds, () -> {
@ -2557,9 +2467,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<PortEntity> getOutputPorts(final String groupId) {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<Port> ports = outputPortDAO.getPorts(groupId);
final Set<String> ids = ports.stream().map(port -> port.getIdentifier()).collect(Collectors.toSet());
@ -2578,9 +2485,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<ProcessGroupEntity> getProcessGroups(final String parentGroupId) {
final ProcessGroup parentGroup = processGroupDAO.getProcessGroup(parentGroupId);
parentGroup.authorize(authorizer, RequestAction.READ);
final Set<ProcessGroup> groups = processGroupDAO.getProcessGroups(parentGroupId);
final Set<String> ids = groups.stream().map(group -> group.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(ids, () -> {
@ -2598,12 +2502,8 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
@Override
public Set<RemoteProcessGroupEntity> getRemoteProcessGroups(final String groupId) {
final ProcessGroup group = processGroupDAO.getProcessGroup(groupId);
group.authorize(authorizer, RequestAction.READ);
final Set<RemoteProcessGroup> rpgs = remoteProcessGroupDAO.getRemoteProcessGroups(groupId);
final Set<String> ids = rpgs.stream().map(rpg -> rpg.getIdentifier()).collect(Collectors.toSet());
return revisionManager.get(ids, () -> {
return rpgs.stream()
.map(rpg -> {
@ -2621,8 +2521,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public PortEntity getInputPort(final String inputPortId) {
return revisionManager.get(inputPortId, rev -> {
final Port port = inputPortDAO.getPort(inputPortId);
port.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(port);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortId));
@ -2640,8 +2538,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public PortEntity getOutputPort(final String outputPortId) {
return revisionManager.get(outputPortId, rev -> {
final Port port = outputPortDAO.getPort(outputPortId);
port.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(port);
final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortId));
@ -2659,8 +2555,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public RemoteProcessGroupEntity getRemoteProcessGroup(final String remoteProcessGroupId) {
return revisionManager.get(remoteProcessGroupId, rev -> {
final RemoteProcessGroup rpg = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId);
rpg.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(rpg);
final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(controllerFacade.getRemoteProcessGroupStatus(rpg.getIdentifier()));
@ -2727,8 +2621,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public ProcessGroupEntity getProcessGroup(final String groupId) {
return revisionManager.get(groupId, rev -> {
final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId);
processGroup.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(processGroup);
final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(groupId));
@ -2764,8 +2656,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public ControllerServiceEntity getControllerService(final String controllerServiceId) {
return revisionManager.get(controllerServiceId, rev -> {
final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId);
controllerService.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(controllerService);
final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(controllerService);
@ -2826,8 +2716,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
public ReportingTaskEntity getReportingTask(final String reportingTaskId) {
return revisionManager.get(reportingTaskId, rev -> {
final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId);
reportingTask.authorize(authorizer, RequestAction.READ);
final RevisionDTO revision = dtoFactory.createRevisionDTO(rev);
final AccessPolicyDTO accessPolicy = dtoFactory.createAccessPolicyDto(reportingTask);
final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTaskId));
@ -2853,6 +2741,56 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
return controllerFacade.getProcessGroupStatusHistory(groupId);
}
private boolean authorizeAction(final Action action) {
final String sourceId = action.getSourceId();
final Component type = action.getSourceType();
final Authorizable authorizable;
try {
switch (type) {
case Processor:
authorizable = authorizableLookup.getProcessor(sourceId);
break;
case ReportingTask:
authorizable = authorizableLookup.getReportingTask(sourceId);
break;
case ControllerService:
authorizable = authorizableLookup.getControllerService(sourceId);
break;
case Controller:
authorizable = controllerFacade;
break;
case InputPort:
authorizable = authorizableLookup.getInputPort(sourceId);
break;
case OutputPort:
authorizable = authorizableLookup.getOutputPort(sourceId);
break;
case ProcessGroup:
authorizable = authorizableLookup.getProcessGroup(sourceId);
break;
case RemoteProcessGroup:
authorizable = authorizableLookup.getRemoteProcessGroup(sourceId);
break;
case Funnel:
authorizable = authorizableLookup.getFunnel(sourceId);
break;
case Connection:
authorizable = authorizableLookup.getConnection(sourceId);
break;
default:
throw new WebApplicationException(Response.serverError().entity("An unexpected type of component is the source of this action.").build());
}
} catch (final ResourceNotFoundException e) {
// if the underlying component is gone, disallow
return false;
}
// perform the authorization
final AuthorizationResult result = authorizable.checkAuthorization(authorizer, RequestAction.READ);
return Result.Approved.equals(result.getResult());
}
@Override
public HistoryDTO getActions(final HistoryQueryDTO historyQueryDto) {
// extract the query criteria
@ -2869,6 +2807,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
// perform the query
final History history = auditService.getActions(historyQuery);
// only retain authorized actions
history.getActions().stream().filter(action -> authorizeAction(action)).collect(Collectors.toList());
// create the response
return dtoFactory.createHistoryDto(history);
}
@ -2883,6 +2824,10 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
throw new ResourceNotFoundException(String.format("Unable to find action with id '%s'.", actionId));
}
if (!authorizeAction(action)) {
throw new AccessDeniedException("Access is denied.");
}
// return the action
return dtoFactory.createActionDto(action);
}
@ -3027,10 +2972,6 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
this.auditService = auditService;
}
public void setKeyService(final KeyService keyService) {
this.keyService = keyService;
}
public void setRevisionManager(final RevisionManager revisionManager) {
this.revisionManager = revisionManager;
}

Просмотреть файл

@ -428,8 +428,8 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
try {
ProcessorDTO processorDTO = buildProcessorDto(id,annotationData,properties);
final UpdateResult<ProcessorEntity> entity = serviceFacade.updateProcessor(revision,processorDTO);
processor = entity.getResult().getComponent();
final ProcessorEntity entity = serviceFacade.updateProcessor(revision,processorDTO);
processor = entity.getComponent();
} finally {
// ensure the revision is canceled.. if the operation succeed, this is a noop
@ -582,8 +582,8 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
serviceFacade.claimRevision(revision, user);
try {
// perform the update
final UpdateResult<ControllerServiceEntity> updateResult = serviceFacade.updateControllerService(revision, controllerServiceDto);
controllerService = updateResult.getResult().getComponent();
final ControllerServiceEntity entity = serviceFacade.updateControllerService(revision, controllerServiceDto);
controllerService = entity.getComponent();
} finally {
// ensure the revision is canceled.. if the operation succeed, this is a noop
serviceFacade.cancelRevision(revision);
@ -749,8 +749,8 @@ public class StandardNiFiWebConfigurationContext implements NiFiWebConfiguration
// claim the revision
serviceFacade.claimRevision(revision, user);
try {
final UpdateResult<ReportingTaskEntity> updateResult = serviceFacade.updateReportingTask(revision, reportingTaskDto);
reportingTask = updateResult.getResult().getComponent();
final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, reportingTaskDto);
reportingTask = entity.getComponent();
} finally {
// ensure the revision is canceled.. if the operation succeed, this is a noop
serviceFacade.cancelRevision(revision);

Просмотреть файл

@ -1,40 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web;
/**
* Result from an update operation.
*/
@SuppressWarnings("serial")
public class UpdateResult<T> {
private final T result;
private final boolean isNew;
public UpdateResult(T result, boolean isNew) {
this.result = result;
this.isNew = isNew;
}
public T getResult() {
return result;
}
public boolean isNew() {
return isNew;
}
}

Просмотреть файл

@ -31,7 +31,6 @@ import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.AccessPolicyDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.entity.AccessPolicyEntity;
@ -188,6 +187,10 @@ public class AccessPolicyResource extends ApplicationResource {
throw new IllegalArgumentException("Access policy details must be specified.");
}
if (accessPolicyEntity.getRevision() == null || (accessPolicyEntity.getRevision().getVersion() == null || accessPolicyEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Processor.");
}
if (accessPolicyEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Access policy ID cannot be specified.");
}
@ -343,23 +346,16 @@ public class AccessPolicyResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable accessPolicy = lookup.getAccessPolicyAuthorizable(id);
accessPolicy.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getAccessPolicyAuthorizable(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
null,
() -> {
// update the access policy
final UpdateResult<AccessPolicyEntity> updateResult = serviceFacade.updateAccessPolicy(revision, accessPolicyDTO);
// get the results
final AccessPolicyEntity entity = updateResult.getResult();
final AccessPolicyEntity entity = serviceFacade.updateAccessPolicy(revision, accessPolicyDTO);
populateRemainingAccessPolicyEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -1,357 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web.api;
import java.util.ArrayList;
import java.util.List;
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.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
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.cluster.coordination.node.NodeConnectionState;
import org.apache.nifi.web.IllegalClusterResourceRequestException;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.api.dto.ClusterDTO;
import org.apache.nifi.web.api.dto.NodeDTO;
import org.apache.nifi.web.api.dto.search.NodeSearchResultDTO;
import org.apache.nifi.web.api.entity.ClusterEntity;
import org.apache.nifi.web.api.entity.ClusterSearchResultsEntity;
import org.apache.nifi.web.api.entity.NodeEntity;
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;
/**
* RESTful endpoint for managing a cluster.
*/
@Path("/cluster")
@Api(
value = "/cluster",
description = "Endpoint for managing the cluster."
)
public class ClusterResource extends ApplicationResource {
@Context
private ResourceContext resourceContext;
private NiFiServiceFacade serviceFacade;
/**
* 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)
public Response getClusterHead() {
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.
*
* @return A clusterEntity
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets the contents of the cluster",
notes = "Returns the contents of the cluster including all nodes and their status.",
response = ClusterEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "DFM", type = "ROLE_DFM"),
@Authorization(value = "Admin", 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 getCluster() {
if (isConnectedToCluster()) {
final ClusterDTO dto = serviceFacade.getCluster();
// create entity
final ClusterEntity entity = new ClusterEntity();
entity.setCluster(dto);
// generate the response
return generateOkResponse(entity).build();
}
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
/**
* Searches the cluster for a node with a given address.
*
* @param value Search value that will be matched against a node's address
* @return Nodes that match the specified criteria
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("/search-results")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Searches the cluster for a node with the specified address",
response = ClusterSearchResultsEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "DFM", type = "ROLE_DFM"),
@Authorization(value = "Admin", 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 = 404, message = "The specified resource could not be found."),
@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 searchCluster(
@ApiParam(
value = "Node address to search for.",
required = true
)
@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) {
// ensure this is the cluster manager
if (isConnectedToCluster()) {
final List<NodeSearchResultDTO> nodeMatches = new ArrayList<>();
// get the nodes in the cluster
final ClusterDTO cluster = serviceFacade.getCluster();
// check each to see if it matches the search term
for (NodeDTO node : cluster.getNodes()) {
// ensure the node is connected
if (!NodeConnectionState.CONNECTED.name().equals(node.getStatus())) {
continue;
}
// determine the current nodes address
final String address = node.getAddress() + ":" + node.getApiPort();
// count the node if there is no search or it matches the address
if (StringUtils.isBlank(value) || StringUtils.containsIgnoreCase(address, value)) {
final NodeSearchResultDTO nodeMatch = new NodeSearchResultDTO();
nodeMatch.setId(node.getNodeId());
nodeMatch.setAddress(address);
nodeMatches.add(nodeMatch);
}
}
// build the response
ClusterSearchResultsEntity results = new ClusterSearchResultsEntity();
results.setNodeResults(nodeMatches);
// generate an 200 - OK response
return noCache(Response.ok(results)).build();
}
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
/**
* Gets the contents of the specified node in this NiFi cluster.
*
* @param id The node id.
* @return A nodeEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("nodes/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets a node in the cluster",
response = NodeEntity.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 = 404, message = "The specified resource could not be found."),
@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 getNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id) {
// get the specified relationship
final NodeDTO dto = serviceFacade.getNode(id);
// create the response entity
final NodeEntity entity = new NodeEntity();
entity.setNode(dto);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Updates the contents of the specified node in this NiFi cluster.
*
* @param id The id of the node
* @param nodeEntity A nodeEntity
* @return A nodeEntity
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("nodes/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@ApiOperation(
value = "Updates a node in the cluster",
response = NodeEntity.class,
authorizations = {
@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 = 404, message = "The specified resource could not be found."),
@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 updateNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id,
@ApiParam(
value = "The node configuration. The only configuration that will be honored at this endpoint is the status or primary flag.",
required = true
) NodeEntity nodeEntity) {
if (nodeEntity == null || nodeEntity.getNode() == null) {
throw new IllegalArgumentException("Node details must be specified.");
}
// get the request node
final NodeDTO requestNodeDTO = nodeEntity.getNode();
if (!id.equals(requestNodeDTO.getNodeId())) {
throw new IllegalArgumentException(String.format("The node id (%s) in the request body does "
+ "not equal the node id of the requested resource (%s).", requestNodeDTO.getNodeId(), id));
}
// update the node
final NodeDTO node = serviceFacade.updateNode(requestNodeDTO);
// create the response entity
NodeEntity entity = new NodeEntity();
entity.setNode(node);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Removes the specified from this NiFi cluster.
*
* @param id The id of the node
* @return A nodeEntity
*/
@DELETE
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("nodes/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@ApiOperation(
value = "Removes a node from the cluster",
response = NodeEntity.class,
authorizations = {
@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 = 404, message = "The specified resource could not be found."),
@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 deleteNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id) {
serviceFacade.deleteNode(id);
// create the response entity
final NodeEntity entity = new NodeEntity();
// generate the response
return generateOkResponse(entity).build();
}
// setters
public void setServiceFacade(NiFiServiceFacade serviceFacade) {
this.serviceFacade = serviceFacade;
}
}

Просмотреть файл

@ -28,7 +28,6 @@ import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.FlowFileSummaryDTO;
import org.apache.nifi.web.api.dto.ListingRequestDTO;
@ -50,7 +49,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.Set;
/**
@ -271,23 +269,16 @@ public class ConnectionResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable conn = lookup.getConnection(id);
conn.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getConnection(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateConnection(connection),
() -> {
// update the relationship target
final UpdateResult<ConnectionEntity> updateResult = serviceFacade.updateConnection(revision, connection);
final ConnectionEntity entity = updateResult.getResult();
final ConnectionEntity entity = serviceFacade.updateConnection(revision, connection);
populateRemainingConnectionEntityContent(entity);
// generate the response
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
});
}

Просмотреть файл

@ -16,25 +16,13 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.Collections;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
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;
@ -45,30 +33,45 @@ 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.protocol.NodeIdentifier;
import org.apache.nifi.cluster.coordination.node.NodeConnectionState;
import org.apache.nifi.controller.FlowController;
import org.apache.nifi.web.IllegalClusterResourceRequestException;
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.dto.ClusterDTO;
import org.apache.nifi.web.api.dto.NodeDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.search.NodeSearchResultDTO;
import org.apache.nifi.web.api.entity.ClusterEntity;
import org.apache.nifi.web.api.entity.ClusterSearchResultsEntity;
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.HistoryEntity;
import org.apache.nifi.web.api.entity.NodeEntity;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ReportingTaskEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.DateTimeParameter;
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 javax.servlet.http.HttpServletRequest;
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;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
/**
* RESTful endpoint for managing a Flow Controller.
@ -150,8 +153,14 @@ public class ControllerResource extends ApplicationResource {
}
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
authorizeController(RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}
@ -163,141 +172,6 @@ public class ControllerResource extends ApplicationResource {
return clusterContext(generateCreatedResponse(uri, entity)).build();
}
/**
* Retrieves the counters report for this NiFi.
*
* @return A countersEntity.
* @throws InterruptedException if interrupted
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("counters")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets the current counters for this NiFi",
response = Entity.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 getCounters(
@ApiParam(
value = "Whether or not to include the breakdown per node. Optional, defaults to false",
required = false
)
@QueryParam("nodewise") @DefaultValue(NODEWISE) final Boolean nodewise,
@ApiParam(
value = "The id of the node where to get the status.",
required = false
)
@QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException {
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
}
// replicate if necessary
if (isReplicateRequest()) {
// determine where this request should be sent
if (clusterNodeId == null) {
final NodeResponse nodeResponse = getRequestReplicator().replicate(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).awaitMergedResponse();
final CountersEntity entity = (CountersEntity) nodeResponse.getUpdatedEntity();
// ensure there is an updated entity (result of merging) and prune the response as necessary
if (entity != null && !nodewise) {
entity.getCounters().setNodeSnapshots(null);
}
return nodeResponse.getResponse();
} else {
// get the target node and ensure it exists
final NodeIdentifier targetNode = getClusterCoordinator().getNodeIdentifier(clusterNodeId);
if (targetNode == null) {
throw new UnknownNodeException("The specified cluster node does not exist.");
}
final Set<NodeIdentifier> targetNodes = Collections.singleton(targetNode);
// replicate the request to the specific node
return getRequestReplicator().replicate(targetNodes, HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).awaitMergedResponse().getResponse();
}
}
final CountersDTO countersReport = serviceFacade.getCounters();
// create the response entity
final CountersEntity entity = new CountersEntity();
entity.setCounters(countersReport);
// generate the response
return clusterContext(generateOkResponse(entity)).build();
}
/**
* Update the specified counter. This will reset the counter value to 0.
*
* @param httpServletRequest request
* @param id The id of the counter.
* @return A counterEntity.
*/
@PUT
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("counters/{id}")
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
@ApiOperation(
value = "Updates the specified counter. This will reset the counter value to 0",
response = CounterEntity.class,
authorizations = {
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
}
)
@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 = 404, message = "The specified resource could not be found."),
@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 updateCounter(
@Context final HttpServletRequest httpServletRequest,
@PathParam("id") final String id) {
if (isReplicateRequest()) {
return replicate(HttpMethod.PUT);
}
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
return generateContinueResponse().build();
}
// reset the specified counter
final CounterDTO counter = serviceFacade.updateCounter(id);
// create the response entity
final CounterEntity entity = new CounterEntity();
entity.setCounter(counter);
// generate the response
return clusterContext(generateOkResponse(entity)).build();
}
/**
* Retrieves the configuration for this NiFi.
*
@ -309,7 +183,7 @@ public class ControllerResource extends ApplicationResource {
@Path("config")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN', 'ROLE_NIFI')")
@ApiOperation(
value = "Retrieves the configuration for this NiFi",
value = "Retrieves the configuration for this NiFi Controller",
response = ControllerConfigurationEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@ -327,8 +201,8 @@ public class ControllerResource extends ApplicationResource {
}
)
public Response getControllerConfig() {
// TODO
// authorizeController(RequestAction.READ);
authorizeController(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -372,7 +246,7 @@ public class ControllerResource extends ApplicationResource {
required = true
) final ControllerConfigurationEntity configEntity) {
if (configEntity == null || configEntity.getConfig() == null) {
if (configEntity == null || configEntity.getControllerConfiguration() == null) {
throw new IllegalArgumentException("Controller configuration must be specified");
}
@ -393,7 +267,7 @@ public class ControllerResource extends ApplicationResource {
},
null,
() -> {
final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getConfig());
final ControllerConfigurationEntity entity = serviceFacade.updateControllerConfiguration(revision, configEntity.getControllerConfiguration());
return clusterContext(generateOkResponse(entity)).build();
}
);
@ -441,6 +315,10 @@ public class ControllerResource extends ApplicationResource {
throw new IllegalArgumentException("Reporting task details must be specified.");
}
if (reportingTaskEntity.getRevision() == null || (reportingTaskEntity.getRevision().getVersion() == null || reportingTaskEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Reporting task.");
}
if (reportingTaskEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Reporting task ID cannot be specified.");
}
@ -454,8 +332,14 @@ public class ControllerResource extends ApplicationResource {
}
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
authorizeController(RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}
@ -463,7 +347,8 @@ public class ControllerResource extends ApplicationResource {
reportingTaskEntity.getComponent().setId(generateUuid());
// create the reporting task and generate the json
final ReportingTaskEntity entity = serviceFacade.createReportingTask(reportingTaskEntity.getComponent());
final Revision revision = getRevision(reportingTaskEntity, reportingTaskEntity.getComponent().getId());
final ReportingTaskEntity entity = serviceFacade.createReportingTask(revision, reportingTaskEntity.getComponent());
reportingTaskResource.populateRemainingReportingTaskEntityContent(entity);
// build the response
@ -512,6 +397,10 @@ public class ControllerResource extends ApplicationResource {
throw new IllegalArgumentException("Controller service details must be specified.");
}
if (controllerServiceEntity.getRevision() == null || (controllerServiceEntity.getRevision().getVersion() == null || controllerServiceEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Controller service.");
}
if (controllerServiceEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Controller service ID cannot be specified.");
}
@ -529,7 +418,7 @@ public class ControllerResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
// TODO - authorize controller access
authorizeController(RequestAction.WRITE);
});
}
if (validationPhase) {
@ -540,13 +429,411 @@ public class ControllerResource extends ApplicationResource {
controllerServiceEntity.getComponent().setId(generateUuid());
// create the controller service and generate the json
final ControllerServiceEntity entity = serviceFacade.createControllerService(null, controllerServiceEntity.getComponent());
final Revision revision = getRevision(controllerServiceEntity, controllerServiceEntity.getComponent().getId());
final ControllerServiceEntity entity = serviceFacade.createControllerService(revision, null, controllerServiceEntity.getComponent());
controllerServiceResource.populateRemainingControllerServiceContent(entity.getComponent());
// build the response
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
}
// -------
// 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.
*
* @return A clusterEntity
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("cluster")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets the contents of the cluster",
notes = "Returns the contents of the cluster including all nodes and their status.",
response = ClusterEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "DFM", type = "ROLE_DFM"),
@Authorization(value = "Admin", 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 getCluster() {
authorizeController(RequestAction.READ);
// ensure connected to the cluster
if (!isConnectedToCluster()) {
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
final ClusterDTO dto = serviceFacade.getCluster();
// create entity
final ClusterEntity entity = new ClusterEntity();
entity.setCluster(dto);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Searches the cluster for a node with a given address.
*
* @param value Search value that will be matched against a node's address
* @return Nodes that match the specified criteria
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("cluster/search-results")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Searches the cluster for a node with the specified address",
response = ClusterSearchResultsEntity.class,
authorizations = {
@Authorization(value = "Read Only", type = "ROLE_MONITOR"),
@Authorization(value = "DFM", type = "ROLE_DFM"),
@Authorization(value = "Admin", 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 = 404, message = "The specified resource could not be found."),
@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 searchCluster(
@ApiParam(
value = "Node address to search for.",
required = true
)
@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) {
authorizeController(RequestAction.READ);
// ensure connected to the cluster
if (!isConnectedToCluster()) {
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
final List<NodeSearchResultDTO> nodeMatches = new ArrayList<>();
// get the nodes in the cluster
final ClusterDTO cluster = serviceFacade.getCluster();
// check each to see if it matches the search term
for (NodeDTO node : cluster.getNodes()) {
// ensure the node is connected
if (!NodeConnectionState.CONNECTED.name().equals(node.getStatus())) {
continue;
}
// determine the current nodes address
final String address = node.getAddress() + ":" + node.getApiPort();
// count the node if there is no search or it matches the address
if (StringUtils.isBlank(value) || StringUtils.containsIgnoreCase(address, value)) {
final NodeSearchResultDTO nodeMatch = new NodeSearchResultDTO();
nodeMatch.setId(node.getNodeId());
nodeMatch.setAddress(address);
nodeMatches.add(nodeMatch);
}
}
// build the response
ClusterSearchResultsEntity results = new ClusterSearchResultsEntity();
results.setNodeResults(nodeMatches);
// generate an 200 - OK response
return noCache(Response.ok(results)).build();
}
/**
* Gets the contents of the specified node in this NiFi cluster.
*
* @param id The node id.
* @return A nodeEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("cluster/nodes/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets a node in the cluster",
response = NodeEntity.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 = 404, message = "The specified resource could not be found."),
@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 getNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id) {
authorizeController(RequestAction.READ);
// ensure connected to the cluster
if (!isConnectedToCluster()) {
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
// get the specified relationship
final NodeDTO dto = serviceFacade.getNode(id);
// create the response entity
final NodeEntity entity = new NodeEntity();
entity.setNode(dto);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Updates the contents of the specified node in this NiFi cluster.
*
* @param id The id of the node
* @param nodeEntity A nodeEntity
* @return A nodeEntity
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("cluster/nodes/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@ApiOperation(
value = "Updates a node in the cluster",
response = NodeEntity.class,
authorizations = {
@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 = 404, message = "The specified resource could not be found."),
@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 updateNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id,
@ApiParam(
value = "The node configuration. The only configuration that will be honored at this endpoint is the status or primary flag.",
required = true
) NodeEntity nodeEntity) {
authorizeController(RequestAction.WRITE);
// ensure connected to the cluster
if (!isConnectedToCluster()) {
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
if (nodeEntity == null || nodeEntity.getNode() == null) {
throw new IllegalArgumentException("Node details must be specified.");
}
// get the request node
final NodeDTO requestNodeDTO = nodeEntity.getNode();
if (!id.equals(requestNodeDTO.getNodeId())) {
throw new IllegalArgumentException(String.format("The node id (%s) in the request body does "
+ "not equal the node id of the requested resource (%s).", requestNodeDTO.getNodeId(), id));
}
// update the node
final NodeDTO node = serviceFacade.updateNode(requestNodeDTO);
// create the response entity
NodeEntity entity = new NodeEntity();
entity.setNode(node);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Removes the specified from this NiFi cluster.
*
* @param id The id of the node
* @return A nodeEntity
*/
@DELETE
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("cluster/nodes/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@ApiOperation(
value = "Removes a node from the cluster",
response = NodeEntity.class,
authorizations = {
@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 = 404, message = "The specified resource could not be found."),
@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 deleteNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id) {
authorizeController(RequestAction.WRITE);
// ensure connected to the cluster
if (!isConnectedToCluster()) {
throw new IllegalClusterResourceRequestException("Only a node connected to a cluster can process the request.");
}
serviceFacade.deleteNode(id);
// create the response entity
final NodeEntity entity = new NodeEntity();
// generate the response
return generateOkResponse(entity).build();
}
// -------
// history
// -------
/**
* Deletes flow history from the specified end date.
*
* @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.
* @param endDate The end date for the purge action.
* @return A historyEntity
*/
@DELETE
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("history")
// TODO - @PreAuthorize("hasRole('ROLE_ADMIN')")
@ApiOperation(
value = "Purges history",
response = HistoryEntity.class,
authorizations = {
@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 deleteHistory(
@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,
@ApiParam(
value = "Purge actions before this date/time.",
required = true
)
@QueryParam("endDate") DateTimeParameter endDate) {
// ensure the end date is specified
if (endDate == null) {
throw new IllegalArgumentException("The end date must be specified.");
}
if (isReplicateRequest()) {
return replicate(HttpMethod.DELETE);
}
// handle expects request (usually from the cluster manager)
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
authorizeController(RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}
// purge the actions
serviceFacade.deleteActions(endDate.getDateTime());
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final HistoryEntity entity = new HistoryEntity();
// generate the response
return generateOkResponse(entity).build();
}
// setters
public void setServiceFacade(final NiFiServiceFacade serviceFacade) {
this.serviceFacade = serviceFacade;

Просмотреть файл

@ -33,7 +33,6 @@ import org.apache.nifi.ui.extension.UiExtensionMapping;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UiExtensionType;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ComponentStateDTO;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
@ -64,7 +63,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -371,12 +369,10 @@ public class ControllerServiceResource extends ApplicationResource {
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable controllerService = lookup.getControllerService(id);
controllerService.authorize(authorizer, RequestAction.WRITE);
final Authorizable processor = lookup.getControllerService(id);
processor.authorize(authorizer, RequestAction.WRITE);
});
}
// handle expects request (usually from the cluster manager)
if (validationPhase) {
serviceFacade.verifyCanClearControllerServiceState(id);
return generateContinueResponse().build();
@ -624,23 +620,16 @@ public class ControllerServiceResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable controllerService = lookup.getControllerService(id);
controllerService.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getControllerService(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateControllerService(requestControllerServiceDTO),
() -> {
// update the controller service
final UpdateResult<ControllerServiceEntity> updateResult = serviceFacade.updateControllerService(revision, requestControllerServiceDTO);
// build the response entity
final ControllerServiceEntity entity = updateResult.getResult();
final ControllerServiceEntity entity = serviceFacade.updateControllerService(revision, requestControllerServiceDTO);
populateRemainingControllerServiceContent(entity.getComponent());
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -0,0 +1,252 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web.api;
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.manager.NodeResponse;
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.api.dto.CounterDTO;
import org.apache.nifi.web.api.dto.CountersDTO;
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 javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Collections;
import java.util.Set;
/**
* RESTful endpoint for managing a cluster.
*/
@Path("/counters")
@Api(
value = "/counters",
description = "Endpoint for managing counters."
)
public class CountersResource extends ApplicationResource {
@Context
private ResourceContext resourceContext;
private NiFiServiceFacade serviceFacade;
private Authorizer authorizer;
/**
* Authorizes access to the flow.
*/
private void authorizeCounters(final RequestAction action) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.resource(ResourceFactory.getCountersResource())
.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);
}
}
/**
* Retrieves the counters report for this NiFi.
*
* @return A countersEntity.
* @throws InterruptedException if interrupted
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("") // necessary due to a bug in swagger
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets the current counters for this NiFi",
response = Entity.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 getCounters(
@ApiParam(
value = "Whether or not to include the breakdown per node. Optional, defaults to false",
required = false
)
@QueryParam("nodewise") @DefaultValue(NODEWISE) final Boolean nodewise,
@ApiParam(
value = "The id of the node where to get the status.",
required = false
)
@QueryParam("clusterNodeId") final String clusterNodeId) throws InterruptedException {
authorizeCounters(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
throw new IllegalArgumentException("Nodewise requests cannot be directed at a specific node.");
}
// replicate if necessary
if (isReplicateRequest()) {
// determine where this request should be sent
if (clusterNodeId == null) {
final NodeResponse nodeResponse = getRequestReplicator().replicate(HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).awaitMergedResponse();
final CountersEntity entity = (CountersEntity) nodeResponse.getUpdatedEntity();
// ensure there is an updated entity (result of merging) and prune the response as necessary
if (entity != null && !nodewise) {
entity.getCounters().setNodeSnapshots(null);
}
return nodeResponse.getResponse();
} else {
// get the target node and ensure it exists
final NodeIdentifier targetNode = getClusterCoordinator().getNodeIdentifier(clusterNodeId);
if (targetNode == null) {
throw new UnknownNodeException("The specified cluster node does not exist.");
}
final Set<NodeIdentifier> targetNodes = Collections.singleton(targetNode);
// replicate the request to the specific node
return getRequestReplicator().replicate(targetNodes, HttpMethod.GET, getAbsolutePath(), getRequestParameters(true), getHeaders()).awaitMergedResponse().getResponse();
}
}
final CountersDTO countersReport = serviceFacade.getCounters();
// create the response entity
final CountersEntity entity = new CountersEntity();
entity.setCounters(countersReport);
// generate the response
return clusterContext(generateOkResponse(entity)).build();
}
/**
* Update the specified counter. This will reset the counter value to 0.
*
* @param httpServletRequest request
* @param id The id of the counter.
* @return A counterEntity.
*/
@PUT
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("{id}")
// TODO - @PreAuthorize("hasRole('ROLE_DFM')")
@ApiOperation(
value = "Updates the specified counter. This will reset the counter value to 0",
response = CounterEntity.class,
authorizations = {
@Authorization(value = "Data Flow Manager", type = "ROLE_DFM")
}
)
@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 = 404, message = "The specified resource could not be found."),
@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 updateCounter(
@Context final HttpServletRequest httpServletRequest,
@PathParam("id") final String id) {
if (isReplicateRequest()) {
return replicate(HttpMethod.PUT);
}
// handle expects request (usually from the cluster manager)
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
authorizeCounters(RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}
// reset the specified counter
final CounterDTO counter = serviceFacade.updateCounter(id);
// create the response entity
final CounterEntity entity = new CounterEntity();
entity.setCounter(counter);
// generate the response
return clusterContext(generateOkResponse(entity)).build();
}
// setters
public void setServiceFacade(NiFiServiceFacade serviceFacade) {
this.serviceFacade = serviceFacade;
}
public void setAuthorizer(Authorizer authorizer) {
this.authorizer = authorizer;
}
}

Просмотреть файл

@ -26,7 +26,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
import org.apache.nifi.cluster.manager.exception.UnknownNodeException;
import org.apache.nifi.cluster.protocol.NodeIdentifier;
import org.apache.nifi.stream.io.StreamUtils;
@ -339,15 +338,16 @@ public class FlowFileQueueResource extends ApplicationResource {
return replicate(HttpMethod.POST);
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(id);
connection.authorize(authorizer, RequestAction.WRITE);
});
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(id);
connection.authorize(authorizer, RequestAction.WRITE);
});
}
if (validationPhase) {
serviceFacade.verifyListQueue(id);
return generateContinueResponse().build();
}
@ -476,17 +476,18 @@ public class FlowFileQueueResource extends ApplicationResource {
}
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
});
// delete the listing request
final ListingRequestDTO listingRequest = serviceFacade.deleteFlowFileListingRequest(connectionId, listingRequestId);
@ -544,15 +545,16 @@ public class FlowFileQueueResource extends ApplicationResource {
return replicate(HttpMethod.POST);
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(id);
connection.authorize(authorizer, RequestAction.WRITE);
});
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(id);
connection.authorize(authorizer, RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}
@ -679,15 +681,16 @@ public class FlowFileQueueResource extends ApplicationResource {
return replicate(HttpMethod.DELETE);
}
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
});
// handle expects request (usually from the cluster manager)
final String expects = httpServletRequest.getHeader(RequestReplicator.REQUEST_VALIDATION_HTTP_HEADER);
if (expects != null) {
final boolean validationPhase = isValidationPhase(httpServletRequest);
if (validationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable connection = lookup.getConnection(connectionId);
connection.authorize(authorizer, RequestAction.WRITE);
});
}
if (validationPhase) {
return generateContinueResponse().build();
}

Просмотреть файл

@ -46,6 +46,9 @@ import org.apache.nifi.web.api.dto.BulletinBoardDTO;
import org.apache.nifi.web.api.dto.BulletinQueryDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.action.ActionDTO;
import org.apache.nifi.web.api.dto.action.HistoryDTO;
import org.apache.nifi.web.api.dto.action.HistoryQueryDTO;
import org.apache.nifi.web.api.dto.flow.FlowDTO;
import org.apache.nifi.web.api.dto.flow.ProcessGroupFlowDTO;
import org.apache.nifi.web.api.dto.search.SearchResultsDTO;
@ -59,15 +62,19 @@ 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.AboutEntity;
import org.apache.nifi.web.api.entity.ActionEntity;
import org.apache.nifi.web.api.entity.AuthorityEntity;
import org.apache.nifi.web.api.entity.BannerEntity;
import org.apache.nifi.web.api.entity.BulletinBoardEntity;
import org.apache.nifi.web.api.entity.ComponentHistoryEntity;
import org.apache.nifi.web.api.entity.ConnectionStatusEntity;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
import org.apache.nifi.web.api.entity.ControllerServiceTypesEntity;
import org.apache.nifi.web.api.entity.ControllerServicesEntity;
import org.apache.nifi.web.api.entity.ControllerStatusEntity;
import org.apache.nifi.web.api.entity.Entity;
import org.apache.nifi.web.api.entity.FlowConfigurationEntity;
import org.apache.nifi.web.api.entity.HistoryEntity;
import org.apache.nifi.web.api.entity.IdentityEntity;
import org.apache.nifi.web.api.entity.PortStatusEntity;
import org.apache.nifi.web.api.entity.PrioritizerTypesEntity;
@ -85,6 +92,7 @@ import org.apache.nifi.web.api.entity.SearchResultsEntity;
import org.apache.nifi.web.api.entity.StatusHistoryEntity;
import org.apache.nifi.web.api.request.BulletinBoardPatternParameter;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.DateTimeParameter;
import org.apache.nifi.web.api.request.IntegerParameter;
import org.apache.nifi.web.api.request.LongParameter;
@ -187,7 +195,7 @@ public class FlowResource extends ApplicationResource {
/**
* Authorizes access to the flow.
*/
private void authorizeFlow() {
private void authorizeFlow(final RequestAction action) {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
final AuthorizationRequest request = new AuthorizationRequest.Builder()
@ -195,7 +203,7 @@ public class FlowResource extends ApplicationResource {
.identity(user.getIdentity())
.anonymous(user.isAnonymous())
.accessAttempt(true)
.action(RequestAction.READ)
.action(action)
.build();
final AuthorizationResult result = authorizer.authorize(request);
@ -233,10 +241,50 @@ public class FlowResource extends ApplicationResource {
}
)
public Response generateClientId() {
authorizeFlow();
authorizeFlow(RequestAction.READ);
return clusterContext(generateOkResponse(generateUuid())).build();
}
/**
* Retrieves the configuration for the flow.
*
* @return A flowConfigurationEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("config")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN', 'ROLE_NIFI')")
@ApiOperation(
value = "Retrieves the configuration for this NiFi flow",
response = FlowConfigurationEntity.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 = "ROLE_NIFI", type = "ROLE_NIFI")
}
)
@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 getFlowConfig() {
authorizeFlow(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
final FlowConfigurationEntity entity = serviceFacade.getFlowConfiguration();
return clusterContext(generateOkResponse(entity)).build();
}
/**
* Retrieves the identity of the user making the request.
*
@ -252,7 +300,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getIdentity() {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// note that the cluster manager will handle this request directly
final NiFiUser user = NiFiUserUtils.getNiFiUser();
@ -301,9 +349,8 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getAuthorities() {
// TODO - Remove
authorizeFlow();
// TODO - remove this method once authorities are completely removed
authorizeFlow(RequestAction.READ);
// note that the cluster manager will handle this request directly
final NiFiUser user = NiFiUserUtils.getNiFiUser();
@ -368,7 +415,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam("recursive") @DefaultValue(RECURSIVE) Boolean recursive) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -413,6 +460,8 @@ public class FlowResource extends ApplicationResource {
)
public Response getControllerServicesFromController() {
authorizeFlow(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
@ -464,6 +513,8 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String groupId) throws InterruptedException {
authorizeFlow(RequestAction.READ);
// get all the controller services
final Set<ControllerServiceEntity> controllerServices = serviceFacade.getControllerServices(groupId);
controllerServiceResource.populateRemainingControllerServiceEntitiesContent(controllerServices);
@ -517,6 +568,8 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam(CLIENT_ID) @DefaultValue(StringUtils.EMPTY) ClientIdParameter clientId) {
authorizeFlow(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
@ -571,6 +624,8 @@ public class FlowResource extends ApplicationResource {
@PathParam("id") String id,
ScheduleComponentsEntity scheduleComponentsEntity) {
authorizeFlow(RequestAction.READ);
// 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 "
@ -595,7 +650,6 @@ public class FlowResource extends ApplicationResource {
// if the components are not specified, gather all components and their current revision
if (scheduleComponentsEntity.getComponents() == null) {
// TODO - this will break while clustered until nodes are able to process/replicate requests
// get the current revisions for the components being updated
final Set<Revision> revisions = serviceFacade.getRevisionsFromGroup(id, group -> {
final Set<String> componentIds = new HashSet<>();
@ -652,9 +706,6 @@ 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);
@ -704,7 +755,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response searchFlow(@QueryParam("q") @DefaultValue(StringUtils.EMPTY) String value) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// query the controller
final SearchResultsDTO results = serviceFacade.searchController(value);
@ -747,7 +798,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getControllerStatus() throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
@ -792,7 +843,7 @@ public class FlowResource extends ApplicationResource {
)
public Response getBanners() {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// get the banner from the properties - will come from the NCM when clustered
final String bannerText = getProperties().getBannerText();
@ -839,7 +890,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getProcessorTypes() throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// create response entity
final ProcessorTypesEntity entity = new ProcessorTypesEntity();
@ -884,7 +935,7 @@ public class FlowResource extends ApplicationResource {
required = false
)
@QueryParam("serviceType") String serviceType) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// create response entity
final ControllerServiceTypesEntity entity = new ControllerServiceTypesEntity();
@ -923,7 +974,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getReportingTaskTypes() throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// create response entity
final ReportingTaskTypesEntity entity = new ReportingTaskTypesEntity();
@ -962,7 +1013,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getPrioritizers() throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// create response entity
final PrioritizerTypesEntity entity = new PrioritizerTypesEntity();
@ -1000,7 +1051,7 @@ public class FlowResource extends ApplicationResource {
}
)
public Response getAboutInfo() {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// create the about dto
final AboutDTO aboutDTO = new AboutDTO();
@ -1090,7 +1141,7 @@ public class FlowResource extends ApplicationResource {
)
@QueryParam("limit") IntegerParameter limit) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1181,7 +1232,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1263,7 +1314,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1345,7 +1396,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1427,7 +1478,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1518,7 +1569,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String groupId) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1621,7 +1672,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// ensure a valid request
if (Boolean.TRUE.equals(nodewise) && clusterNodeId != null) {
@ -1697,7 +1748,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1752,7 +1803,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String groupId) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1807,7 +1858,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1862,7 +1913,7 @@ public class FlowResource extends ApplicationResource {
)
@PathParam("id") String id) throws InterruptedException {
authorizeFlow();
authorizeFlow(RequestAction.READ);
// replicate if cluster manager
if (isReplicateRequest()) {
@ -1880,6 +1931,279 @@ public class FlowResource extends ApplicationResource {
return clusterContext(generateOkResponse(entity)).build();
}
// -------
// history
// -------
/**
* Queries the history of this Controller.
*
* @param offset The offset into the data. This parameter is required and is
* used in conjunction with count.
* @param count The number of rows that should be returned. This parameter
* is required and is used in conjunction with page.
* @param sortColumn The column to sort on. This parameter is optional. If
* not specified the results will be returned with the most recent first.
* @param sortOrder The sort order.
* @param startDate The start date/time for the query. The start date/time
* must be formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional
* and must be specified in the timezone of the server. The server's
* timezone can be determined by inspecting the result of a status or
* history request.
* @param endDate The end date/time for the query. The end date/time must be
* formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional and must
* be specified in the timezone of the server. The server's timezone can be
* determined by inspecting the result of a status or history request.
* @param userName The user name of the user who's actions are being
* queried. This parameter is optional.
* @param sourceId The id of the source being queried (usually a processor
* id). This parameter is optional.
* @return A historyEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("history")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets configuration history",
response = HistoryEntity.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 queryHistory(
@ApiParam(
value = "The offset into the result set.",
required = true
)
@QueryParam("offset") IntegerParameter offset,
@ApiParam(
value = "The number of actions to return.",
required = true
)
@QueryParam("count") IntegerParameter count,
@ApiParam(
value = "The field to sort on.",
required = false
)
@QueryParam("sortColumn") String sortColumn,
@ApiParam(
value = "The direction to sort.",
required = false
)
@QueryParam("sortOrder") String sortOrder,
@ApiParam(
value = "Include actions after this date.",
required = false
)
@QueryParam("startDate") DateTimeParameter startDate,
@ApiParam(
value = "Include actions before this date.",
required = false
)
@QueryParam("endDate") DateTimeParameter endDate,
@ApiParam(
value = "Include actions performed by this user.",
required = false
)
@QueryParam("userName") String userName,
@ApiParam(
value = "Include actions on this component.",
required = false
)
@QueryParam("sourceId") String sourceId) {
authorizeFlow(RequestAction.READ);
// ensure the page is specified
if (offset == null) {
throw new IllegalArgumentException("The desired offset must be specified.");
} else if (offset.getInteger() < 0) {
throw new IllegalArgumentException("The desired offset must be an integer value greater than or equal to 0.");
}
// ensure the row count is specified
if (count == null) {
throw new IllegalArgumentException("The desired row count must be specified.");
} else if (count.getInteger() < 1) {
throw new IllegalArgumentException("The desired row count must be an integer value greater than 0.");
}
// normalize the sort order
if (sortOrder != null) {
if (!sortOrder.equalsIgnoreCase("asc") && !sortOrder.equalsIgnoreCase("desc")) {
throw new IllegalArgumentException("The sort order must be 'asc' or 'desc'.");
}
}
// ensure the start and end dates are specified
if (endDate != null && startDate != null) {
if (endDate.getDateTime().before(startDate.getDateTime())) {
throw new IllegalArgumentException("The start date/time must come before the end date/time.");
}
}
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// create a history query
final HistoryQueryDTO query = new HistoryQueryDTO();
query.setSortColumn(sortColumn);
query.setSortOrder(sortOrder);
query.setOffset(offset.getInteger());
query.setCount(count.getInteger());
// optionally set the start date
if (startDate != null) {
query.setStartDate(startDate.getDateTime());
}
// optionally set the end date
if (endDate != null) {
query.setEndDate(endDate.getDateTime());
}
// optionally set the user id
if (userName != null) {
query.setUserName(userName);
}
// optionally set the processor id
if (sourceId != null) {
query.setSourceId(sourceId);
}
// perform the query
final HistoryDTO history = serviceFacade.getActions(query);
// create the response entity
final HistoryEntity entity = new HistoryEntity();
entity.setHistory(history);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Gets the action for the corresponding id.
*
* @param id The id of the action to get.
* @return An actionEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@Path("history/{id}")
@ApiOperation(
value = "Gets an action",
response = ActionEntity.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 = 404, message = "The specified resource could not be found."),
@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 getAction(
@ApiParam(
value = "The action id.",
required = true
)
@PathParam("id") IntegerParameter id) {
authorizeFlow(RequestAction.READ);
// ensure the id was specified
if (id == null) {
throw new IllegalArgumentException("The action id must be specified.");
}
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// get the specified action
final ActionDTO action = serviceFacade.getAction(id.getInteger());
// create the response entity
final ActionEntity entity = new ActionEntity();
entity.setAction(action);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Gets the actions for the specified component.
*
* @param componentId The id of the component.
* @return An processorHistoryEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("history/components/{componentId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets configuration history for a processor",
response = ComponentHistoryEntity.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 = 404, message = "The specified resource could not be found."),
@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 getComponentHistory(
@ApiParam(
value = "The component id.",
required = true
)
@PathParam("componentId") final String componentId) {
authorizeFlow(RequestAction.READ);
if (isReplicateRequest()) {
return replicate(HttpMethod.GET);
}
// create the response entity
final ComponentHistoryEntity entity = new ComponentHistoryEntity();
entity.setComponentHistory(serviceFacade.getComponentHistory(componentId));
// generate the response
return generateOkResponse(entity).build();
}
// setters
public void setServiceFacade(NiFiServiceFacade serviceFacade) {
this.serviceFacade = serviceFacade;

Просмотреть файл

@ -28,7 +28,6 @@ import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.FunnelDTO;
import org.apache.nifi.web.api.entity.FunnelEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
@ -48,7 +47,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.Set;
/**
@ -231,23 +229,16 @@ public class FunnelResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable funnel = lookup.getFunnel(id);
funnel.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getFunnel(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
null,
() -> {
// update the funnel
final UpdateResult<FunnelEntity> updateResult = serviceFacade.updateFunnel(revision, requestFunnelDTO);
// get the results
final FunnelEntity entity = updateResult.getResult();
final FunnelEntity entity = serviceFacade.updateFunnel(revision, requestFunnelDTO);
populateRemainingFunnelEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -1,525 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web.api;
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.web.NiFiServiceFacade;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.action.ActionDTO;
import org.apache.nifi.web.api.dto.action.HistoryDTO;
import org.apache.nifi.web.api.dto.action.HistoryQueryDTO;
import org.apache.nifi.web.api.entity.ActionEntity;
import org.apache.nifi.web.api.entity.ComponentHistoryEntity;
import org.apache.nifi.web.api.entity.HistoryEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.DateTimeParameter;
import org.apache.nifi.web.api.request.IntegerParameter;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
/**
* RESTful endpoint for querying the history of this Controller.
*/
@Path("/history")
@Api(
value = "/history",
description = "Endpoint for accessing flow history."
)
public class HistoryResource extends ApplicationResource {
private NiFiServiceFacade serviceFacade;
/**
* Queries the history of this Controller.
*
* @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.
* @param offset The offset into the data. This parameter is required and is
* used in conjunction with count.
* @param count The number of rows that should be returned. This parameter
* is required and is used in conjunction with page.
* @param sortColumn The column to sort on. This parameter is optional. If
* not specified the results will be returned with the most recent first.
* @param sortOrder The sort order.
* @param startDate The start date/time for the query. The start date/time
* must be formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional
* and must be specified in the timezone of the server. The server's
* timezone can be determined by inspecting the result of a status or
* history request.
* @param endDate The end date/time for the query. The end date/time must be
* formatted as 'MM/dd/yyyy HH:mm:ss'. This parameter is optional and must
* be specified in the timezone of the server. The server's timezone can be
* determined by inspecting the result of a status or history request.
* @param userName The user name of the user who's actions are being
* queried. This parameter is optional.
* @param sourceId The id of the source being queried (usually a processor
* id). This parameter is optional.
* @return A historyEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("") // necessary due to bug in swagger
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets configuration history",
response = HistoryEntity.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 queryHistory(
@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,
@ApiParam(
value = "The offset into the result set.",
required = true
)
@QueryParam("offset") IntegerParameter offset,
@ApiParam(
value = "The number of actions to return.",
required = true
)
@QueryParam("count") IntegerParameter count,
@ApiParam(
value = "The field to sort on.",
required = false
)
@QueryParam("sortColumn") String sortColumn,
@ApiParam(
value = "The direction to sort.",
required = false
)
@QueryParam("sortOrder") String sortOrder,
@ApiParam(
value = "Include actions after this date.",
required = false
)
@QueryParam("startDate") DateTimeParameter startDate,
@ApiParam(
value = "Include actions before this date.",
required = false
)
@QueryParam("endDate") DateTimeParameter endDate,
@ApiParam(
value = "Include actions performed by this user.",
required = false
)
@QueryParam("userName") String userName,
@ApiParam(
value = "Include actions on this component.",
required = false
)
@QueryParam("sourceId") String sourceId) {
// ensure the page is specified
if (offset == null) {
throw new IllegalArgumentException("The desired offset must be specified.");
} else if (offset.getInteger() < 0) {
throw new IllegalArgumentException("The desired offset must be an integer value greater than or equal to 0.");
}
// ensure the row count is specified
if (count == null) {
throw new IllegalArgumentException("The desired row count must be specified.");
} else if (count.getInteger() < 1) {
throw new IllegalArgumentException("The desired row count must be an integer value greater than 0.");
}
// normalize the sort order
if (sortOrder != null) {
if (!sortOrder.equalsIgnoreCase("asc") && !sortOrder.equalsIgnoreCase("desc")) {
throw new IllegalArgumentException("The sort order must be 'asc' or 'desc'.");
}
}
// ensure the start and end dates are specified
if (endDate != null && startDate != null) {
if (endDate.getDateTime().before(startDate.getDateTime())) {
throw new IllegalArgumentException("The start date/time must come before the end date/time.");
}
}
// create a history query
final HistoryQueryDTO query = new HistoryQueryDTO();
query.setSortColumn(sortColumn);
query.setSortOrder(sortOrder);
query.setOffset(offset.getInteger());
query.setCount(count.getInteger());
// optionally set the start date
if (startDate != null) {
query.setStartDate(startDate.getDateTime());
}
// optionally set the end date
if (endDate != null) {
query.setEndDate(endDate.getDateTime());
}
// optionally set the user id
if (userName != null) {
query.setUserName(userName);
}
// optionally set the processor id
if (sourceId != null) {
query.setSourceId(sourceId);
}
// perform the query
final HistoryDTO history = serviceFacade.getActions(query);
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final HistoryEntity entity = new HistoryEntity();
entity.setHistory(history);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Gets the action for the corresponding id.
*
* @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.
* @param id The id of the action to get.
* @return An actionEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@Path("{id}")
@ApiOperation(
value = "Gets an action",
response = ActionEntity.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 = 404, message = "The specified resource could not be found."),
@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 getAction(
@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,
@ApiParam(
value = "The action id.",
required = true
)
@PathParam("id") IntegerParameter id) {
// ensure the id was specified
if (id == null) {
throw new IllegalArgumentException("The action id must be specified.");
}
// get the specified action
final ActionDTO action = serviceFacade.getAction(id.getInteger());
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final ActionEntity entity = new ActionEntity();
entity.setAction(action);
// generate the response
return generateOkResponse(entity).build();
}
/**
* Deletes flow history from the specified end date.
*
* @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.
* @param endDate The end date for the purge action.
* @return A historyEntity
*/
@DELETE
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("") // necessary due to bug in swagger
// TODO - @PreAuthorize("hasRole('ROLE_ADMIN')")
@ApiOperation(
value = "Purges history",
response = HistoryEntity.class,
authorizations = {
@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 deleteHistory(
@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,
@ApiParam(
value = "Purge actions before this date/time.",
required = true
)
@QueryParam("endDate") DateTimeParameter endDate) {
// ensure the end date is specified
if (endDate == null) {
throw new IllegalArgumentException("The end date must be specified.");
}
// purge the actions
serviceFacade.deleteActions(endDate.getDateTime());
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final HistoryEntity entity = new HistoryEntity();
// generate the response
return generateOkResponse(entity).build();
}
/**
* Gets the actions for the specified processor.
*
* @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.
* @param processorId The id of the processor.
* @return An processorHistoryEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("processors/{processorId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets configuration history for a processor",
response = ComponentHistoryEntity.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 = 404, message = "The specified resource could not be found."),
@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 getProcessorHistory(
@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,
@ApiParam(
value = "The processor id.",
required = true
)
@PathParam("processorId") final String processorId) {
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final ComponentHistoryEntity entity = new ComponentHistoryEntity();
entity.setComponentHistory(serviceFacade.getComponentHistory(processorId));
// generate the response
return generateOkResponse(entity).build();
}
/**
* Gets the actions for the specified 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.
* @param controllerServiceId The id of the controller service.
* @return An componentHistoryEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("controller-services/{controllerServiceId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets configuration history for a controller service",
response = ComponentHistoryEntity.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 = 404, message = "The specified resource could not be found."),
@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 getControllerServiceHistory(
@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,
@ApiParam(
value = "The controller service id.",
required = true
)
@PathParam("controllerServiceId") final String controllerServiceId) {
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final ComponentHistoryEntity entity = new ComponentHistoryEntity();
entity.setComponentHistory(serviceFacade.getComponentHistory(controllerServiceId));
// generate the response
return generateOkResponse(entity).build();
}
/**
* Gets the actions for the specified reporting task.
*
* @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.
* @param reportingTaskId The id of the reporting task.
* @return An componentHistoryEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("reporting-tasks/{reportingTaskId}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets configuration history for a reporting task",
response = ComponentHistoryEntity.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 = 404, message = "The specified resource could not be found."),
@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 getReportingTaskHistory(
@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,
@ApiParam(
value = "The reporting task id.",
required = true
)
@PathParam("reportingTaskId") final String reportingTaskId) {
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId.getClientId());
// create the response entity
final ComponentHistoryEntity entity = new ComponentHistoryEntity();
entity.setComponentHistory(serviceFacade.getComponentHistory(reportingTaskId));
// generate the response
return generateOkResponse(entity).build();
}
/* setters */
public void setServiceFacade(NiFiServiceFacade serviceFacade) {
this.serviceFacade = serviceFacade;
}
}

Просмотреть файл

@ -16,8 +16,22 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.Set;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@ -33,25 +47,7 @@ import javax.ws.rs.QueryParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
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.util.Set;
/**
* RESTful endpoint for managing an Input Port.
@ -233,23 +229,16 @@ public class InputPortResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable inputPort = lookup.getInputPort(id);
inputPort.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getInputPort(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateInputPort(requestPortDTO),
() -> {
// update the input port
final UpdateResult<PortEntity> updateResult = serviceFacade.updateInputPort(revision, requestPortDTO);
// build the response entity
final PortEntity entity = updateResult.getResult();
final PortEntity entity = serviceFacade.updateInputPort(revision, requestPortDTO);
populateRemainingInputPortEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -16,8 +16,22 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.Set;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.LabelDTO;
import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@ -33,25 +47,7 @@ import javax.ws.rs.QueryParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.LabelDTO;
import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
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.util.Set;
/**
* RESTful endpoint for managing a Label.
@ -233,21 +229,16 @@ public class LabelResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable label = lookup.getLabel(id);
label.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getLabel(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
null,
() -> {
// update the label
final UpdateResult<LabelEntity> result = serviceFacade.updateLabel(revision, requestLabelDTO);
final LabelEntity entity = result.getResult();
final LabelEntity entity = serviceFacade.updateLabel(revision, requestLabelDTO);
populateRemainingLabelEntityContent(entity);
if (result.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -1,219 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.web.api;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.apache.nifi.web.IllegalClusterResourceRequestException;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.api.dto.NodeDTO;
import org.apache.nifi.web.api.entity.NodeEntity;
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;
/**
* RESTful endpoint for managing a cluster connection.
*/
@Api(hidden = true)
public class NodeResource extends ApplicationResource {
private NiFiServiceFacade serviceFacade;
/**
* Gets the contents of the specified node in this NiFi cluster.
*
* @param id The node id.
* @return A nodeEntity.
*/
@GET
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_MONITOR', 'ROLE_DFM', 'ROLE_ADMIN')")
@ApiOperation(
value = "Gets a node in the cluster",
response = NodeEntity.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 = 404, message = "The specified resource could not be found."),
@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 getNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id) {
if (isConnectedToCluster()) {
// get the specified relationship
final NodeDTO dto = serviceFacade.getNode(id);
// create the response entity
final NodeEntity entity = new NodeEntity();
entity.setNode(dto);
// generate the response
return generateOkResponse(entity).build();
}
throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
}
/**
* Updates the contents of the specified node in this NiFi cluster.
*
* @param id The id of the node
* @param nodeEntity A nodeEntity
* @return A nodeEntity
*/
@PUT
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@ApiOperation(
value = "Updates a node in the cluster",
response = NodeEntity.class,
authorizations = {
@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 = 404, message = "The specified resource could not be found."),
@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 updateNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id,
@ApiParam(
value = "The node configuration. The only configuration that will be honored at this endpoint is the status or primary flag.",
required = true
)
NodeEntity nodeEntity) {
if (isConnectedToCluster()) {
if (nodeEntity == null || nodeEntity.getNode() == null) {
throw new IllegalArgumentException("Node details must be specified.");
}
// get the request node
final NodeDTO requestNodeDTO = nodeEntity.getNode();
if (!id.equals(requestNodeDTO.getNodeId())) {
throw new IllegalArgumentException(String.format("The node id (%s) in the request body does "
+ "not equal the node id of the requested resource (%s).", requestNodeDTO.getNodeId(), id));
}
// update the node
final NodeDTO node = serviceFacade.updateNode(requestNodeDTO);
// create the response entity
NodeEntity entity = new NodeEntity();
entity.setNode(node);
// generate the response
return generateOkResponse(entity).build();
}
throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
}
/**
* Removes the specified from this NiFi cluster.
*
* @param id The id of the node
* @return A nodeEntity
*/
@DELETE
@Consumes(MediaType.WILDCARD)
@Produces(MediaType.APPLICATION_JSON)
@Path("/{id}")
// TODO - @PreAuthorize("hasAnyRole('ROLE_ADMIN')")
@ApiOperation(
value = "Removes a node from the cluster",
response = NodeEntity.class,
authorizations = {
@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 = 404, message = "The specified resource could not be found."),
@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 deleteNode(
@ApiParam(
value = "The node id.",
required = true
)
@PathParam("id") String id) {
if (isConnectedToCluster()) {
serviceFacade.deleteNode(id);
// create the response entity
final NodeEntity entity = new NodeEntity();
// generate the response
return generateOkResponse(entity).build();
}
throw new IllegalClusterResourceRequestException("Only a cluster manager can process the request.");
}
// setters
public void setServiceFacade(NiFiServiceFacade serviceFacade) {
this.serviceFacade = serviceFacade;
}
}

Просмотреть файл

@ -16,8 +16,22 @@
*/
package org.apache.nifi.web.api;
import java.net.URI;
import java.util.Set;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@ -33,25 +47,7 @@ import javax.ws.rs.QueryParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.request.ClientIdParameter;
import org.apache.nifi.web.api.request.LongParameter;
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.util.Set;
/**
* RESTful endpoint for managing an Output Port.
@ -233,23 +229,16 @@ public class OutputPortResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable outputPort = lookup.getOutputPort(id);
outputPort.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getOutputPort(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateOutputPort(requestPortDTO),
() -> {
// update the output port
final UpdateResult<PortEntity> updateResult = serviceFacade.updateOutputPort(revision, requestPortDTO);
// get the results
final PortEntity entity = updateResult.getResult();
final PortEntity entity = serviceFacade.updateOutputPort(revision, requestPortDTO);
populateRemainingOutputPortEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -16,36 +16,14 @@
*/
package org.apache.nifi.web.api;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import com.sun.jersey.api.core.ResourceContext;
import com.sun.jersey.multipart.FormDataParam;
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.Authorizer;
import org.apache.nifi.authorization.RequestAction;
@ -54,7 +32,6 @@ import org.apache.nifi.controller.Snippet;
import org.apache.nifi.web.AuthorizableLookup;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ConnectionDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
@ -88,14 +65,34 @@ import org.apache.nifi.web.api.request.LongParameter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jersey.api.core.ResourceContext;
import com.sun.jersey.multipart.FormDataParam;
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 javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.HttpMethod;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* RESTful endpoint for managing a Group.
@ -320,21 +317,16 @@ public class ProcessGroupResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable processGroup = lookup.getProcessGroup(id);
processGroup.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getProcessGroup(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
null,
() -> {
// update the process group
final UpdateResult<ProcessGroupEntity> updateResult = serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO);
final ProcessGroupEntity entity = updateResult.getResult();
final ProcessGroupEntity entity = serviceFacade.updateProcessGroup(revision, requestProcessGroupDTO);
populateRemainingProcessGroupEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}
@ -457,6 +449,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Process group details must be specified.");
}
if (processGroupEntity.getRevision() == null || (processGroupEntity.getRevision().getVersion() == null || processGroupEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Process group.");
}
if (processGroupEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Process group ID cannot be specified.");
}
@ -488,7 +484,8 @@ public class ProcessGroupResource extends ApplicationResource {
processGroupEntity.getComponent().setId(generateUuid());
// create the process group contents
final ProcessGroupEntity entity = serviceFacade.createProcessGroup(groupId, processGroupEntity.getComponent());
final Revision revision = getRevision(processGroupEntity, processGroupEntity.getComponent().getId());
final ProcessGroupEntity entity = serviceFacade.createProcessGroup(revision, groupId, processGroupEntity.getComponent());
populateRemainingProcessGroupEntityContent(entity);
// generate a 201 created response
@ -608,6 +605,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Processor details must be specified.");
}
if (processorEntity.getRevision() == null || (processorEntity.getRevision().getVersion() == null || processorEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Processor.");
}
if (processorEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Processor ID cannot be specified.");
}
@ -643,7 +644,8 @@ public class ProcessGroupResource extends ApplicationResource {
processorEntity.getComponent().setId(generateUuid());
// create the new processor
final ProcessorEntity entity = serviceFacade.createProcessor(groupId, processorEntity.getComponent());
final Revision revision = getRevision(processorEntity, processorEntity.getComponent().getId());
final ProcessorEntity entity = serviceFacade.createProcessor(revision, groupId, processorEntity.getComponent());
processorResource.populateRemainingProcessorEntityContent(entity);
// generate a 201 created response
@ -757,6 +759,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Port details must be specified.");
}
if (portEntity.getRevision() == null || (portEntity.getRevision().getVersion() == null || portEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Input port.");
}
if (portEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Input port ID cannot be specified.");
}
@ -788,7 +794,8 @@ public class ProcessGroupResource extends ApplicationResource {
portEntity.getComponent().setId(generateUuid());
// create the input port and generate the json
final PortEntity entity = serviceFacade.createInputPort(groupId, portEntity.getComponent());
final Revision revision = getRevision(portEntity, portEntity.getComponent().getId());
final PortEntity entity = serviceFacade.createInputPort(revision, groupId, portEntity.getComponent());
inputPortResource.populateRemainingInputPortEntityContent(entity);
// build the response
@ -899,6 +906,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Port details must be specified.");
}
if (portEntity.getRevision() == null || (portEntity.getRevision().getVersion() == null || portEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Output port.");
}
if (portEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Output port ID cannot be specified.");
}
@ -930,7 +941,8 @@ public class ProcessGroupResource extends ApplicationResource {
portEntity.getComponent().setId(generateUuid());
// create the output port and generate the json
final PortEntity entity = serviceFacade.createOutputPort(groupId, portEntity.getComponent());
final Revision revision = getRevision(portEntity, portEntity.getComponent().getId());
final PortEntity entity = serviceFacade.createOutputPort(revision, groupId, portEntity.getComponent());
outputPortResource.populateRemainingOutputPortEntityContent(entity);
// build the response
@ -1042,6 +1054,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Funnel details must be specified.");
}
if (funnelEntity.getRevision() == null || (funnelEntity.getRevision().getVersion() == null || funnelEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Funnel.");
}
if (funnelEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Funnel ID cannot be specified.");
}
@ -1073,7 +1089,8 @@ public class ProcessGroupResource extends ApplicationResource {
funnelEntity.getComponent().setId(generateUuid());
// create the funnel and generate the json
final FunnelEntity entity = serviceFacade.createFunnel(groupId, funnelEntity.getComponent());
final Revision revision = getRevision(funnelEntity, funnelEntity.getComponent().getId());
final FunnelEntity entity = serviceFacade.createFunnel(revision, groupId, funnelEntity.getComponent());
funnelResource.populateRemainingFunnelEntityContent(entity);
// build the response
@ -1185,6 +1202,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Label details must be specified.");
}
if (labelEntity.getRevision() == null || (labelEntity.getRevision().getVersion() == null || labelEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Label.");
}
if (labelEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Label ID cannot be specified.");
}
@ -1216,7 +1237,8 @@ public class ProcessGroupResource extends ApplicationResource {
labelEntity.getComponent().setId(generateUuid());
// create the label and generate the json
final LabelEntity entity = serviceFacade.createLabel(groupId, labelEntity.getComponent());
final Revision revision = getRevision(labelEntity, labelEntity.getComponent().getId());
final LabelEntity entity = serviceFacade.createLabel(revision, groupId, labelEntity.getComponent());
labelResource.populateRemainingLabelEntityContent(entity);
// build the response
@ -1328,6 +1350,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Remote process group details must be specified.");
}
if (remoteProcessGroupEntity.getRevision() == null || (remoteProcessGroupEntity.getRevision().getVersion() == null || remoteProcessGroupEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Remote process group.");
}
final RemoteProcessGroupDTO requestProcessGroupDTO = remoteProcessGroupEntity.getComponent();
if (requestProcessGroupDTO.getId() != null) {
@ -1391,7 +1417,8 @@ public class ProcessGroupResource extends ApplicationResource {
requestProcessGroupDTO.setTargetUri(controllerUri);
// create the remote process group
final RemoteProcessGroupEntity entity = serviceFacade.createRemoteProcessGroup(groupId, requestProcessGroupDTO);
final Revision revision = getRevision(remoteProcessGroupEntity, requestProcessGroupDTO.getId());
final RemoteProcessGroupEntity entity = serviceFacade.createRemoteProcessGroup(revision, groupId, requestProcessGroupDTO);
remoteProcessGroupResource.populateRemainingRemoteProcessGroupEntityContent(entity);
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
@ -1517,6 +1544,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Connection details must be specified.");
}
if (connectionEntity.getRevision() == null || (connectionEntity.getRevision().getVersion() == null || connectionEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Connection.");
}
if (connectionEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Connection ID cannot be specified.");
}
@ -1552,7 +1583,8 @@ public class ProcessGroupResource extends ApplicationResource {
connection.setId(generateUuid());
// create the new relationship target
final ConnectionEntity entity = serviceFacade.createConnection(groupId, connection);
final Revision revision = getRevision(connectionEntity, connection.getId());
final ConnectionEntity entity = serviceFacade.createConnection(revision, groupId, connection);
connectionResource.populateRemainingConnectionEntityContent(entity);
// extract the href and build the response
@ -2127,6 +2159,10 @@ public class ProcessGroupResource extends ApplicationResource {
throw new IllegalArgumentException("Controller service details must be specified.");
}
if (controllerServiceEntity.getRevision() == null || (controllerServiceEntity.getRevision().getVersion() == null || controllerServiceEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Controller service.");
}
if (controllerServiceEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("Controller service ID cannot be specified.");
}
@ -2162,7 +2198,8 @@ public class ProcessGroupResource extends ApplicationResource {
controllerServiceEntity.getComponent().setId(generateUuid());
// create the controller service and generate the json
final ControllerServiceEntity entity = serviceFacade.createControllerService(groupId, controllerServiceEntity.getComponent());
final Revision revision = getRevision(controllerServiceEntity, controllerServiceEntity.getComponent().getId());
final ControllerServiceEntity entity = serviceFacade.createControllerService(revision, groupId, controllerServiceEntity.getComponent());
controllerServiceResource.populateRemainingControllerServiceContent(entity.getComponent());
// build the response

Просмотреть файл

@ -31,7 +31,6 @@ import org.apache.nifi.ui.extension.UiExtensionMapping;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UiExtensionType;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ComponentStateDTO;
import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
import org.apache.nifi.web.api.dto.ProcessorDTO;
@ -58,7 +57,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.List;
import java.util.Set;
@ -383,8 +381,6 @@ public class ProcessorResource extends ApplicationResource {
processor.authorize(authorizer, RequestAction.WRITE);
});
}
// handle expects request (usually from the cluster manager)
if (isValidationPhase) {
serviceFacade.verifyCanClearProcessorState(id);
return generateContinueResponse().build();
@ -467,21 +463,16 @@ public class ProcessorResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable processor = lookup.getProcessor(id);
processor.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getProcessor(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateProcessor(requestProcessorDTO),
() -> {
// update the processor
final UpdateResult<ProcessorEntity> result = serviceFacade.updateProcessor(revision, requestProcessorDTO);
final ProcessorEntity entity = result.getResult();
final ProcessorEntity entity = serviceFacade.updateProcessor(revision, requestProcessorDTO);
populateRemainingProcessorEntityContent(entity);
if (result.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -28,7 +28,6 @@ import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
@ -492,8 +491,8 @@ public class RemoteProcessGroupResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable remoteProcessGroup = lookup.getRemoteProcessGroup(id);
remoteProcessGroup.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getRemoteProcessGroup(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateRemoteProcessGroup(requestRemoteProcessGroup),
() -> {
@ -530,16 +529,10 @@ public class RemoteProcessGroupResource extends ApplicationResource {
}
// update the specified remote process group
final UpdateResult<RemoteProcessGroupEntity> updateResult = serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup);
final RemoteProcessGroupEntity entity = updateResult.getResult();
final RemoteProcessGroupEntity entity = serviceFacade.updateRemoteProcessGroup(revision, requestRemoteProcessGroup);
populateRemainingRemoteProcessGroupEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -31,7 +31,6 @@ import org.apache.nifi.ui.extension.UiExtensionMapping;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UiExtensionType;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.ComponentStateDTO;
import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
import org.apache.nifi.web.api.dto.ReportingTaskDTO;
@ -57,7 +56,6 @@ import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.util.List;
import java.util.Set;
@ -359,12 +357,10 @@ public class ReportingTaskResource extends ApplicationResource {
if (isValidationPhase || !isTwoPhaseRequest(httpServletRequest)) {
// authorize access
serviceFacade.authorizeAccess(lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id);
reportingTask.authorize(authorizer, RequestAction.WRITE);
final Authorizable processor = lookup.getReportingTask(id);
processor.authorize(authorizer, RequestAction.WRITE);
});
}
// handle expects request (usually from the cluster manager)
if (isValidationPhase) {
serviceFacade.verifyCanClearReportingTaskState(id);
return generateContinueResponse().build();
@ -446,23 +442,16 @@ public class ReportingTaskResource extends ApplicationResource {
serviceFacade,
revision,
lookup -> {
final Authorizable reportingTask = lookup.getReportingTask(id);
reportingTask.authorize(authorizer, RequestAction.WRITE);
Authorizable authorizable = lookup.getReportingTask(id);
authorizable.authorize(authorizer, RequestAction.WRITE);
},
() -> serviceFacade.verifyUpdateReportingTask(requestReportingTaskDTO),
() -> {
// update the reporting task
final UpdateResult<ReportingTaskEntity> controllerResponse = serviceFacade.updateReportingTask(revision, requestReportingTaskDTO);
// get the results
final ReportingTaskEntity entity = controllerResponse.getResult();
final ReportingTaskEntity entity = serviceFacade.updateReportingTask(revision, requestReportingTaskDTO);
populateRemainingReportingTaskEntityContent(entity);
if (controllerResponse.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -24,6 +24,7 @@ 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.Authorizer;
import org.apache.nifi.authorization.user.NiFiUser;
import org.apache.nifi.authorization.user.NiFiUserUtils;
import org.apache.nifi.remote.HttpRemoteSiteListener;
@ -38,11 +39,11 @@ import org.apache.nifi.remote.exception.NotAuthorizedException;
import org.apache.nifi.remote.exception.RequestExpiredException;
import org.apache.nifi.remote.io.http.HttpOutput;
import org.apache.nifi.remote.io.http.HttpServerCommunicationsSession;
import org.apache.nifi.remote.protocol.HandshakeProperty;
import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocol;
import org.apache.nifi.remote.protocol.http.HttpFlowFileServerProtocolImpl;
import org.apache.nifi.remote.protocol.http.HttpHeaders;
import org.apache.nifi.remote.protocol.HandshakeProperty;
import org.apache.nifi.remote.protocol.ResponseCode;
import org.apache.nifi.stream.io.ByteArrayOutputStream;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.api.dto.ControllerDTO;
@ -82,17 +83,17 @@ import java.util.ArrayList;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static org.apache.commons.lang3.StringUtils.isEmpty;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_USE_COMPRESSION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_COUNT;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_DURATION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_SIZE;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_REQUEST_EXPIRATION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_NAME;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_VALUE;
import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_COUNT;
import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_DURATION;
import static org.apache.nifi.remote.protocol.HandshakeProperty.BATCH_SIZE;
import static org.apache.nifi.remote.protocol.HandshakeProperty.REQUEST_EXPIRATION_MILLIS;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_COUNT;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_DURATION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_BATCH_SIZE;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_REQUEST_EXPIRATION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.HANDSHAKE_PROPERTY_USE_COMPRESSION;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_NAME;
import static org.apache.nifi.remote.protocol.http.HttpHeaders.LOCATION_URI_INTENT_VALUE;
/**
* RESTful endpoint for managing a SiteToSite connection.
@ -114,6 +115,7 @@ public class SiteToSiteResource extends ApplicationResource {
private static final String PORT_TYPE_OUTPUT = "output-ports";
private NiFiServiceFacade serviceFacade;
private Authorizer authorizer;
private final ResponseCreator responseCreator = new ResponseCreator();
private final VersionNegotiator transportProtocolVersionNegotiator = new TransportProtocolVersionNegotiator(1);
private final HttpRemoteSiteListener transactionManager = HttpRemoteSiteListener.getInstance();
@ -143,7 +145,7 @@ public class SiteToSiteResource 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 getController(
public Response getSiteToSite(
@Context HttpServletRequest req) {
if (isReplicateRequest()) {
@ -996,6 +998,9 @@ public class SiteToSiteResource extends ApplicationResource {
this.serviceFacade = serviceFacade;
}
public void setAuthorizer(Authorizer authorizer) {
this.authorizer = authorizer;
}
private class ResponseCreator {

Просмотреть файл

@ -31,7 +31,6 @@ import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.UserGroupDTO;
import org.apache.nifi.web.api.entity.UserGroupEntity;
@ -133,6 +132,10 @@ public class UserGroupsResource extends ApplicationResource {
throw new IllegalArgumentException("User group details must be specified.");
}
if (userGroupEntity.getRevision() == null || (userGroupEntity.getRevision().getVersion() == null || userGroupEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Processor.");
}
if (userGroupEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("User group ID cannot be specified.");
}
@ -294,17 +297,10 @@ public class UserGroupsResource extends ApplicationResource {
null,
() -> {
// update the user group
final UpdateResult<UserGroupEntity> updateResult = serviceFacade.updateUserGroup(revision, userGroupDTO);
// get the results
final UserGroupEntity entity = updateResult.getResult();
final UserGroupEntity entity = serviceFacade.updateUserGroup(revision, userGroupDTO);
populateRemainingUserGroupEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -31,7 +31,6 @@ import org.apache.nifi.cluster.coordination.http.replication.RequestReplicator;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiServiceFacade;
import org.apache.nifi.web.Revision;
import org.apache.nifi.web.UpdateResult;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.dto.UserDTO;
import org.apache.nifi.web.api.entity.UserEntity;
@ -133,6 +132,10 @@ public class UsersResource extends ApplicationResource {
throw new IllegalArgumentException("User details must be specified.");
}
if (userEntity.getRevision() == null || (userEntity.getRevision().getVersion() == null || userEntity.getRevision().getVersion() != 0)) {
throw new IllegalArgumentException("A revision of 0 must be specified when creating a new Processor.");
}
if (userEntity.getComponent().getId() != null) {
throw new IllegalArgumentException("User ID cannot be specified.");
}
@ -294,17 +297,10 @@ public class UsersResource extends ApplicationResource {
null,
() -> {
// update the user
final UpdateResult<UserEntity> updateResult = serviceFacade.updateUser(revision, userDTO);
// get the results
final UserEntity entity = updateResult.getResult();
final UserEntity entity = serviceFacade.updateUser(revision, userDTO);
populateRemainingUserEntityContent(entity);
if (updateResult.isNew()) {
return clusterContext(generateCreatedResponse(URI.create(entity.getComponent().getUri()), entity)).build();
} else {
return clusterContext(generateOkResponse(entity)).build();
}
return clusterContext(generateOkResponse(entity)).build();
}
);
}

Просмотреть файл

@ -185,10 +185,15 @@ public final class DtoFactory {
private EntityFactory entityFactory;
private Authorizer authorizer;
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade, final String autoRefreshInterval) {
public ControllerConfigurationDTO createControllerConfigurationDto(final ControllerFacade controllerFacade) {
final ControllerConfigurationDTO dto = new ControllerConfigurationDTO();
dto.setMaxTimerDrivenThreadCount(controllerFacade.getMaxTimerDrivenThreadCount());
dto.setMaxEventDrivenThreadCount(controllerFacade.getMaxEventDrivenThreadCount());
return dto;
}
public FlowConfigurationDTO createFlowConfigurationDto(final String autoRefreshInterval) {
final FlowConfigurationDTO dto = new FlowConfigurationDTO();
// get the refresh interval
final long refreshInterval = FormatUtils.getTimeDuration(autoRefreshInterval, TimeUnit.SECONDS);

Просмотреть файл

@ -42,6 +42,7 @@ import org.apache.nifi.web.api.entity.SnippetEntity;
import org.apache.nifi.web.api.entity.UserEntity;
import org.apache.nifi.web.api.entity.UserGroupEntity;
import java.util.Date;
import java.util.List;
public final class EntityFactory {
@ -49,12 +50,12 @@ public final class EntityFactory {
public ControllerConfigurationEntity createControllerConfigurationEntity(final ControllerConfigurationDTO dto, final RevisionDTO revision, final AccessPolicyDTO accessPolicy) {
final ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
entity.setRevision(revision);
entity.setCurrentTime(new Date());
if (dto != null) {
entity.setAccessPolicy(accessPolicy);
// TODO - remove this once contents of ControllerConfigurationEntity is updated
// if (accessPolicy != null && accessPolicy.getCanRead()) {
entity.setConfig(dto);
// }
if (accessPolicy != null && accessPolicy.getCanRead()) {
entity.setControllerConfiguration(dto);
}
}
return entity;
}

Просмотреть файл

@ -19,7 +19,12 @@ package org.apache.nifi.web.controller;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.admin.service.KeyService;
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;
import org.apache.nifi.authorization.resource.Authorizable;
import org.apache.nifi.authorization.resource.ResourceFactory;
@ -111,6 +116,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response;
import java.io.IOException;
import java.io.InputStream;
import java.text.Collator;
@ -130,6 +136,8 @@ import java.util.TimeZone;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import static org.apache.nifi.controller.FlowController.ROOT_GROUP_ID_ALIAS;
public class ControllerFacade implements Authorizable {
private static final Logger logger = LoggerFactory.getLogger(ControllerFacade.class);
@ -137,14 +145,15 @@ public class ControllerFacade implements Authorizable {
// nifi components
private FlowController flowController;
private FlowService flowService;
private KeyService keyService;
private ClusterCoordinator clusterCoordinator;
private BulletinRepository bulletinRepository;
private Authorizer authorizer;
// properties
private NiFiProperties properties;
private DtoFactory dtoFactory;
/**
* Creates an archive of the current flow.
*
@ -264,6 +273,14 @@ public class ControllerFacade implements Authorizable {
* @return status history
*/
public StatusHistoryDTO getProcessorStatusHistory(final String processorId) {
final ProcessGroup root = flowController.getGroup(flowController.getRootGroupId());
final ProcessorNode processor = root.findProcessor(processorId);
// ensure the processor was found
if (processor == null) {
throw new ResourceNotFoundException(String.format("Unable to locate processor with id '%s'.", processorId));
}
return flowController.getProcessorStatusHistory(processorId);
}
@ -274,6 +291,14 @@ public class ControllerFacade implements Authorizable {
* @return status history
*/
public StatusHistoryDTO getConnectionStatusHistory(final String connectionId) {
final ProcessGroup root = flowController.getGroup(flowController.getRootGroupId());
final Connection connection = root.findConnection(connectionId);
// ensure the connection was found
if (connection == null) {
throw new ResourceNotFoundException(String.format("Unable to locate connection with id '%s'.", connectionId));
}
return flowController.getConnectionStatusHistory(connectionId);
}
@ -284,6 +309,15 @@ public class ControllerFacade implements Authorizable {
* @return status history
*/
public StatusHistoryDTO getProcessGroupStatusHistory(final String groupId) {
final String searchId = groupId.equals(ROOT_GROUP_ID_ALIAS) ? flowController.getRootGroupId() : groupId;
final ProcessGroup root = flowController.getGroup(flowController.getRootGroupId());
final ProcessGroup group = root.findProcessGroup(searchId);
// ensure the processor was found
if (group == null) {
throw new ResourceNotFoundException(String.format("Unable to locate process group with id '%s'.", groupId));
}
return flowController.getProcessGroupStatusHistory(groupId);
}
@ -294,6 +328,14 @@ public class ControllerFacade implements Authorizable {
* @return status history
*/
public StatusHistoryDTO getRemoteProcessGroupStatusHistory(final String remoteProcessGroupId) {
final ProcessGroup root = flowController.getGroup(flowController.getRootGroupId());
final RemoteProcessGroup remoteProcessGroup = root.findRemoteProcessGroup(remoteProcessGroupId);
// ensure the output port was found
if (remoteProcessGroup == null) {
throw new ResourceNotFoundException(String.format("Unable to locate remote process group with id '%s'.", remoteProcessGroupId));
}
return flowController.getRemoteProcessGroupStatusHistory(remoteProcessGroupId);
}
@ -1085,9 +1127,6 @@ public class ControllerFacade implements Authorizable {
public DownloadableContent getContent(final Long eventId, final String uri, final ContentDirection contentDirection) {
try {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
if (user == null) {
throw new WebApplicationException(new Throwable("Unable to access details for current user."));
}
// get the event in order to get the filename
final ProvenanceEventRecord event = flowController.getProvenanceRepository().getEvent(eventId);
@ -1105,12 +1144,56 @@ public class ControllerFacade implements Authorizable {
// calculate the dn chain
final List<String> dnChain = ProxiedEntitiesUtils.buildProxiedEntitiesChain(user);
dnChain.forEach(identity -> {
final String rootGroupId = flowController.getRootGroupId();
final ProcessGroup rootGroup = flowController.getGroup(rootGroupId);
// TODO - ensure the users in this chain are allowed to download this content
// final DownloadAuthorization downloadAuthorization = keyService.authorizeDownload(dnChain, attributes);
// if (!downloadAuthorization.isApproved()) {
// throw new AccessDeniedException(downloadAuthorization.getExplanation());
// }
final Resource eventResource;
if (rootGroupId.equals(event.getComponentId())) {
eventResource = ResourceFactory.getComponentProvenanceResource(ResourceType.ProcessGroup, rootGroup.getIdentifier(), rootGroup.getName());
} else {
final Connectable connectable = rootGroup.findConnectable(event.getComponentId());
if (connectable == null) {
throw new AccessDeniedException("The component that generated this event is no longer part of the data flow. Unable to determine access policy.");
}
switch (connectable.getConnectableType()) {
case PROCESSOR:
eventResource = ResourceFactory.getComponentProvenanceResource(ResourceType.Processor, connectable.getIdentifier(), connectable.getName());
break;
case INPUT_PORT:
case REMOTE_INPUT_PORT:
eventResource = ResourceFactory.getComponentProvenanceResource(ResourceType.InputPort, connectable.getIdentifier(), connectable.getName());
break;
case OUTPUT_PORT:
case REMOTE_OUTPUT_PORT:
eventResource = ResourceFactory.getComponentProvenanceResource(ResourceType.OutputPort, connectable.getIdentifier(), connectable.getName());
break;
case FUNNEL:
eventResource = ResourceFactory.getComponentProvenanceResource(ResourceType.Funnel, connectable.getIdentifier(), connectable.getName());
break;
default:
throw new WebApplicationException(Response.serverError().entity("An unexpected type of component generated this event.").build());
}
}
// build the request
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(identity)
.anonymous(user.isAnonymous()) // allow current user to drive anonymous flag as anonymous users are never chained... supports single user case
.accessAttempt(false)
.action(RequestAction.READ)
.resource(eventResource)
.eventAttributes(attributes)
.build();
// perform the authorization
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
throw new AccessDeniedException(result.getExplanation());
}
});
// get the filename and fall back to the identifier (should never happen)
String filename = attributes.get(CoreAttributes.FILENAME.key());
@ -1687,8 +1770,8 @@ public class ControllerFacade implements Authorizable {
this.properties = properties;
}
public void setKeyService(KeyService keyService) {
this.keyService = keyService;
public void setAuthorizer(Authorizer authorizer) {
this.authorizer = authorizer;
}
public void setFlowService(FlowService flowService) {

Просмотреть файл

@ -16,6 +16,10 @@
*/
package org.apache.nifi.web.dao.impl;
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.user.NiFiUser;
@ -579,9 +583,6 @@ public class StandardConnectionDAO extends ComponentDAO implements ConnectionDAO
public DownloadableContent getContent(String id, String flowFileUuid, String requestUri) {
try {
final NiFiUser user = NiFiUserUtils.getNiFiUser();
if (user == null) {
throw new WebApplicationException(new Throwable("Unable to access details for current user."));
}
final Connection connection = locateConnection(id);
final FlowFileQueue queue = connection.getFlowFileQueue();
@ -591,15 +592,27 @@ public class StandardConnectionDAO extends ComponentDAO implements ConnectionDAO
throw new ResourceNotFoundException(String.format("The FlowFile with UUID %s is no longer in the active queue.", flowFileUuid));
}
final Map<String, String> attributes = flowFile.getAttributes();
// calculate the dn chain
final List<String> dnChain = ProxiedEntitiesUtils.buildProxiedEntitiesChain(user);
dnChain.forEach(identity -> {
// build the request
final AuthorizationRequest request = new AuthorizationRequest.Builder()
.identity(identity)
.anonymous(user.isAnonymous())
.accessAttempt(false)
.action(RequestAction.WRITE)
.resource(connection.getResource())
.eventAttributes(attributes)
.build();
// TODO - ensure the users in this chain are allowed to download this content
final Map<String, String> attributes = flowFile.getAttributes();
// final DownloadAuthorization downloadAuthorization = keyService.authorizeDownload(dnChain, attributes);
// if (!downloadAuthorization.isApproved()) {
// throw new AccessDeniedException(downloadAuthorization.getExplanation());
// }
// perform the authorization
final AuthorizationResult result = authorizer.authorize(request);
if (!Result.Approved.equals(result.getResult())) {
throw new AccessDeniedException(result.getExplanation());
}
});
// get the filename and fall back to the identifier (should never happen)
String filename = attributes.get(CoreAttributes.FILENAME.key());

Просмотреть файл

@ -39,6 +39,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.nifi.controller.FlowController.ROOT_GROUP_ID_ALIAS;
public class StandardControllerServiceDAO extends ComponentDAO implements ControllerServiceDAO {
private ControllerServiceProvider serviceProvider;
@ -79,7 +81,7 @@ public class StandardControllerServiceDAO extends ComponentDAO implements Contro
flowController.addRootControllerService(controllerService);
} else {
final ProcessGroup group;
if (groupId.equals(FlowController.ROOT_GROUP_ID_ALIAS)) {
if (groupId.equals(ROOT_GROUP_ID_ALIAS)) {
group = flowController.getGroup(flowController.getRootGroupId());
} else {
group = flowController.getGroup(flowController.getRootGroupId()).findProcessGroup(groupId);
@ -113,7 +115,8 @@ public class StandardControllerServiceDAO extends ComponentDAO implements Contro
if (groupId == null) {
return flowController.getRootControllerServices();
} else {
final ProcessGroup procGroup = flowController.getGroup(flowController.getRootGroupId()).findProcessGroup(groupId);
final String searchId = groupId.equals(ROOT_GROUP_ID_ALIAS) ? flowController.getRootGroupId() : groupId;
final ProcessGroup procGroup = flowController.getGroup(flowController.getRootGroupId()).findProcessGroup(searchId);
if (procGroup == null) {
throw new ResourceNotFoundException("Could not find Process Group with ID " + groupId);
}

Просмотреть файл

@ -116,7 +116,7 @@
<property name="flowController" ref="flowController"/>
<property name="flowService" ref="flowService"/>
<property name="clusterCoordinator" ref="clusterCoordinator" />
<property name="keyService" ref="keyService"/>
<property name="authorizer" ref="authorizer"/>
<property name="dtoFactory" ref="dtoFactory"/>
<property name="bulletinRepository" ref="bulletinRepository"/>
</bean>
@ -157,7 +157,6 @@
<property name="userGroupDAO" ref="policyBasedAuthorizerDAO"/>
<property name="userDAO" ref="policyBasedAuthorizerDAO"/>
<property name="auditService" ref="auditService"/>
<property name="keyService" ref="keyService"/>
<property name="snippetUtils" ref="snippetUtils"/>
<property name="revisionManager" ref="revisionManager" />
<property name="dtoFactory" ref="dtoFactory"/>
@ -219,6 +218,7 @@
<property name="properties" ref="nifiProperties"/>
<property name="clusterCoordinator" ref="clusterCoordinator"/>
<property name="requestReplicator" ref="requestReplicator" />
<property name="authorizer" ref="authorizer"/>
</bean>
<bean id="snippetResource" class="org.apache.nifi.web.api.SnippetResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>
@ -320,12 +320,6 @@
<property name="requestReplicator" ref="requestReplicator" />
<property name="authorizer" ref="authorizer" />
</bean>
<bean id="historyResource" class="org.apache.nifi.web.api.HistoryResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>
<property name="properties" ref="nifiProperties"/>
<property name="clusterCoordinator" ref="clusterCoordinator"/>
<property name="requestReplicator" ref="requestReplicator" />
</bean>
<bean id="provenanceResource" class="org.apache.nifi.web.api.ProvenanceResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>
<property name="properties" ref="nifiProperties"/>
@ -333,17 +327,12 @@
<property name="requestReplicator" ref="requestReplicator" />
<property name="authorizer" ref="authorizer"/>
</bean>
<bean id="clusterResource" class="org.apache.nifi.web.api.ClusterResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>
<property name="properties" ref="nifiProperties"/>
<property name="clusterCoordinator" ref="clusterCoordinator"/>
<property name="requestReplicator" ref="requestReplicator" />
</bean>
<bean id="nodeResource" class="org.apache.nifi.web.api.NodeResource" scope="singleton">
<bean id="countersResource" class="org.apache.nifi.web.api.CountersResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>
<property name="properties" ref="nifiProperties"/>
<property name="clusterCoordinator" ref="clusterCoordinator"/>
<property name="requestReplicator" ref="requestReplicator" />
<property name="authorizer" ref="authorizer"/>
</bean>
<bean id="systemDiagnosticsResource" class="org.apache.nifi.web.api.SystemDiagnosticsResource" scope="singleton">
<property name="serviceFacade" ref="serviceFacade"/>

Просмотреть файл

@ -20,6 +20,7 @@ import org.apache.nifi.authorization.*
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.authorization.user.NiFiUserDetails
import org.apache.nifi.controller.service.ControllerServiceProvider
import org.apache.nifi.web.api.dto.*
import org.apache.nifi.web.api.entity.UserEntity
@ -28,11 +29,25 @@ import org.apache.nifi.web.dao.AccessPolicyDAO
import org.apache.nifi.web.dao.UserDAO
import org.apache.nifi.web.dao.UserGroupDAO
import org.apache.nifi.web.revision.*
import org.apache.nifi.web.security.token.NiFiAuthenticationToken
import org.springframework.security.core.context.SecurityContextHolder
import spock.lang.Ignore
import spock.lang.Specification
import spock.lang.Unroll
@Ignore
class StandardNiFiServiceFacadeSpec extends Specification {
def setup() {
final NiFiUser user = new NiFiUser("nifi-user");
final NiFiAuthenticationToken auth = new NiFiAuthenticationToken(new NiFiUserDetails(user));
SecurityContextHolder.getContext().setAuthentication(auth);
}
def cleanup() {
SecurityContextHolder.getContext().setAuthentication(null);
}
@Unroll
def "CreateUser: isAuthorized: #isAuthorized"() {
given:
@ -48,7 +63,7 @@ class StandardNiFiServiceFacadeSpec extends Specification {
def newUser = new User.Builder().identifier(userDto.id).identity(userDto.identity).build()
when:
def userEntity = niFiServiceFacade.createUser(new Revision(0L, 'client-1'), userDto)
def userEntity = niFiServiceFacade.createUser(new Revision(0L, 'client-1', userDto.id), userDto)
then:
1 * userDao.createUser(_) >> newUser
@ -97,19 +112,19 @@ class StandardNiFiServiceFacadeSpec extends Specification {
}
then:
if (isAuthorized) {
1 * userDao.getUser(userDto.id) >> requestedUser
}
1 * userDao.getUser(userDto.id) >> requestedUser
1 * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult)
0 * _
assert userEntity != null
if (isAuthorized) {
assert userEntity?.component?.id?.equals(userDto.id)
assert userEntity.component?.id?.equals(userDto.id)
} else {
assert exception instanceof AccessDeniedException
assert userEntity.component == null
}
where:
@ -149,6 +164,7 @@ class StandardNiFiServiceFacadeSpec extends Specification {
1 * revisionManager.updateRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser niFiUser, UpdateRevisionTask callback ->
callback.update()
}
1 * revisionManager.getRevision(currentRevision.componentId) >> currentRevision.incrementRevision(currentRevision.clientId)
}
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult)
@ -215,11 +231,11 @@ class StandardNiFiServiceFacadeSpec extends Specification {
}
where:
userExists | currentRevision | userDto | isAuthorized | authorizationResult
true | new Revision(1L, 'client1') | createUserDTO() | true | AuthorizationResult.approved()
false | null | createUserDTO() | true | AuthorizationResult.approved()
true | new Revision(1L, 'client1') | createUserDTO() | false | AuthorizationResult.denied()
false | null | createUserDTO() | false | AuthorizationResult.denied()
userExists | currentRevision | userDto | isAuthorized | authorizationResult
true | new Revision(1L, 'client1', 'user-1') | createUserDTO() | true | AuthorizationResult.approved()
false | null | createUserDTO() | true | AuthorizationResult.approved()
true | new Revision(1L, 'client1', 'user-1') | createUserDTO() | false | AuthorizationResult.denied()
false | null | createUserDTO() | false | AuthorizationResult.denied()
}
@Unroll
@ -249,26 +265,22 @@ class StandardNiFiServiceFacadeSpec extends Specification {
when:
try {
userGroupEntity = niFiServiceFacade.createUserGroup(new Revision(0L, 'client-1'), userGroupDto)
userGroupEntity = niFiServiceFacade.createUserGroup(new Revision(0L, 'client-1', userGroupDto.id), userGroupDto)
} catch (AccessDeniedException e) {
exception = e
}
then:
if (isAuthorized) {
1 * authorizableLookup.getUserGroupsAuthorizable() >>
new SimpleAuthorizable(null, ResourceFactory.userGroupsResource, isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
}
1 * authorizableLookup.getUserGroupsAuthorizable() >>
new SimpleAuthorizable(null, ResourceFactory.userGroupsResource, isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource, isAuthorized, authorizationResult.get(ResourceFactory.usersResource))
1 * userGroupDao.createUserGroup(_) >> newUserGroup
if (authorizationResult.get(ResourceFactory.usersResource) == AuthorizationResult.approved()) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity)
.addGroups(userEntity.groups.collect { it.id } as Set)
.build()
}
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity)
.addGroups(userEntity.groups.collect { it.id } as Set)
.build()
}
userGroupDto.users.size() * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
assert userGroupDto.users.collect { it.id }.contains(id)
@ -276,6 +288,8 @@ class StandardNiFiServiceFacadeSpec extends Specification {
callback.withRevision new Revision(revisionDTO.version, revisionDTO.clientId, id)
}
0 * _
assert userGroupEntity != null
if (isAuthorized) {
assert userGroupEntity?.component?.id == userGroupDto.id
assert userGroupEntity?.component?.users?.equals(userGroupDto.users)
@ -283,7 +297,6 @@ class StandardNiFiServiceFacadeSpec extends Specification {
assert userGroupEntity?.accessPolicy?.canWrite
} else {
assert userGroupEntity?.component == null
assert exception instanceof AccessDeniedException
}
@ -322,27 +335,25 @@ class StandardNiFiServiceFacadeSpec extends Specification {
}
then:
if (isAuthorized) {
1 * userGroupDao.getUserGroup(userGroupDto.id) >> requestedUserGroup
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource, isAuthorized, authorizationResult)
}
1 * userGroupDao.getUserGroup(userGroupDto.id) >> requestedUserGroup
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource, isAuthorized, authorizationResult)
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUserGroupsResource(),
isAuthorized, authorizationResult)
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
if (authorizationResult == AuthorizationResult.approved()) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
0 * _
assert userGroupEntity != null
if (isAuthorized) {
assert userGroupEntity?.component?.id?.equals(userGroupDto.id)
} else {
assert exception instanceof AccessDeniedException
assert userGroupEntity.component == null
}
where:
@ -393,32 +404,30 @@ class StandardNiFiServiceFacadeSpec extends Specification {
1 * revisionManager.updateRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser niFiUser, UpdateRevisionTask callback ->
callback.update()
}
1 * revisionManager.getRevision(currentRevision.componentId) >> currentRevision.incrementRevision(currentRevision.clientId)
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource,
isAuthorized, authorizationResult.get(ResourceFactory.usersResource))
}
if (isAuthorized || userGroupExists) {
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.userGroupsResource,
isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
}
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.userGroupsResource,
isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
if (authorizationResult.get(ResourceFactory.userGroupsResource) == AuthorizationResult.approved()) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
0 * _
def userGroupEntity = userGroupsEntityUpdateResult?.result
assert userGroupEntity != null
if (isAuthorized) {
assert userGroupEntity?.component?.id?.equals(userGroupDto.id)
assert userGroupEntity?.accessPolicy?.canRead
assert userGroupEntity?.accessPolicy?.canWrite
} else {
assert userGroupEntity?.component == null
assert exception instanceof AccessDeniedException
assert userGroupEntity.component == null
}
where:
@ -467,27 +476,23 @@ class StandardNiFiServiceFacadeSpec extends Specification {
then:
if (userGroupExists) {
1 * userGroupDao.getUserGroup(userGroupDto.id) >> userGroup
if (isAuthorized) {
1 * userGroupDao.deleteUserGroup(userGroupDto.id) >> userGroup
}
1 * userGroupDao.deleteUserGroup(userGroupDto.id) >> userGroup
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult.get(ResourceFactory.getUsersResource()))
} else {
1 * userGroupDao.getUserGroup(userGroupDto.id) >> null
1 * userGroupDao.deleteUserGroup(userGroupDto.id) >> null
}
if (!(!isAuthorized && userGroupExists)) {
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.userGroupsResource,
isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
task.performTask()
}
1 * controllerFacade.save()
1 * authorizableLookup.getUserGroupsAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.userGroupsResource,
isAuthorized, authorizationResult.get(ResourceFactory.userGroupsResource))
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
task.performTask()
}
1 * controllerFacade.save()
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
if (authorizationResult.get(ResourceFactory.userGroupsResource) == AuthorizationResult.approved() && userGroupExists) {
if (userGroupExists) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = userGroupDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
@ -496,14 +501,11 @@ class StandardNiFiServiceFacadeSpec extends Specification {
}
0 * _
userGroupEntity?.component?.id == null
if (userGroupExists && isAuthorized) {
if (userGroupExists) {
assert userGroupEntity?.id?.equals(userGroupDto.id)
} else {
assert userGroupEntity?.id == null
}
if (authorizationResult.get(ResourceFactory.usersResource) == AuthorizationResult.denied()) {
assert exception instanceof AccessDeniedException
}
where:
userGroupExists | currentRevision | userGroupDto | isAuthorized |
@ -550,37 +552,34 @@ class StandardNiFiServiceFacadeSpec extends Specification {
when:
try {
accessPolicyEntity = niFiServiceFacade.createAccessPolicy(new Revision(0L, 'client-1'), accessPolicyDto)
accessPolicyEntity = niFiServiceFacade.createAccessPolicy(new Revision(0L, 'client-1', accessPolicyDto.id), accessPolicyDto)
} catch (AccessDeniedException e) {
exception = e
}
then:
1 * accessPolicyDao.createAccessPolicy(accessPolicyDto) >> newAccessPolicy
if (isAuthorized) {
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
}
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult)
if (authorizationResult == AuthorizationResult.approved()) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
0 * _
assert accessPolicyEntity != null
if (isAuthorized) {
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
assert accessPolicyEntity?.accessPolicy?.canRead
assert accessPolicyEntity?.accessPolicy?.canWrite
} else {
assert accessPolicyEntity?.component == null
assert exception instanceof AccessDeniedException
assert accessPolicyEntity.component == null
}
where:
@ -626,28 +625,26 @@ class StandardNiFiServiceFacadeSpec extends Specification {
}
then:
if (isAuthorized) {
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> requestedAccessPolicy
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult)
}
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> requestedAccessPolicy
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult)
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
if (authorizationResult == AuthorizationResult.approved()) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
0 * _
assert accessPolicyEntity != null
if (isAuthorized) {
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
} else {
assert exception instanceof AccessDeniedException
assert accessPolicyEntity.component == null
}
where:
@ -704,32 +701,30 @@ class StandardNiFiServiceFacadeSpec extends Specification {
1 * revisionManager.updateRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser niFiUser, UpdateRevisionTask callback ->
callback.update()
}
1 * revisionManager.getRevision(currentRevision.componentId) >> currentRevision.incrementRevision(currentRevision.clientId)
}
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.getUsersResource(),
isAuthorized, authorizationResult)
if (isAuthorized || hasPolicy) {
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
}
if (authorizationResult == AuthorizationResult.approved()) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
new User.Builder().identifier(userEntity.id).identity(userEntity.identity).build()
}
1 * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
0 * _
def accessPolicyEntity = accessPolicyEntityUpdateResult?.result
assert accessPolicyEntity != null
if (isAuthorized) {
assert accessPolicyEntity?.component?.id?.equals(accessPolicyDto.id)
assert accessPolicyEntity?.accessPolicy?.canRead
assert accessPolicyEntity?.accessPolicy?.canWrite
} else {
assert accessPolicyEntity?.component == null
assert exception instanceof AccessDeniedException
assert accessPolicyEntity.component == null
}
where:
@ -787,27 +782,23 @@ class StandardNiFiServiceFacadeSpec extends Specification {
then:
if (hasPolicy) {
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> accessPolicy
if (isAuthorized) {
1 * accessPolicyDao.deleteAccessPolicy(accessPolicyDto.id) >> accessPolicy
}
1 * accessPolicyDao.deleteAccessPolicy(accessPolicyDto.id) >> accessPolicy
1 * authorizableLookup.getUsersAuthorizable() >> new SimpleAuthorizable(null, ResourceFactory.usersResource,
isAuthorized, authorizationResult)
} else {
1 * accessPolicyDao.getAccessPolicy(accessPolicyDto.id) >> null
1 * accessPolicyDao.deleteAccessPolicy(accessPolicyDto.id) >> null
}
if (!(!isAuthorized && hasPolicy)) {
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
task.performTask()
}
1 * controllerFacade.save()
1 * authorizableLookup.getAccessPolicyAuthorizable(accessPolicyDto.id) >> new SimpleAuthorizable(null, ResourceFactory.getPolicyResource(accessPolicyDto.id),
isAuthorized, authorizationResult)
1 * revisionManager.deleteRevision(_, _, _) >> { RevisionClaim revisionClaim, NiFiUser nifiUser, DeleteRevisionTask task ->
task.performTask()
}
1 * controllerFacade.save()
_ * revisionManager.get(_, _) >> { String id, ReadOnlyRevisionCallback callback ->
callback.withRevision(new Revision(1L, 'client1', 'root'))
}
if (authorizationResult == AuthorizationResult.approved() && hasPolicy) {
if (hasPolicy) {
1 * userDao.getUser(_) >> { String userId ->
def userEntity = accessPolicyDto.users.find { it.id.equals(userId) }?.component
assert userEntity != null
@ -815,14 +806,13 @@ class StandardNiFiServiceFacadeSpec extends Specification {
}
}
0 * _
if (hasPolicy && isAuthorized) {
assert accessPolicyEntity != null
if (hasPolicy) {
assert accessPolicyEntity?.id?.equals(accessPolicyDto.id)
} else {
assert accessPolicyEntity?.id == null
}
if (!isAuthorized && hasPolicy) {
assert exception instanceof AccessDeniedException
}
where:
hasPolicy | currentRevision | accessPolicyDto | isAuthorized |
@ -831,9 +821,9 @@ class StandardNiFiServiceFacadeSpec extends Specification {
AuthorizationResult.approved()
false | null | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | true |
AuthorizationResult.approved()
true | new Revision(1L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
true | new Revision(1L, 'client1', 'root') | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
AuthorizationResult.denied()
false | null | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
false | null | new AccessPolicyDTO(id: '1', resource: ResourceFactory.flowResource.identifier, users: [createUserEntity()], canRead: true) | false |
AuthorizationResult.denied()
}

Просмотреть файл

@ -48,10 +48,6 @@ import java.util.Set;
@Ignore
public class NiFiWebApiTest {
public static void populateFlow(Client client, String baseUrl, String clientId) throws Exception {
}
public static void populateFlow(Client client, String baseUrl, NiFiTestUser user, String clientId) throws Exception {
// -----------------------------------------------
@ -66,7 +62,7 @@ public class NiFiWebApiTest {
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(clientId);
revision.setVersion(NiFiTestUser.REVISION);
revision.setVersion(0l);
// create the local selection processor entity
ProcessorEntity processorEntity = new ProcessorEntity();

Просмотреть файл

@ -16,6 +16,7 @@
*/
package org.apache.nifi.integration.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.nifi.integration.NiFiWebApiTest;
import org.apache.nifi.integration.util.NiFiTestAuthorizer;
import org.apache.nifi.integration.util.NiFiTestServer;
@ -26,6 +27,8 @@ import org.apache.nifi.util.NiFiProperties;
import java.io.File;
import static org.junit.Assert.assertEquals;
/**
* Access control test for the dfm user.
*/
@ -48,6 +51,10 @@ public class AccessControlHelper {
private String baseUrl;
public AccessControlHelper(final String flowXmlPath) throws Exception {
this(flowXmlPath, null);
}
public AccessControlHelper(final String flowXmlPath, final String overrideAuthorizer) throws Exception {
this.flowXmlPath = flowXmlPath;
// look for the flow.xml and toss it
@ -64,6 +71,10 @@ public class AccessControlHelper {
NiFiProperties props = NiFiProperties.getInstance();
props.setProperty(NiFiProperties.FLOW_CONFIGURATION_FILE, flowXmlPath);
if (overrideAuthorizer != null) {
props.setProperty(NiFiProperties.SECURITY_USER_AUTHORIZER, overrideAuthorizer);
}
// load extensions
NarClassLoaders.load(props);
ExtensionManager.discoverExtensions();
@ -102,6 +113,26 @@ public class AccessControlHelper {
return noneUser;
}
public void testGenericGetUri(final String uri) throws Exception {
ClientResponse response;
// read
response = getReadUser().testGet(uri);
assertEquals(200, response.getStatus());
// read/write
response = getReadWriteUser().testGet(uri);
assertEquals(200, response.getStatus());
// write
response = getWriteUser().testGet(uri);
assertEquals(403, response.getStatus());
// none
response = getNoneUser().testGet(uri);
assertEquals(403, response.getStatus());
}
public String getBaseUrl() {
return baseUrl;
}

Просмотреть файл

@ -47,7 +47,7 @@ import java.util.Map;
/**
* Access token endpoint test.
*/
public class AccessTokenEndpointTest {
public class ITAccessTokenEndpoint {
private static final String CLIENT_ID = "token-endpoint-id";
private static final String CONTEXT_PATH = "/nifi-api";
@ -159,7 +159,7 @@ public class AccessTokenEndpointTest {
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
revision.setVersion(0l);
// create the entity body
ProcessorEntity entity = new ProcessorEntity();

Просмотреть файл

@ -50,7 +50,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for connections.
*/
public class ConnectionAccessControlTest {
public class ITConnectionAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-connections.xml";
@ -354,8 +354,8 @@ public class ConnectionAccessControlTest {
String url = helper.getBaseUrl() + "/process-groups/root/connections";
// get two processors
final ProcessorEntity one = ProcessorAccessControlTest.createProcessor(helper, "one");
final ProcessorEntity two = ProcessorAccessControlTest.createProcessor(helper, "two");
final ProcessorEntity one = ITProcessorAccessControl.createProcessor(helper, "one");
final ProcessorEntity two = ITProcessorAccessControl.createProcessor(helper, "two");
// create the source connectable
ConnectableDTO source = new ConnectableDTO();
@ -410,7 +410,7 @@ public class ConnectionAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -0,0 +1,86 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.Collections;
import static org.junit.Assert.assertEquals;
/**
* Access control test for funnels.
*/
public class ITCountersAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-counters.xml";
private static AccessControlHelper helper;
private static String uri;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH);
uri = helper.getBaseUrl() + "/counters";
}
/**
* Test get counters.
*
* @throws Exception exception
*/
@Test
public void testGetCounters() throws Exception {
helper.testGenericGetUri(uri);
}
/**
* Ensures the READ user can get counters.
*
* @throws Exception ex
*/
@Test
public void testUpdateCounters() throws Exception {
final String counterUri = uri + "/my-counter";
ClientResponse response;
// read
response = helper.getReadUser().testPut(counterUri, Collections.emptyMap());
assertEquals(403, response.getStatus());
// read/write
response = helper.getReadWriteUser().testPut(counterUri, Collections.emptyMap());
assertEquals(404, response.getStatus());
// write
response = helper.getWriteUser().testPut(counterUri, Collections.emptyMap());
assertEquals(404, response.getStatus());
// none
response = helper.getNoneUser().testPut(counterUri, Collections.emptyMap());
assertEquals(403, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

Просмотреть файл

@ -0,0 +1,245 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
/**
* Access control test for funnels.
*/
public class ITFlowAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-flow.xml";
private static AccessControlHelper helper;
@BeforeClass
public static void setup() throws Exception {
helper = new AccessControlHelper(FLOW_XML_PATH, "flow-test-provider");
}
/**
* Test get flow.
*
* @throws Exception exception
*/
@Test
public void testGetFlow() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/process-groups/root");
}
// TODO - test update flow
/**
* Test generate client.
*
* @throws Exception exception
*/
@Test
public void testGenerateClientId() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/client-id");
}
/**
* Test get identity.
*
* @throws Exception exception
*/
@Test
public void testGetIdentity() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/identity");
}
/**
* Test get controller services.
*
* @throws Exception exception
*/
@Test
public void testGetControllerServices() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/controller/controller-services");
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/process-groups/root/controller-services");
}
/**
* Test get reporting tasks.
*
* @throws Exception exception
*/
@Test
public void testGetReportingTasks() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/reporting-tasks");
}
/**
* Test search.
*
* @throws Exception exception
*/
@Test
public void testSearch() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/search-results");
}
/**
* Test status.
*
* @throws Exception exception
*/
@Test
public void testStatus() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/status");
}
/**
* Test banners.
*
* @throws Exception exception
*/
@Test
public void testBanners() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/status");
}
/**
* Test bulletin board.
*
* @throws Exception exception
*/
@Test
public void testBulletinBoard() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/bulletin-board");
}
/**
* Test about.
*
* @throws Exception exception
*/
@Test
public void testAbout() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/about");
}
/**
* Test get flow config.
*
* @throws Exception exception
*/
@Test
public void testGetFlowConfig() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/config");
}
/**
* Test get status.
*
* @throws Exception exception
*/
@Test
public void testGetStatus() throws Exception {
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/processors/my-component/status");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/input-ports/my-component/status");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/output-ports/my-component/status");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/remote-process-groups/my-component/status");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/process-groups/my-component/status");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/connections/my-component/status");
}
/**
* Test get status history.
*
* @throws Exception exception
*/
@Test
public void testGetStatusHistory() throws Exception {
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/processors/my-component/status/history");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/remote-process-groups/my-component/status/history");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/process-groups/my-component/status/history");
testComponentSpecificGetUri(helper.getBaseUrl() + "/flow/connections/my-component/status/history");
}
/**
* Test get action.
*
* @throws Exception exception
*/
@Test
public void testGetAction() throws Exception {
final String uri = helper.getBaseUrl() + "/flow/history/1";
ClientResponse response;
// the action does not exist... all users should return 403
// read
response = helper.getReadUser().testGet(uri);
assertEquals(403, response.getStatus());
// read/write
response = helper.getReadWriteUser().testGet(uri);
assertEquals(403, response.getStatus());
// write
response = helper.getWriteUser().testGet(uri);
assertEquals(403, response.getStatus());
// none
response = helper.getNoneUser().testGet(uri);
assertEquals(403, response.getStatus());
}
/**
* Test get action.
*
* @throws Exception exception
*/
@Test
public void testGetComponentHistory() throws Exception {
helper.testGenericGetUri(helper.getBaseUrl() + "/flow/history/components/my-component");
}
public void testComponentSpecificGetUri(final String uri) throws Exception {
ClientResponse response;
// read
response = helper.getReadUser().testGet(uri);
assertEquals(404, response.getStatus());
// read/write
response = helper.getReadWriteUser().testGet(uri);
assertEquals(404, response.getStatus());
// write
response = helper.getWriteUser().testGet(uri);
assertEquals(403, response.getStatus());
// none
response = helper.getNoneUser().testGet(uri);
assertEquals(403, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
helper.cleanup();
}
}

Просмотреть файл

@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for funnels.
*/
public class FunnelAccessControlTest {
public class ITFunnelAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-funnels.xml";
@ -344,7 +344,7 @@ public class FunnelAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for input ports.
*/
public class InputPortAccessControlTest {
public class ITInputPortAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-input-ports.xml";
@ -388,7 +388,7 @@ public class InputPortAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for labels.
*/
public class LabelAccessControlTest {
public class ITLabelAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-labels.xml";
@ -385,7 +385,7 @@ public class LabelAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for output ports.
*/
public class OutputPortAccessControlTest {
public class ITOutputPortAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-output-ports.xml";
@ -388,7 +388,7 @@ public class OutputPortAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -46,7 +46,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for process groups.
*/
public class ProcessGroupAccessControlTest {
public class ITProcessGroupAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-processors.xml";
@ -388,7 +388,7 @@ public class ProcessGroupAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -47,7 +47,7 @@ import static org.junit.Assert.assertTrue;
/**
* Access control test for processors.
*/
public class ProcessorAccessControlTest {
public class ITProcessorAccessControl {
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-processors.xml";
@ -472,7 +472,7 @@ public class ProcessorAccessControlTest {
// create the entity body
final Map<String, String> queryParams = new HashMap<>();
queryParams.put("revision", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("version", String.valueOf(entity.getRevision().getVersion()));
queryParams.put("clientId", clientId);
// perform the request

Просмотреть файл

@ -1,983 +0,0 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.accesscontrol;
import com.sun.jersey.api.client.ClientResponse;
import org.apache.nifi.integration.NiFiWebApiTest;
import org.apache.nifi.integration.util.NiFiTestServer;
import org.apache.nifi.integration.util.NiFiTestUser;
import org.apache.nifi.nar.ExtensionManager;
import org.apache.nifi.nar.NarClassLoaders;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.api.dto.FlowSnippetDTO;
import org.apache.nifi.web.api.dto.ProcessGroupDTO;
import org.apache.nifi.web.api.dto.RevisionDTO;
import org.apache.nifi.web.api.entity.AuthorityEntity;
import org.apache.nifi.web.api.entity.BannerEntity;
import org.apache.nifi.web.api.entity.ConnectionEntity;
import org.apache.nifi.web.api.entity.ConnectionsEntity;
import org.apache.nifi.web.api.entity.ControllerConfigurationEntity;
import org.apache.nifi.web.api.entity.InputPortsEntity;
import org.apache.nifi.web.api.entity.LabelEntity;
import org.apache.nifi.web.api.entity.LabelsEntity;
import org.apache.nifi.web.api.entity.OutputPortsEntity;
import org.apache.nifi.web.api.entity.PortEntity;
import org.apache.nifi.web.api.entity.PrioritizerTypesEntity;
import org.apache.nifi.web.api.entity.ProcessGroupEntity;
import org.apache.nifi.web.api.entity.ProcessGroupsEntity;
import org.apache.nifi.web.api.entity.ProcessorEntity;
import org.apache.nifi.web.api.entity.ProcessorTypesEntity;
import org.apache.nifi.web.api.entity.ProcessorsEntity;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
/**
* Access control test for a read only user.
*/
@Ignore
public class ReadOnlyAccessControlTest {
public static final String READ_ONLY_USER_DN = "CN=Lastname Firstname Middlename monitor, OU=Unknown, OU=Unknown, OU=Unknown, O=Unknown, C=Unknown";
private static final String CLIENT_ID = "readonly-client-id";
private static final String CONTEXT_PATH = "/nifi-api";
private static final String FLOW_XML_PATH = "target/test-classes/access-control/flow-monitor.xml";
private static NiFiTestServer SERVER;
private static NiFiTestUser READ_ONLY_USER;
private static String BASE_URL;
@BeforeClass
public static void setup() throws Exception {
// configure the location of the nifi properties
File nifiPropertiesFile = new File("src/test/resources/access-control/nifi.properties");
System.setProperty(NiFiProperties.PROPERTIES_FILE_PATH, nifiPropertiesFile.getAbsolutePath());
// update the flow.xml property
NiFiProperties props = NiFiProperties.getInstance();
props.setProperty("nifi.flow.configuration.file", FLOW_XML_PATH);
// load extensions
NarClassLoaders.load(props);
ExtensionManager.discoverExtensions();
// start the server
SERVER = new NiFiTestServer("src/main/webapp", CONTEXT_PATH);
SERVER.startServer();
SERVER.loadFlow();
// get the base url
BASE_URL = SERVER.getBaseUrl() + CONTEXT_PATH;
// create the user
READ_ONLY_USER = new NiFiTestUser(SERVER.getClient(), READ_ONLY_USER_DN);
// populate the flow
NiFiWebApiTest.populateFlow(SERVER.getClient(), BASE_URL, CLIENT_ID);
}
// ----------------------------------------------
// PROCESS GROUPS
// ----------------------------------------------
/**
* Ensures the admin user can get a groups content.
*
* @throws Exception ex
*/
@Test
public void testGroupGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root";
// build the query params
Map<String, String> queryParams = new HashMap<>();
queryParams.put("verbose", Boolean.TRUE.toString());
ClientResponse response = READ_ONLY_USER.testGet(url, queryParams);
// ensure the request is successful
Assert.assertEquals(200, response.getStatus());
// extract the process group
ProcessGroupEntity processGroupEntity = response.getEntity(ProcessGroupEntity.class);
// ensure there is content
Assert.assertNotNull(processGroupEntity);
// extract the process group dto
ProcessGroupDTO processGroupDTO = processGroupEntity.getComponent();
FlowSnippetDTO processGroupContentsDTO = processGroupDTO.getContents();
// verify graph
Assert.assertEquals(2, processGroupContentsDTO.getProcessors().size());
Assert.assertEquals(1, processGroupContentsDTO.getConnections().size());
Assert.assertEquals(1, processGroupContentsDTO.getProcessGroups().size());
Assert.assertEquals(1, processGroupContentsDTO.getInputPorts().size());
Assert.assertEquals(1, processGroupContentsDTO.getOutputPorts().size());
Assert.assertEquals(1, processGroupContentsDTO.getLabels().size());
}
/**
* Verifies the admin user cannot update a group.
*
* @throws Exception ex
*/
@Test
public void testGroupPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root";
// create the entity body
Map<String, String> formData = new HashMap<>();
formData.put("revision", String.valueOf(NiFiTestUser.REVISION));
formData.put("clientId", CLIENT_ID);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, formData);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// CONTROLLER
// ----------------------------------------------
/**
* Verifies the read only user can retrieve the controller configuration.
*
* @throws Exception ex
*/
@Test
public void testControllerConfigurationGet() throws Exception {
String url = BASE_URL + "/controller/config";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is successful
Assert.assertEquals(200, response.getStatus());
// verify the results
ControllerConfigurationEntity entity = response.getEntity(ControllerConfigurationEntity.class);
Assert.assertNotNull(entity);
Assert.assertNotNull(entity.getConfig());
Assert.assertEquals(10, entity.getConfig().getMaxTimerDrivenThreadCount().intValue());
Assert.assertEquals(5, entity.getConfig().getMaxEventDrivenThreadCount().intValue());
Assert.assertEquals(30, entity.getConfig().getAutoRefreshIntervalSeconds().intValue());
}
/**
* Verifies the read only user cannot update the controller configuration.
*
* @throws Exception ex
*/
@Test
public void testControllerConfigurationPut() throws Exception {
String url = BASE_URL + "/controller/config";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ControllerConfigurationEntity entity = new ControllerConfigurationEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies the read only user cannot create a new flow archive.
*
* @throws Exception ex
*/
@Test
public void testFlowConfigurationArchivePost() throws Exception {
String url = BASE_URL + "/controller/archive";
// create the entity body
Map<String, String> formData = new HashMap<>();
formData.put("revision", String.valueOf(NiFiTestUser.REVISION));
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, formData);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies the read only user can retrieve his credentials.
*
* @throws Exception ex
*/
@Test
public void testAuthoritiesGet() throws Exception {
String url = BASE_URL + "/controller/authorities";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is successful
Assert.assertEquals(200, response.getStatus());
// verify the result
AuthorityEntity entity = response.getEntity(AuthorityEntity.class);
Assert.assertNotNull(entity);
Assert.assertNotNull(entity.getAuthorities());
Assert.assertEquals(1, entity.getAuthorities().size());
Assert.assertEquals("ROLE_MONITOR", entity.getAuthorities().toArray()[0]);
}
/**
* Verifies the read only user can retrieve the banners.
*
* @throws Exception ex
*/
@Test
public void testBannersGet() throws Exception {
String url = BASE_URL + "/controller/banners";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is successful
Assert.assertEquals(200, response.getStatus());
// verify the result
BannerEntity entity = response.getEntity(BannerEntity.class);
Assert.assertNotNull(entity);
Assert.assertNotNull(entity.getBanners());
Assert.assertEquals("TEST BANNER", entity.getBanners().getHeaderText());
Assert.assertEquals("TEST BANNER", entity.getBanners().getFooterText());
}
/**
* Verifies the read only user can retrieve the processor types.
*
* @throws Exception ex
*/
@Test
public void testProcessorTypesGet() throws Exception {
String url = BASE_URL + "/controller/processor-types";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is successful
Assert.assertEquals(200, response.getStatus());
// verify the result
ProcessorTypesEntity entity = response.getEntity(ProcessorTypesEntity.class);
Assert.assertNotNull(entity);
Assert.assertNotNull(entity.getProcessorTypes());
Assert.assertFalse(entity.getProcessorTypes().isEmpty());
}
/**
* Verifies the read only user can retrieve the prioritizer types.
*
* @throws Exception ex
*/
@Test
public void testPrioritizerTypesGet() throws Exception {
String url = BASE_URL + "/controller/prioritizers";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is successful
Assert.assertEquals(200, response.getStatus());
// verify the result
PrioritizerTypesEntity entity = response.getEntity(PrioritizerTypesEntity.class);
Assert.assertNotNull(entity);
Assert.assertNotNull(entity.getPrioritizerTypes());
Assert.assertFalse(entity.getPrioritizerTypes().isEmpty());
}
// ----------------------------------------------
// PROCESS GROUP
// ----------------------------------------------
/**
* Verifies that the admin user can get process groups.
*
* @throws Exception ex
*/
@Test
public void testProcessorGroupsGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/process-group-references";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// get the response
ProcessGroupsEntity entity = response.getEntity(ProcessGroupsEntity.class);
// ensure the request was successful
Assert.assertEquals(200, response.getStatus());
Assert.assertNotNull(entity.getProcessGroups());
Assert.assertEquals(1, entity.getProcessGroups().size());
}
/**
* Verifies that the operator user cannot create new process groups.
*
* @throws Exception ex
*/
@Test
public void testProcessGroupPost() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/process-group-references";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ProcessGroupEntity entity = new ProcessGroupEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the operator user cannot update process group configuration.
*
* @throws Exception ex
*/
@Test
public void testProcessGroupPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/process-group-references/1";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ProcessGroupEntity entity = new ProcessGroupEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the operator user cannot delete process groups.
*
* @throws Exception ex
*/
@Test
public void testProcessGroupDelete() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/process-group-references/1";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// PROCESSOR
// ----------------------------------------------
/**
* Verifies that the admin user can get processors.
*
* @throws Exception ex
*/
@Test
public void testProcessorsGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/processors";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// get the response
ProcessorsEntity entity = response.getEntity(ProcessorsEntity.class);
// ensure the request was successful
Assert.assertEquals(200, response.getStatus());
Assert.assertNotNull(entity.getProcessors());
Assert.assertEquals(2, entity.getProcessors().size());
}
/**
* Verifies that the read only user cannot create new processors.
*
* @throws Exception ex
*/
@Test
public void testProcessorPost() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/processors";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ProcessorEntity entity = new ProcessorEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the read only user cannot create new processors.
*
* @throws Exception ex
*/
@Test
public void testProcessorPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/processors/1";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ProcessorEntity entity = new ProcessorEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the read only user cannot delete processors.
*
* @throws Exception ex
*/
@Test
public void testProcessorDelete() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/processors/1";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// CONNECTION
// ----------------------------------------------
/**
* Verifies that the admin user can get connections.
*
* @throws Exception ex
*/
@Test
public void testConnectionsGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/connections";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// get the response
ConnectionsEntity entity = response.getEntity(ConnectionsEntity.class);
// ensure the request was successful
Assert.assertEquals(200, response.getStatus());
Assert.assertNotNull(entity.getConnections());
Assert.assertEquals(1, entity.getConnections().size());
}
/**
* Verifies that the read only user cannot create connections.
*
* @throws Exception ex
*/
@Test
public void testConnectionPost() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/connections";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ConnectionEntity entity = new ConnectionEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the read only user cannot create connections.
*
* @throws Exception ex
*/
@Test
public void testConnectionPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/connections/1";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
ConnectionEntity entity = new ConnectionEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the read only user cannot delete connections.
*
* @throws Exception ex
*/
@Test
public void testConnectionDelete() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/connections/1";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// INPUT PORTS
// ----------------------------------------------
/**
* Verifies that the admin user can get input ports.
*
* @throws Exception ex
*/
@Test
public void testInputPortsGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/input-ports";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// get the response
InputPortsEntity entity = response.getEntity(InputPortsEntity.class);
// ensure the request was successful
Assert.assertEquals(200, response.getStatus());
Assert.assertNotNull(entity.getInputPorts());
Assert.assertEquals(1, entity.getInputPorts().size());
}
/**
* Verifies that the admin user cannot create input ports.
*
* @throws Exception ex
*/
@Test
public void testInputPortPost() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/input-ports";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
PortEntity entity = new PortEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the admin user cannot create input ports.
*
* @throws Exception ex
*/
@Test
public void testInputPortPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/input-ports/1";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
PortEntity entity = new PortEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the admin user cannot delete input ports.
*
* @throws Exception ex
*/
@Test
public void testInputPortDelete() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/input-ports/1";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// OUTPUT PORTS
// ----------------------------------------------
/**
* Verifies that the admin user can get output ports.
*
* @throws Exception ex
*/
@Test
public void testOutputPortsGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/output-ports";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// get the response
OutputPortsEntity entity = response.getEntity(OutputPortsEntity.class);
// ensure the request was successful
Assert.assertEquals(200, response.getStatus());
Assert.assertNotNull(entity.getOutputPorts());
Assert.assertEquals(1, entity.getOutputPorts().size());
}
/**
* Verifies that the admin user cannot create output ports.
*
* @throws Exception ex
*/
@Test
public void testOutputPortPost() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/output-ports";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
PortEntity entity = new PortEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the admin user cannot create input ports.
*
* @throws Exception ex
*/
@Test
public void testOutputPortPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/output-ports/1";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setClientId(CLIENT_ID);
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
PortEntity entity = new PortEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the admin user cannot delete output ports.
*
* @throws Exception ex
*/
@Test
public void testOutputPortDelete() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/output-ports/1";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// LABEL
// ----------------------------------------------
/**
* Verifies that the admin user can get input ports.
*
* @throws Exception ex
*/
@Test
public void testLabelsGet() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/labels";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// get the response
LabelsEntity entity = response.getEntity(LabelsEntity.class);
// ensure the request was successful
Assert.assertEquals(200, response.getStatus());
Assert.assertNotNull(entity.getLabels());
Assert.assertEquals(1, entity.getLabels().size());
}
/**
* Verifies that the read only user cannot create labels.
*
* @throws Exception ex
*/
@Test
public void testLabelPost() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/labels";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
LabelEntity entity = new LabelEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPost(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the read only user cannot create labels.
*
* @throws Exception ex
*/
@Test
public void testLabelPut() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/labels/1";
// create the revision
final RevisionDTO revision = new RevisionDTO();
revision.setVersion(NiFiTestUser.REVISION);
// create the entity body
LabelEntity entity = new LabelEntity();
entity.setRevision(revision);
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, entity);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies that the read only user cannot delete labels.
*
* @throws Exception ex
*/
@Test
public void testLabelDelete() throws Exception {
String url = BASE_URL + "/controller/process-groups/root/labels/1";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// HISTORY
// ----------------------------------------------
/**
* Tests the ability to retrieve the NiFi history.
*
* @throws Exception ex
*/
@Test
public void testHistoryGet() throws Exception {
String url = BASE_URL + "/controller/history";
Map<String, String> queryParams = new HashMap<>();
queryParams.put("offset", "1");
queryParams.put("count", "1");
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url, queryParams);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(200, response.getStatus());
}
/**
* Tests the ability to retrieve a specific action.
*
* @throws Exception ex
*/
@Test
public void testActionGet() throws Exception {
int nonExistentActionId = 98775;
String url = BASE_URL + "/controller/history/" + nonExistentActionId;
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(404, response.getStatus());
}
/**
* Verifies the read only user cannot purge history.
*
* @throws Exception ex
*/
@Test
public void testHistoryDelete() throws Exception {
String url = BASE_URL + "/controller/history";
// perform the request
ClientResponse response = READ_ONLY_USER.testDelete(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
// ----------------------------------------------
// USER
// ----------------------------------------------
/**
* Tests the ability to retrieve the NiFi users.
*
* @throws Exception ex
*/
@Test
public void testUsersGet() throws Exception {
String url = BASE_URL + "/controller/users";
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Tests the ability to retrieve a specific user.
*
* @throws Exception ex
*/
@Test
public void testUserGet() throws Exception {
int nonExistentUserId = 98775;
String url = BASE_URL + "/controller/users/" + nonExistentUserId;
// perform the request
ClientResponse response = READ_ONLY_USER.testGet(url);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
/**
* Verifies the admin user can update a person.
*
* @throws Exception ex
*/
@Test
public void testUserPut() throws Exception {
int nonExistentUserId = 98775;
String url = BASE_URL + "/controller/users/" + nonExistentUserId;
// create the form data
Map<String, String> formData = new HashMap<>();
formData.put("status", "DISABLED");
// perform the request
ClientResponse response = READ_ONLY_USER.testPut(url, formData);
// ensure the request is failed with a forbidden status code
Assert.assertEquals(403, response.getStatus());
}
@AfterClass
public static void cleanup() throws Exception {
// shutdown the server
if (SERVER != null) {
SERVER.shutdownServer();
}
SERVER = null;
// look for the flow.xml
File flow = new File(FLOW_XML_PATH);
if (flow.exists()) {
flow.delete();
}
}
}

Просмотреть файл

@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.nifi.integration.util;
import org.apache.nifi.authorization.AuthorizationRequest;
import org.apache.nifi.authorization.AuthorizationResult;
import org.apache.nifi.authorization.Authorizer;
import org.apache.nifi.authorization.AuthorizerConfigurationContext;
import org.apache.nifi.authorization.AuthorizerInitializationContext;
import org.apache.nifi.authorization.RequestAction;
import org.apache.nifi.authorization.exception.AuthorizationAccessException;
import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.resource.ResourceFactory;
/**
*
*/
public class NiFiFlowTestAuthorizer implements Authorizer {
public static final String NO_POLICY_COMPONENT_NAME = "No policies";
public static final String PROXY_DN = "CN=localhost, OU=Apache NiFi, O=Apache, L=Santa Monica, ST=CA, C=US";
public static final String NONE_USER_DN = "none@nifi";
public static final String READ_USER_DN = "read@nifi";
public static final String WRITE_USER_DN = "write@nifi";
public static final String READ_WRITE_USER_DN = "readwrite@nifi";
public static final String TOKEN_USER = "user@nifi";
/**
* Creates a new FileAuthorizationProvider.
*/
public NiFiFlowTestAuthorizer() {
}
@Override
public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
}
@Override
public void onConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
}
@Override
public AuthorizationResult authorize(AuthorizationRequest request) throws AuthorizationAccessException {
// allow proxy
if (ResourceFactory.getProxyResource().getIdentifier().equals(request.getResource().getIdentifier()) && PROXY_DN.equals(request.getIdentity())) {
return AuthorizationResult.approved();
}
// read access
if (READ_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity())) {
if (RequestAction.READ.equals(request.getAction())) {
return AuthorizationResult.approved();
}
}
// write access
if (WRITE_USER_DN.equals(request.getIdentity()) || READ_WRITE_USER_DN.equals(request.getIdentity())) {
if (RequestAction.WRITE.equals(request.getAction())) {
return AuthorizationResult.approved();
}
}
return AuthorizationResult.denied();
}
@Override
public void preDestruction() {
}
}

Просмотреть файл

@ -27,7 +27,7 @@ import org.apache.nifi.authorization.exception.AuthorizerCreationException;
import org.apache.nifi.authorization.resource.ResourceFactory;
/**
*
* Contains extra rules to convenience when in component based access control tests.
*/
public class NiFiTestAuthorizer implements Authorizer {
@ -63,7 +63,7 @@ public class NiFiTestAuthorizer implements Authorizer {
return AuthorizationResult.approved();
}
// allow flow
// allow flow for all users unless explicitly disable
if (ResourceFactory.getFlowResource().getIdentifier().equals(request.getResource().getIdentifier())) {
return AuthorizationResult.approved();
}

Просмотреть файл

@ -30,8 +30,6 @@ import java.util.Map;
*/
public class NiFiTestUser {
public static final long REVISION = 0L;
private final Client client;
private final String proxyDn;
@ -100,7 +98,7 @@ public class NiFiTestUser {
}
// get the builder
WebResource.Builder builder = addProxiedEntities(resource.accept(MediaType.APPLICATION_JSON));
WebResource.Builder builder = addProxiedEntities(resource.getRequestBuilder());
// append any headers
if (headers != null && !headers.isEmpty()) {
@ -147,7 +145,7 @@ public class NiFiTestUser {
*/
public ClientResponse testPostWithHeaders(String url, Object entity, Map<String, String> headers) throws Exception {
// get the resource
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON));
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).type(MediaType.APPLICATION_JSON));
// include the request entity
if (entity != null) {
@ -235,7 +233,7 @@ public class NiFiTestUser {
}
// get the resource
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED));
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).type(MediaType.APPLICATION_FORM_URLENCODED));
// add the form data if necessary
if (!entity.isEmpty()) {
@ -276,7 +274,7 @@ public class NiFiTestUser {
*/
public ClientResponse testPutWithHeaders(String url, Object entity, Map<String, String> headers) throws Exception {
// get the resource
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON));
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).type(MediaType.APPLICATION_JSON));
// include the request entity
if (entity != null) {
@ -323,7 +321,7 @@ public class NiFiTestUser {
}
// get the resource
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED));
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).type(MediaType.APPLICATION_FORM_URLENCODED));
// add the form data if necessary
if (!entity.isEmpty()) {
@ -362,7 +360,7 @@ public class NiFiTestUser {
*/
public ClientResponse testDeleteWithHeaders(String url, Map<String, String> headers) throws Exception {
// get the resource
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).accept(MediaType.APPLICATION_JSON));
WebResource.Builder resourceBuilder = addProxiedEntities(client.resource(url).getRequestBuilder());
// append any headers
if (headers != null && !headers.isEmpty()) {
@ -395,7 +393,7 @@ public class NiFiTestUser {
}
// perform the request
return addProxiedEntities(resource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_FORM_URLENCODED)).delete(ClientResponse.class);
return addProxiedEntities(resource.type(MediaType.APPLICATION_FORM_URLENCODED)).delete(ClientResponse.class);
}
/**

Просмотреть файл

@ -83,7 +83,7 @@ public class TestSiteToSiteResource {
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final Response response = resource.getController(req);
final Response response = resource.getSiteToSite(req);
ControllerEntity resultEntity = (ControllerEntity)response.getEntity();
@ -110,7 +110,7 @@ public class TestSiteToSiteResource {
final SiteToSiteResource resource = new SiteToSiteResource();
resource.setProperties(NiFiProperties.getInstance());
resource.setServiceFacade(serviceFacade);
final Response response = resource.getController(req);
final Response response = resource.getSiteToSite(req);
ControllerEntity resultEntity = (ControllerEntity)response.getEntity();

Просмотреть файл

@ -12,4 +12,5 @@
# 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.
org.apache.nifi.integration.util.NiFiTestAuthorizer
org.apache.nifi.integration.util.NiFiTestAuthorizer
org.apache.nifi.integration.util.NiFiFlowTestAuthorizer

Просмотреть файл

@ -21,4 +21,8 @@
<identifier>test-provider</identifier>
<class>org.apache.nifi.integration.util.NiFiTestAuthorizer</class>
</authorizer>
<authorizer>
<identifier>flow-test-provider</identifier>
<class>org.apache.nifi.integration.util.NiFiFlowTestAuthorizer</class>
</authorizer>
</authorizers>

Просмотреть файл

@ -956,6 +956,11 @@
// build the controller service entity
var controllerServiceEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0,
}
}),
'component': {
'type': newControllerServiceType
}

Просмотреть файл

@ -74,6 +74,11 @@ nf.ng.FunnelComponent = function (serviceProvider) {
*/
createFunnel: function(pt) {
var outputPortEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'position': {
'x': pt.x,

Просмотреть файл

@ -28,6 +28,11 @@ nf.ng.GroupComponent = function (serviceProvider) {
*/
var createGroup = function (groupName, pt) {
var processGroupEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'name': groupName,
'position': {

Просмотреть файл

@ -28,6 +28,11 @@ nf.ng.InputPortComponent = function (serviceProvider) {
*/
var createInputPort = function (portName, pt) {
var inputPortEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'name': portName,
'position': {

Просмотреть файл

@ -74,6 +74,11 @@ nf.ng.LabelComponent = function (serviceProvider) {
*/
createLabel: function(pt) {
var labelEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'width': nf.Label.config.width,
'height': nf.Label.config.height,

Просмотреть файл

@ -28,6 +28,11 @@ nf.ng.OutputPortComponent = function (serviceProvider) {
*/
var createOutputPort = function (portName, pt) {
var outputPortEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'name': portName,
'position': {

Просмотреть файл

@ -202,6 +202,11 @@ nf.ng.ProcessorComponent = function (serviceProvider) {
*/
var createProcessor = function (name, processorType, pt) {
var processorEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'type': processorType,
'name': name,

Просмотреть файл

@ -28,6 +28,11 @@ nf.ng.RemoteProcessGroupComponent = function (serviceProvider) {
var createRemoteProcessGroup = function (pt) {
var remoteProcessGroupEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'targetUri': $('#new-remote-process-group-uri').val(),
'position': {

Просмотреть файл

@ -131,8 +131,8 @@ nf.Canvas = (function () {
kerberos: '../nifi-api/access/kerberos',
revision: '../nifi-api/flow/revision',
banners: '../nifi-api/flow/banners',
controllerConfig: '../nifi-api/controller/config',
cluster: '../nifi-api/cluster'
flowConfig: '../nifi-api/flow/config',
cluster: '../nifi-api/controller/cluster'
}
};
@ -811,7 +811,7 @@ nf.Canvas = (function () {
// get the controller config to register the status poller
var configXhr = $.ajax({
type: 'GET',
url: config.urls.controllerConfig,
url: config.urls.flowConfig,
dataType: 'json'
});
@ -842,7 +842,7 @@ nf.Canvas = (function () {
nf.Canvas.CANVAS_OFFSET = canvasContainer.offset().top;
// get the config details
var configDetails = configResponse.config;
var configDetails = configResponse.flowConfiguration;
// when both request complete, load the application
isClusteredRequest.done(function () {

Просмотреть файл

@ -864,6 +864,11 @@ nf.ConnectionConfiguration = (function () {
if (validateSettings()) {
var connectionEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'name': connectionName,
'source': {

Просмотреть файл

@ -1691,7 +1691,7 @@ nf.ControllerService = (function () {
// get the controller service history
var loadHistory = $.ajax({
type: 'GET',
url: '../nifi-api/history/controller-services/' + encodeURIComponent(controllerServiceEntity.id),
url: '../nifi-api/flow/history/components/' + encodeURIComponent(controllerServiceEntity.id),
dataType: 'json'
});
@ -1856,7 +1856,7 @@ nf.ControllerService = (function () {
// get the controller service history
var loadHistory = $.ajax({
type: 'GET',
url: '../nifi-api/history/controller-services/' + encodeURIComponent(controllerServiceEntity.id),
url: '../nifi-api/flow/history/components/' + encodeURIComponent(controllerServiceEntity.id),
dataType: 'json'
});

Просмотреть файл

@ -218,6 +218,11 @@ nf.ControllerServices = (function () {
var addControllerService = function (controllerServicesUri, serviceTable, controllerServiceType) {
// build the controller service entity
var controllerServiceEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'type': controllerServiceType
}

Просмотреть файл

@ -576,7 +576,7 @@ nf.ProcessorConfiguration = (function () {
// get the processor history
requests.push($.ajax({
type: 'GET',
url: '../nifi-api/history/processors/' + encodeURIComponent(processor.id),
url: '../nifi-api/flow/history/components/' + encodeURIComponent(processor.id),
dataType: 'json'
}));

Просмотреть файл

@ -392,7 +392,7 @@ nf.ReportingTask = (function () {
// get the reporting task history
var loadHistory = $.ajax({
type: 'GET',
url: '../nifi-api/history/reporting-tasks/' + encodeURIComponent(reportingTaskEntity.id),
url: '../nifi-api/flow/history/components/' + encodeURIComponent(reportingTaskEntity.id),
dataType: 'json'
});
@ -595,7 +595,7 @@ nf.ReportingTask = (function () {
// get the reporting task history
var loadHistory = $.ajax({
type: 'GET',
url: '../nifi-api/history/reporting-tasks/' + encodeURIComponent(reportingTaskEntity.id),
url: '../nifi-api/flow/history/components/' + encodeURIComponent(reportingTaskEntity.id),
dataType: 'json'
});

Просмотреть файл

@ -67,7 +67,7 @@ nf.Settings = (function () {
'version': version
}
}),
'config': configuration
'controllerConfiguration': configuration
};
// save the new configuration details
@ -358,6 +358,11 @@ nf.Settings = (function () {
var addReportingTask = function (reportingTaskType) {
// build the reporting task entity
var reportingTaskEntity = {
'revision': nf.Client.getRevision({
'revision': {
'version': 0
}
}),
'component': {
'type': reportingTaskType
}
@ -836,12 +841,12 @@ nf.Settings = (function () {
dataType: 'json'
}).done(function (response) {
// update the current time
$('#settings-last-refreshed').text(response.config.currentTime);
$('#settings-last-refreshed').text(response.currentTime);
if (response.accessPolicy.canWrite) {
// populate the settings
$('#maximum-timer-driven-thread-count-field').removeClass('unset').val(response.config.maxTimerDrivenThreadCount);
$('#maximum-event-driven-thread-count-field').removeClass('unset').val(response.config.maxEventDrivenThreadCount);
$('#maximum-timer-driven-thread-count-field').removeClass('unset').val(response.controllerConfiguration.maxTimerDrivenThreadCount);
$('#maximum-event-driven-thread-count-field').removeClass('unset').val(response.controllerConfiguration.maxEventDrivenThreadCount);
setEditable(true);
@ -852,8 +857,8 @@ nf.Settings = (function () {
} else {
if (response.accessPolicy.canRead) {
// populate the settings
$('#read-only-maximum-timer-driven-thread-count-field').removeClass('unset').text(response.config.maxTimerDrivenThreadCount);
$('#read-only-maximum-event-driven-thread-count-field').removeClass('unset').text(response.config.maxEventDrivenThreadCount);
$('#read-only-maximum-timer-driven-thread-count-field').removeClass('unset').text(response.controllerConfiguration.maxTimerDrivenThreadCount);
$('#read-only-maximum-event-driven-thread-count-field').removeClass('unset').text(response.controllerConfiguration.maxEventDrivenThreadCount);
} else {
setUnauthorizedText();
}

Просмотреть файл

@ -29,7 +29,7 @@ nf.ClusterTable = (function () {
},
urls: {
cluster: '../nifi-api/cluster',
nodes: '../nifi-api/cluster/nodes'
nodes: '../nifi-api/controller/cluster/nodes'
}
};

Просмотреть файл

@ -27,7 +27,7 @@ nf.CountersTable = (function () {
filterList: 'counters-filter-list'
},
urls: {
counters: '../nifi-api/controller/counters'
counters: '../nifi-api/counters'
}
};

Просмотреть файл

@ -123,7 +123,7 @@
// perform query...
var xhr = $.ajax({
type: 'GET',
url: '../nifi-api/history',
url: '../nifi-api/flow/history',
data: query,
dataType: 'json'
}).done(function (response) {

Просмотреть файл

@ -31,7 +31,7 @@ nf.HistoryTable = (function () {
hidden: 'hidden'
},
urls: {
history: '../nifi-api/history'
history: '../nifi-api/controller/history'
}
};

Просмотреть файл

@ -187,7 +187,7 @@ nf.ProcessorDetails = (function () {
// get the processor history
var getProcessorHistory = $.ajax({
type: 'GET',
url: '../nifi-api/history/processors/' + encodeURIComponent(processorId),
url: '../nifi-api/flow/history/components/' + encodeURIComponent(processorId),
dataType: 'json'
}).done(function (response) {
var processorHistory = response.componentHistory;

Просмотреть файл

@ -35,7 +35,7 @@ nf.ProvenanceTable = (function () {
searchOptions: '../nifi-api/provenance/search-options',
replays: '../nifi-api/provenance/replays',
provenance: '../nifi-api/provenance',
cluster: '../nifi-api/cluster',
cluster: '../nifi-api/controller/cluster',
d3Script: 'js/d3/d3.min.js',
lineageScript: 'js/nf/provenance/nf-provenance-lineage.js',
uiExtensionToken: '../nifi-api/access/ui-extension-token',

Просмотреть файл

@ -34,7 +34,7 @@ nf.Provenance = (function () {
*/
var config = {
urls: {
cluster: '../nifi-api/cluster',
cluster: '../nifi-api/controller/cluster',
banners: '../nifi-api/flow/banners',
about: '../nifi-api/flow/about',
authorities: '../nifi-api/flow/authorities'

Просмотреть файл

@ -21,7 +21,7 @@ nf.ClusterSearch = (function () {
var config = {
search: 'Search nodes',
urls: {
clusterSearch: '../nifi-api/cluster/search-results'
clusterSearch: '../nifi-api/controller/cluster/search-results'
}
};

Просмотреть файл

@ -29,7 +29,7 @@ nf.SummaryTable = (function () {
api: '../nifi-api',
status: '../nifi-api/flow/process-groups/root/status',
systemDiagnostics: '../nifi-api/system-diagnostics',
controllerConfig: '../nifi-api/controller/config'
flowConfig: '../nifi-api/flow/config'
}
};
@ -2715,10 +2715,10 @@ nf.SummaryTable = (function () {
// get the controller config to get the server offset
var configRequest = $.ajax({
type: 'GET',
url: config.urls.controllerConfig,
url: config.urls.flowConfig,
dataType: 'json'
}).done(function (configResponse) {
var configDetails = configResponse.config;
var configDetails = configResponse.flowConfiguration;
// initialize the chart
nf.StatusHistory.init(configDetails.timeOffset);

Просмотреть файл

@ -68,7 +68,7 @@ nf.Summary = (function () {
urls: {
banners: '../nifi-api/flow/banners',
about: '../nifi-api/flow/about',
cluster: '../nifi-api/cluster'
cluster: '../nifi-api/controller/cluster'
}
};

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше