зеркало из https://github.com/syncfusion/nifi.git
NIFI-1554:
- 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:
Родитель
f0662a24ef
Коммит
f0811ca45a
|
@ -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'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче