You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by jo...@apache.org on 2016/07/14 22:33:08 UTC
[02/10] nifi git commit: NIFI-1896 This closes #650. Refactored
nifi-api into nifi-framework-api and other locations. The nifi-api is
specific to that which is needed for intended extension points.
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDescriptor.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDescriptor.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDescriptor.java
new file mode 100644
index 0000000..9412ee1
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDescriptor.java
@@ -0,0 +1,93 @@
+/*
+ * 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 java.util.Map;
+
+public class ComponentDescriptor {
+
+ private final String name;
+ private final String displayName;
+ private final String description;
+ private final String defaultValue;
+ private final Map<String,String> allowableValues;
+
+ private ComponentDescriptor(Builder builder){
+ this.name = builder.name;
+ this.displayName = builder.displayName;
+ this.description = builder.description;
+ this.defaultValue = builder.defaultValue;
+ this.allowableValues = builder.allowableValues;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public String getDefaultValue() {
+ return defaultValue;
+ }
+
+ public Map<String,String> getAllowableValues() {
+ return allowableValues;
+ }
+
+ public static final class Builder{
+ private String name;
+ private String displayName;
+ private String description;
+ private String defaultValue;
+ private Map<String,String> allowableValues;
+
+ public Builder name(String name){
+ this.name = name;
+ return this;
+ }
+
+ public Builder displayName(String displayName){
+ this.displayName = displayName;
+ return this;
+ }
+
+ public Builder description(String description){
+ this.description = description;
+ return this;
+ }
+
+ public Builder defaultValue(String defaultValue){
+ this.defaultValue = defaultValue;
+ return this;
+ }
+
+ public Builder allowableValues(Map<String,String> allowableValues){
+ this.allowableValues = allowableValues;
+ return this;
+ }
+
+ public ComponentDescriptor build(){
+ return new ComponentDescriptor(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java
new file mode 100644
index 0000000..9d163e4
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/ComponentDetails.java
@@ -0,0 +1,163 @@
+/*
+ * 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 java.util.Collection;
+import java.util.Map;
+
+/**
+ * Details about a given component. Contains configuration and current
+ * validation errors.
+ */
+public class ComponentDetails {
+
+ private final String id;
+ private final String name;
+ private final String type;
+ private final String state;
+ private final String annotationData;
+ private final Map<String, String> properties;
+ private final Map<String, ComponentDescriptor> descriptors;
+
+ private final Collection<String> validationErrors;
+
+ private ComponentDetails(final Builder builder) {
+ this.id = builder.id;
+ this.name = builder.name;
+ this.type = builder.type;
+ this.state = builder.state;
+ this.annotationData = builder.annotationData;
+ this.properties = builder.properties;
+ this.descriptors = builder.descriptors;
+ this.validationErrors = builder.validationErrors;
+
+ }
+
+ /**
+ * @return component id
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @return component name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return component type
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * @return component state
+ */
+ public String getState() {
+ return state;
+ }
+
+ /**
+ * @return component's annotation data
+ */
+ public String getAnnotationData() {
+ return annotationData;
+ }
+
+ /**
+ * @return Mapping of component properties
+ */
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+
+ /**
+ * @return Mapping of component descriptors
+ */
+ public Map<String,ComponentDescriptor> getDescriptors(){
+ return descriptors;
+ }
+
+ /**
+ * @return Current validation errors for the component
+ */
+ public Collection<String> getValidationErrors() {
+ return validationErrors;
+ }
+
+ public static final class Builder {
+
+ private String id;
+ private String name;
+ private String type;
+ private String state;
+ private String annotationData;
+ private Map<String, String> properties;
+ private Map<String,ComponentDescriptor> descriptors;
+
+ private Collection<String> validationErrors;
+
+ public Builder id(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder name(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder type(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder state(final String state) {
+ this.state = state;
+ return this;
+ }
+
+ public Builder annotationData(final String annotationData) {
+ this.annotationData = annotationData;
+ return this;
+ }
+
+ public Builder properties(final Map<String, String> properties) {
+ this.properties = properties;
+ return this;
+ }
+
+ public Builder validateErrors(final Collection<String> validationErrors) {
+ this.validationErrors = validationErrors;
+ return this;
+ }
+
+ public Builder descriptors(final Map<String,ComponentDescriptor> descriptors){
+ this.descriptors = descriptors;
+ return this;
+ }
+
+ public ComponentDetails build() {
+ return new ComponentDetails(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
new file mode 100644
index 0000000..96f2abf
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
@@ -0,0 +1,125 @@
+/*
+ * 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;
+
+/**
+ * An action that represents the configuration of a component.
+ */
+public class ConfigurationAction {
+
+ private final String id;
+ private final String name;
+ private final String type;
+ private final String field;
+ private final String previousValue;
+ private final String value;
+
+ private ConfigurationAction(final Builder builder) {
+ this.id = builder.id;
+ this.name = builder.name;
+ this.type = builder.type;
+ this.field = builder.field;
+ this.previousValue = builder.previousValue;
+ this.value = builder.value;
+ }
+
+ /**
+ * @return id of the component being modified
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * @return name of the component being modified
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * @return type of the component being modified
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * @return the name of the field, property, etc that has been modified
+ */
+ public String getField() {
+ return field;
+ }
+
+ /**
+ * @return the previous value
+ */
+ public String getPreviousValue() {
+ return previousValue;
+ }
+
+ /**
+ * @return the new value
+ */
+ public String getValue() {
+ return value;
+ }
+
+ public static class Builder {
+
+ private String id;
+ private String name;
+ private String type;
+ private String field;
+ private String previousValue;
+ private String value;
+
+ public Builder id(final String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder name(final String name) {
+ this.name = name;
+ return this;
+ }
+
+ public Builder type(final String type) {
+ this.type = type;
+ return this;
+ }
+
+ public Builder field(final String field) {
+ this.field = field;
+ return this;
+ }
+
+ public Builder previousValue(final String previousValue) {
+ this.previousValue = previousValue;
+ return this;
+ }
+
+ public Builder value(final String value) {
+ this.value = value;
+ return this;
+ }
+
+ public ConfigurationAction build() {
+ return new ConfigurationAction(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/InvalidRevisionException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/InvalidRevisionException.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/InvalidRevisionException.java
new file mode 100644
index 0000000..8e04f69
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/InvalidRevisionException.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+/**
+ * Exception indicating that the client has included an old revision in their
+ * request.
+ */
+@SuppressWarnings("serial")
+public class InvalidRevisionException extends RuntimeException {
+
+ public InvalidRevisionException(String message) {
+ super(message);
+ }
+
+ public InvalidRevisionException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
new file mode 100644
index 0000000..5082af2
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationContext.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apache.nifi.controller.ControllerService;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * NiFi web context providing limited access to dataflow configuration for
+ * component custom UIs.
+ */
+public interface NiFiWebConfigurationContext {
+
+ /**
+ * @param serviceIdentifier of the controller service
+ * @param componentId the id of the component that is referencing the controller service
+ * @return the ControllerService for the specified identifier. If a
+ * corresponding service cannot be found, null is returned. If this NiFi is
+ * clustered, the only services available will be those those availability
+ * is NCM only
+ */
+ ControllerService getControllerService(String serviceIdentifier, String componentId);
+
+ /**
+ * Provides a mechanism for custom UIs to save actions to appear in NiFi
+ * configuration history. Note all fields within each Action must be
+ * populated. Null values will result in a failure to insert the audit
+ * record. Since the saving to these actions is separate from the actual
+ * configuration change, a failure to insert here will just generate a
+ * warning log message. The recording of these actions typically happens
+ * after a configuration change is applied. Since those changes have already
+ * been applied to the flow, we cannot revert them because of a failure to
+ * insert an audit record.
+ *
+ * @param requestContext context of the request
+ * @param actions to save
+ * @throws IllegalArgumentException When the requestContext isn't fully
+ * populated or isn't appropriate for the given request
+ */
+ void saveActions(NiFiWebRequestContext requestContext, Collection<ConfigurationAction> actions);
+
+ /**
+ * @return the current user identity. The value may be a DN, an email, a username, or any string that identities the user. Returns null if no user is found
+ */
+ String getCurrentUserIdentity();
+
+ /**
+ * Sets the annotation data for the underlying component.
+ *
+ * @param configurationContext config context
+ * @param annotationData the data
+ * @param properties component properties
+ * @return the configuration for the underlying component
+ * @throws ResourceNotFoundException if the underlying component does not
+ * exit
+ * @throws InvalidRevisionException if a revision other than the current
+ * revision is given
+ * @throws ClusterRequestException if the annotation data was unable to be
+ * set for the underlying component. This exception will only be thrown when
+ * operating in a cluster.
+ * @throws IllegalArgumentException When the requestContext isn't fully
+ * populated or isn't appropriate for the given request
+ */
+ ComponentDetails updateComponent(NiFiWebConfigurationRequestContext configurationContext, String annotationData, Map<String, String> properties)
+ throws ResourceNotFoundException, InvalidRevisionException, ClusterRequestException;
+
+
+ /**
+ * Gets the details for the underlying component (including configuration,
+ * validation errors, and annotation data).
+ *
+ * @param requestContext context of request
+ * @return the configuration for the underlying component
+ * @throws ResourceNotFoundException if the underlying component does not
+ * exit
+ * @throws ClusterRequestException if the underlying component was unable to
+ * be retrieved from the cluster. This exception will only be thrown when
+ * operating in a cluster.
+ * @throws IllegalArgumentException When the requestContext isn't fully
+ * populated or isn't appropriate for the given request
+ */
+ ComponentDetails getComponentDetails(NiFiWebRequestContext requestContext) throws ResourceNotFoundException, ClusterRequestException;
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationRequestContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationRequestContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationRequestContext.java
new file mode 100644
index 0000000..c75d9dc
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebConfigurationRequestContext.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * Contextual details required to make a configuration request from a UI
+ * extension.
+ */
+public interface NiFiWebConfigurationRequestContext extends NiFiWebRequestContext {
+
+ /**
+ * The revision to include in the request.
+ *
+ * @return the revision
+ */
+ Revision getRevision();
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebRequestContext.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebRequestContext.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebRequestContext.java
new file mode 100644
index 0000000..9dd44ab
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/NiFiWebRequestContext.java
@@ -0,0 +1,56 @@
+/*
+ * 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;
+
+/**
+ * Contextual details required to make a request from a UI extension.
+ */
+public interface NiFiWebRequestContext {
+
+ /**
+ * @return the type of UI extension is making the request
+ */
+ UiExtensionType getExtensionType();
+
+ /**
+ * The request protocol scheme (http or https). When scheme is https, the
+ * X509Certificate can be used for subsequent remote requests.
+ *
+ * @return the protocol scheme
+ */
+ String getScheme();
+
+ /**
+ * The id of the component.
+ *
+ * @return the ID
+ */
+ String getId();
+
+ /**
+ * Returns the proxied entities chain. The format of the chain is as
+ * follows:
+ *
+ * <code>
+ * <CN=original-proxied-entity><CN=first-proxy><CN=second-proxy>...
+ * </code>
+ *
+ * @return the proxied entities chain or null if no chain
+ */
+ String getProxiedEntitiesChain();
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/ResourceNotFoundException.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/ResourceNotFoundException.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/ResourceNotFoundException.java
new file mode 100644
index 0000000..b2f2e57
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/ResourceNotFoundException.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * Exception indicating that the desired resource was not found.
+ */
+@SuppressWarnings("serial")
+public class ResourceNotFoundException extends RuntimeException {
+
+ public ResourceNotFoundException(String message) {
+ super(message);
+ }
+
+ public ResourceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/Revision.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/Revision.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/Revision.java
new file mode 100644
index 0000000..d768faa
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/Revision.java
@@ -0,0 +1,129 @@
+/*
+ * 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 java.io.Serializable;
+
+/**
+ * A model object representing a revision. Equality is defined as matching
+ * component ID and either a matching version number or matching non-empty client IDs.
+ *
+ * @Immutable
+ * @Threadsafe
+ */
+public class Revision implements Serializable {
+ private static final long serialVersionUID = 988658790374170022L;
+
+ /**
+ * the version number
+ */
+ private final Long version;
+
+ /**
+ * the client ID
+ */
+ private final String clientId;
+
+ /**
+ * the ID of the component that this revision belongs to, or <code>null</code> if
+ * the revision is not attached to any component but rather is attached to the entire
+ * data flow.
+ */
+ private final String componentId;
+
+ 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.");
+ }
+
+ this.version = version;
+ this.clientId = clientId;
+ this.componentId = componentId;
+ }
+
+ public String getClientId() {
+ return clientId;
+ }
+
+ public Long getVersion() {
+ return version;
+ }
+
+ public String getComponentId() {
+ 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) {
+ return false;
+ }
+ if (obj == this) {
+ return true;
+ }
+
+ if ((obj instanceof Revision) == false) {
+ return false;
+ }
+
+ Revision thatRevision = (Revision) obj;
+ // ensure that component ID's are the same (including null)
+ if (thatRevision.getComponentId() == null && getComponentId() != null) {
+ return false;
+ }
+ if (thatRevision.getComponentId() != null && getComponentId() == null) {
+ return false;
+ }
+ if (thatRevision.getComponentId() != null && !thatRevision.getComponentId().equals(getComponentId())) {
+ return false;
+ }
+
+ if (this.version != null && this.version.equals(thatRevision.version)) {
+ return true;
+ } else {
+ return clientId != null && !clientId.trim().isEmpty() && clientId.equals(thatRevision.getClientId());
+ }
+
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 5;
+ hash = 59 * hash + (this.componentId != null ? this.componentId.hashCode() : 0);
+ hash = 59 * hash + (this.version != null ? this.version.hashCode() : 0);
+ hash = 59 * hash + (this.clientId != null ? this.clientId.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + version + ", " + clientId + ", " + componentId + ']';
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/UiExtensionType.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/UiExtensionType.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/UiExtensionType.java
new file mode 100644
index 0000000..e3b0f8a
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/UiExtensionType.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+/**
+ * Types of UI extensions. Since a UI extension could support multiple types of
+ * custom UIs it will need to include the type so the framework can appropriate
+ * understand and process the request (recording actions in the audit database,
+ * replicating a request throughout the cluster to the appropriate endpoints,
+ * etc).
+ */
+public enum UiExtensionType {
+
+ ContentViewer,
+ ProcessorConfiguration,
+ ControllerServiceConfiguration,
+ ReportingTaskConfiguration
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/main/java/org/apache/nifi/web/ViewableContent.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/main/java/org/apache/nifi/web/ViewableContent.java b/nifi-framework-api/src/main/java/org/apache/nifi/web/ViewableContent.java
new file mode 100644
index 0000000..d506b5d
--- /dev/null
+++ b/nifi-framework-api/src/main/java/org/apache/nifi/web/ViewableContent.java
@@ -0,0 +1,71 @@
+/*
+ * 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 java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Interface for obtaining content from the NiFi content repository.
+ */
+public interface ViewableContent {
+
+ public static final String CONTENT_REQUEST_ATTRIBUTE = "org.apache.nifi.web.content";
+
+ public enum DisplayMode {
+
+ Original,
+ Formatted,
+ Hex;
+ }
+
+ /**
+ * @return stream to the viewable content. The data stream can only be read once
+ * so an extension can call this method or getContent
+ */
+ InputStream getContentStream();
+
+ /**
+ * @return the content as a string. The data stream can only be read once so an
+ * extension can call this method or getContentStream
+ * @throws java.io.IOException if unable to read content
+ */
+ String getContent() throws IOException;
+
+ /**
+ * @return the desired display mode. If the mode is Hex the framework will
+ * handle generating the mark up. The only values that an extension will see
+ * is Original or Formatted
+ */
+ DisplayMode getDisplayMode();
+
+ /**
+ * @return contents file name
+ */
+ String getFileName();
+
+ /**
+ * @return mime type of the content, value is lowercase and stripped of all parameters if there were any
+ */
+ String getContentType();
+
+ /**
+ * @return unchanged mime type of the content
+ */
+ String getRawContentType();
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
new file mode 100644
index 0000000..b173d3d
--- /dev/null
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAbstractPolicyBasedAuthorizer.java
@@ -0,0 +1,447 @@
+/*
+ * 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.authorization;
+
+import org.apache.nifi.authorization.exception.AuthorizationAccessException;
+import org.apache.nifi.authorization.exception.AuthorizerCreationException;
+import org.apache.nifi.authorization.exception.AuthorizerDestructionException;
+import org.junit.Assert;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+public class TestAbstractPolicyBasedAuthorizer {
+
+ static final Resource TEST_RESOURCE = new Resource() {
+ @Override
+ public String getIdentifier() {
+ return "1";
+ }
+
+ @Override
+ public String getName() {
+ return "resource1";
+ }
+ };
+
+ @Test
+ public void testApproveBasedOnUser() {
+ AbstractPolicyBasedAuthorizer authorizer = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ UsersAndAccessPolicies usersAndAccessPolicies = Mockito.mock(UsersAndAccessPolicies.class);
+ when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
+
+ final String userIdentifier = "userIdentifier1";
+ final String userIdentity = "userIdentity1";
+
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE.getIdentifier())
+ .addUser(userIdentifier)
+ .action(RequestAction.READ)
+ .build();
+
+ when(usersAndAccessPolicies.getAccessPolicy(TEST_RESOURCE.getIdentifier(), RequestAction.READ)).thenReturn(policy);
+
+ final User user = new User.Builder()
+ .identity(userIdentity)
+ .identifier(userIdentifier)
+ .build();
+
+ when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
+
+ final AuthorizationRequest request = new AuthorizationRequest.Builder()
+ .identity(userIdentity)
+ .resource(TEST_RESOURCE)
+ .action(RequestAction.READ)
+ .accessAttempt(true)
+ .anonymous(false)
+ .build();
+
+ assertEquals(AuthorizationResult.approved(), authorizer.authorize(request));
+ }
+
+ @Test
+ public void testApprovedBasedOnGroup() {
+ AbstractPolicyBasedAuthorizer authorizer = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ UsersAndAccessPolicies usersAndAccessPolicies = Mockito.mock(UsersAndAccessPolicies.class);
+ when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
+
+ final String userIdentifier = "userIdentifier1";
+ final String userIdentity = "userIdentity1";
+ final String groupIdentifier = "groupIdentifier1";
+
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE.getIdentifier())
+ .addGroup(groupIdentifier)
+ .action(RequestAction.READ)
+ .build();
+
+ when(usersAndAccessPolicies.getAccessPolicy(TEST_RESOURCE.getIdentifier(), RequestAction.READ)).thenReturn(policy);
+
+ final User user = new User.Builder()
+ .identity(userIdentity)
+ .identifier(userIdentifier)
+ .build();
+
+ when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
+
+ final Group group = new Group.Builder()
+ .identifier(groupIdentifier)
+ .name(groupIdentifier)
+ .addUser(user.getIdentifier())
+ .build();
+
+ when(usersAndAccessPolicies.getGroups(userIdentity)).thenReturn(Collections.singleton(group));
+
+ final AuthorizationRequest request = new AuthorizationRequest.Builder()
+ .identity(userIdentity)
+ .resource(TEST_RESOURCE)
+ .action(RequestAction.READ)
+ .accessAttempt(true)
+ .anonymous(false)
+ .build();
+
+ assertEquals(AuthorizationResult.approved(), authorizer.authorize(request));
+ }
+
+ @Test
+ public void testDeny() {
+ AbstractPolicyBasedAuthorizer authorizer = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ UsersAndAccessPolicies usersAndAccessPolicies = Mockito.mock(UsersAndAccessPolicies.class);
+ when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
+
+ final String userIdentifier = "userIdentifier1";
+ final String userIdentity = "userIdentity1";
+
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE.getIdentifier())
+ .addUser("NOT_USER_1")
+ .action(RequestAction.READ)
+ .build();
+
+ when(usersAndAccessPolicies.getAccessPolicy(TEST_RESOURCE.getIdentifier(), RequestAction.READ)).thenReturn(policy);
+
+ final User user = new User.Builder()
+ .identity(userIdentity)
+ .identifier(userIdentifier)
+ .build();
+
+ when(usersAndAccessPolicies.getUser(userIdentity)).thenReturn(user);
+
+ final AuthorizationRequest request = new AuthorizationRequest.Builder()
+ .identity(userIdentity)
+ .resource(TEST_RESOURCE)
+ .action(RequestAction.READ)
+ .accessAttempt(true)
+ .anonymous(false)
+ .build();
+
+ assertEquals(AuthorizationResult.denied().getResult(), authorizer.authorize(request).getResult());
+ }
+
+ @Test
+ public void testResourceNotFound() {
+ AbstractPolicyBasedAuthorizer authorizer = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ UsersAndAccessPolicies usersAndAccessPolicies = Mockito.mock(UsersAndAccessPolicies.class);
+ when(authorizer.getUsersAndAccessPolicies()).thenReturn(usersAndAccessPolicies);
+
+ when(usersAndAccessPolicies.getAccessPolicy(TEST_RESOURCE.getIdentifier(), RequestAction.READ)).thenReturn(null);
+
+ final AuthorizationRequest request = new AuthorizationRequest.Builder()
+ .identity("userIdentity")
+ .resource(TEST_RESOURCE)
+ .action(RequestAction.READ)
+ .accessAttempt(true)
+ .anonymous(false)
+ .build();
+
+ assertEquals(AuthorizationResult.resourceNotFound(), authorizer.authorize(request));
+ }
+
+ @Test
+ public void testGetFingerprint() {
+ // create the users, groups, and policies
+
+ User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
+ User user2 = new User.Builder().identifier("user-id-2").identity("user-2").build();
+
+ Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").addUser(user1.getIdentifier()).build();
+ Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").addUser(user2.getIdentifier()).build();
+
+ AccessPolicy policy1 = new AccessPolicy.Builder()
+ .identifier("policy-id-1")
+ .resource("resource1")
+ .action(RequestAction.READ)
+ .addUser(user1.getIdentifier())
+ .addUser(user2.getIdentifier())
+ .build();
+
+ AccessPolicy policy2 = new AccessPolicy.Builder()
+ .identifier("policy-id-2")
+ .resource("resource2")
+ .action(RequestAction.READ)
+ .addGroup(group1.getIdentifier())
+ .addGroup(group2.getIdentifier())
+ .addUser(user1.getIdentifier())
+ .addUser(user2.getIdentifier())
+ .build();
+
+ // create the first Authorizer
+
+ Set<Group> groups1 = new LinkedHashSet<>();
+ groups1.add(group1);
+ groups1.add(group2);
+
+ Set<User> users1 = new LinkedHashSet<>();
+ users1.add(user1);
+ users1.add(user2);
+
+ Set<AccessPolicy> policies1 = new LinkedHashSet<>();
+ policies1.add(policy1);
+ policies1.add(policy2);
+
+ AbstractPolicyBasedAuthorizer authorizer1 = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ when(authorizer1.getGroups()).thenReturn(groups1);
+ when(authorizer1.getUsers()).thenReturn(users1);
+ when(authorizer1.getAccessPolicies()).thenReturn(policies1);
+
+ // create the second Authorizer
+
+ Set<Group> groups2 = new LinkedHashSet<>();
+ groups2.add(group2);
+ groups2.add(group1);
+
+ Set<User> users2 = new LinkedHashSet<>();
+ users2.add(user2);
+ users2.add(user1);
+
+ Set<AccessPolicy> policies2 = new LinkedHashSet<>();
+ policies2.add(policy2);
+ policies2.add(policy1);
+
+ AbstractPolicyBasedAuthorizer authorizer2 = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ when(authorizer2.getGroups()).thenReturn(groups2);
+ when(authorizer2.getUsers()).thenReturn(users2);
+ when(authorizer2.getAccessPolicies()).thenReturn(policies2);
+
+ // compare the fingerprints
+
+ assertEquals(authorizer1.getFingerprint(), authorizer2.getFingerprint());
+
+ System.out.println(authorizer1.getFingerprint());
+ }
+
+ @Test
+ public void testInheritFingerprint() {
+
+ User user1 = new User.Builder().identifier("user-id-1").identity("user-1").build();
+ User user2 = new User.Builder().identifier("user-id-2").identity("user-2").build();
+
+ Group group1 = new Group.Builder().identifier("group-id-1").name("group-1").addUser(user1.getIdentifier()).build();
+ Group group2 = new Group.Builder().identifier("group-id-2").name("group-2").build();
+
+ AccessPolicy policy1 = new AccessPolicy.Builder()
+ .identifier("policy-id-1")
+ .resource("resource1")
+ .action(RequestAction.READ)
+ .addUser(user1.getIdentifier())
+ .addUser(user2.getIdentifier())
+ .build();
+
+ AccessPolicy policy2 = new AccessPolicy.Builder()
+ .identifier("policy-id-2")
+ .resource("resource2")
+ .action(RequestAction.READ)
+ .addGroup(group1.getIdentifier())
+ .addGroup(group2.getIdentifier())
+ .addUser(user1.getIdentifier())
+ .addUser(user2.getIdentifier())
+ .build();
+
+ // create the first Authorizer
+
+ Set<Group> groups1 = new LinkedHashSet<>();
+ groups1.add(group1);
+ groups1.add(group2);
+
+ Set<User> users1 = new LinkedHashSet<>();
+ users1.add(user1);
+ users1.add(user2);
+
+ Set<AccessPolicy> policies1 = new LinkedHashSet<>();
+ policies1.add(policy1);
+ policies1.add(policy2);
+
+ AbstractPolicyBasedAuthorizer authorizer1 = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ when(authorizer1.getGroups()).thenReturn(groups1);
+ when(authorizer1.getUsers()).thenReturn(users1);
+ when(authorizer1.getAccessPolicies()).thenReturn(policies1);
+
+ final String fingerprint1 = authorizer1.getFingerprint();
+
+ // make a second authorizer using the memory-backed implementation so we can inherit the fingerprint
+ // and then compute a new fingerprint to compare them
+ AbstractPolicyBasedAuthorizer authorizer2 = new MemoryPolicyBasedAuthorizer();
+ authorizer2.inheritFingerprint(fingerprint1);
+
+ // computer the fingerprint of the second authorizer and it should be the same as the first
+ final String fingerprint2 = authorizer2.getFingerprint();
+ assertEquals(fingerprint1, fingerprint2);
+
+ // all the sets should be equal now after inheriting
+ assertEquals(authorizer1.getUsers(), authorizer2.getUsers());
+ assertEquals(authorizer1.getGroups(), authorizer2.getGroups());
+ assertEquals(authorizer1.getAccessPolicies(), authorizer2.getAccessPolicies());
+ }
+
+ @Test
+ public void testEmptyAuthorizer() {
+ AbstractPolicyBasedAuthorizer authorizer = Mockito.mock(AbstractPolicyBasedAuthorizer.class);
+ when(authorizer.getGroups()).thenReturn(new HashSet<Group>());
+ when(authorizer.getUsers()).thenReturn(new HashSet<User>());
+ when(authorizer.getAccessPolicies()).thenReturn(new HashSet<AccessPolicy>());
+
+ final String fingerprint = authorizer.getFingerprint();
+ Assert.assertNotNull(fingerprint);
+ Assert.assertTrue(fingerprint.length() > 0);
+ }
+
+ /**
+ * An AbstractPolicyBasedAuthorizer that stores everything in memory.
+ */
+ private static final class MemoryPolicyBasedAuthorizer extends AbstractPolicyBasedAuthorizer {
+
+ private Set<Group> groups = new HashSet<>();
+ private Set<User> users = new HashSet<>();
+ private Set<AccessPolicy> policies = new HashSet<>();
+
+ @Override
+ public Group addGroup(Group group) throws AuthorizationAccessException {
+ groups.add(group);
+ return group;
+ }
+
+ @Override
+ public Group getGroup(String identifier) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Group updateGroup(Group group) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Group deleteGroup(Group group) throws AuthorizationAccessException {
+ groups.remove(group);
+ return group;
+ }
+
+ @Override
+ public Set<Group> getGroups() throws AuthorizationAccessException {
+ return groups;
+ }
+
+ @Override
+ public User addUser(User user) throws AuthorizationAccessException {
+ users.add(user);
+ return user;
+ }
+
+ @Override
+ public User getUser(String identifier) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public User getUserByIdentity(String identity) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public User updateUser(User user) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public User deleteUser(User user) throws AuthorizationAccessException {
+ users.remove(user);
+ return user;
+ }
+
+ @Override
+ public Set<User> getUsers() throws AuthorizationAccessException {
+ return users;
+ }
+
+ @Override
+ protected AccessPolicy doAddAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ policies.add(accessPolicy);
+ return accessPolicy;
+ }
+
+ @Override
+ public AccessPolicy getAccessPolicy(String identifier) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AccessPolicy updateAccessPolicy(AccessPolicy accessPolicy) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public AccessPolicy deleteAccessPolicy(AccessPolicy policy) throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Set<AccessPolicy> getAccessPolicies() throws AuthorizationAccessException {
+ return policies;
+ }
+
+ @Override
+ public UsersAndAccessPolicies getUsersAndAccessPolicies() throws AuthorizationAccessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public void initialize(AuthorizerInitializationContext initializationContext) throws AuthorizerCreationException {
+
+ }
+
+ @Override
+ public void doOnConfigured(AuthorizerConfigurationContext configurationContext) throws AuthorizerCreationException {
+
+ }
+
+ @Override
+ public void preDestruction() throws AuthorizerDestructionException {
+
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
new file mode 100644
index 0000000..c8a4452
--- /dev/null
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestAccessPolicy.java
@@ -0,0 +1,240 @@
+/*
+ * 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.authorization;
+
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestAccessPolicy {
+
+ static final String TEST_RESOURCE = "1";
+
+ @Test
+ public void testSimpleCreation() {
+ final String identifier = "1";
+ final String user1 = "user1";
+ final String user2 = "user2";
+ final RequestAction action = RequestAction.READ;
+
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier(identifier)
+ .resource(TEST_RESOURCE)
+ .addUser(user1)
+ .addUser(user2)
+ .action(action)
+ .build();
+
+ assertEquals(identifier, policy.getIdentifier());
+
+ assertNotNull(policy.getResource());
+ assertEquals(TEST_RESOURCE, policy.getResource());
+
+ assertNotNull(policy.getUsers());
+ assertEquals(2, policy.getUsers().size());
+ assertTrue(policy.getUsers().contains(user1));
+ assertTrue(policy.getUsers().contains(user2));
+
+ assertNotNull(policy.getAction());
+ assertEquals(RequestAction.READ, policy.getAction());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingIdentifier() {
+ new AccessPolicy.Builder()
+ .resource(TEST_RESOURCE)
+ .addUser("user1")
+ .action(RequestAction.READ)
+ .build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingResource() {
+ new AccessPolicy.Builder()
+ .identifier("1")
+ .addUser("user1")
+ .action(RequestAction.READ)
+ .build();
+ }
+
+ @Test
+ public void testMissingUsersAndGroups() {
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE)
+ .action(RequestAction.READ)
+ .build();
+
+ assertNotNull(policy);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingActions() {
+ new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE)
+ .addUser("user1")
+ .build();
+ }
+
+ @Test
+ public void testFromPolicy() {
+ final String identifier = "1";
+ final String user1 = "user1";
+ final String user2 = "user2";
+ final String group1 = "group1";
+ final String group2 = "group2";
+ final RequestAction action = RequestAction.READ;
+
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier(identifier)
+ .resource(TEST_RESOURCE)
+ .addUser(user1)
+ .addUser(user2)
+ .addGroup(group1)
+ .addGroup(group2)
+ .action(action)
+ .build();
+
+ assertEquals(identifier, policy.getIdentifier());
+
+ assertNotNull(policy.getResource());
+ assertEquals(TEST_RESOURCE, policy.getResource());
+
+ assertNotNull(policy.getUsers());
+ assertEquals(2, policy.getUsers().size());
+ assertTrue(policy.getUsers().contains(user1));
+ assertTrue(policy.getUsers().contains(user2));
+
+ assertNotNull(policy.getGroups());
+ assertEquals(2, policy.getGroups().size());
+ assertTrue(policy.getGroups().contains(group1));
+ assertTrue(policy.getGroups().contains(group2));
+
+ assertNotNull(policy.getAction());
+ assertEquals(RequestAction.READ, policy.getAction());
+
+ final AccessPolicy policy2 = new AccessPolicy.Builder(policy).build();
+ assertEquals(policy.getIdentifier(), policy2.getIdentifier());
+ assertEquals(policy.getResource(), policy2.getResource());
+ assertEquals(policy.getUsers(), policy2.getUsers());
+ assertEquals(policy.getAction(), policy2.getAction());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testFromPolicyAndChangeIdentifier() {
+ final AccessPolicy policy = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE)
+ .addUser("user1")
+ .action(RequestAction.READ)
+ .build();
+
+ new AccessPolicy.Builder(policy).identifier("2").build();
+ }
+
+ @Test
+ public void testAddRemoveClearUsers() {
+ final AccessPolicy.Builder builder = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE)
+ .addUser("user1")
+ .action(RequestAction.READ);
+
+ final AccessPolicy policy1 = builder.build();
+ assertEquals(1, policy1.getUsers().size());
+ assertTrue(policy1.getUsers().contains("user1"));
+
+ final Set<String> moreEntities = new HashSet<>();
+ moreEntities.add("user2");
+ moreEntities.add("user3");
+ moreEntities.add("user4");
+
+ final AccessPolicy policy2 = builder.addUsers(moreEntities).build();
+ assertEquals(4, policy2.getUsers().size());
+ assertTrue(policy2.getUsers().contains("user1"));
+ assertTrue(policy2.getUsers().contains("user2"));
+ assertTrue(policy2.getUsers().contains("user3"));
+ assertTrue(policy2.getUsers().contains("user4"));
+
+ final AccessPolicy policy3 = builder.removeUser("user3").build();
+ assertEquals(3, policy3.getUsers().size());
+ assertTrue(policy3.getUsers().contains("user1"));
+ assertTrue(policy3.getUsers().contains("user2"));
+ assertTrue(policy3.getUsers().contains("user4"));
+
+ final Set<String> removeEntities = new HashSet<>();
+ removeEntities.add("user1");
+ removeEntities.add("user4");
+
+ final AccessPolicy policy4 = builder.removeUsers(removeEntities).build();
+ assertEquals(1, policy4.getUsers().size());
+ assertTrue(policy4.getUsers().contains("user2"));
+
+
+ final AccessPolicy policy5 = builder.clearUsers().build();
+ assertEquals(0, policy5.getUsers().size());
+ }
+
+ @Test
+ public void testAddRemoveClearGroups() {
+ final AccessPolicy.Builder builder = new AccessPolicy.Builder()
+ .identifier("1")
+ .resource(TEST_RESOURCE)
+ .addGroup("group1")
+ .action(RequestAction.READ);
+
+ final AccessPolicy policy1 = builder.build();
+ assertEquals(1, policy1.getGroups().size());
+ assertTrue(policy1.getGroups().contains("group1"));
+
+ final Set<String> moreGroups = new HashSet<>();
+ moreGroups.add("group2");
+ moreGroups.add("group3");
+ moreGroups.add("group4");
+
+ final AccessPolicy policy2 = builder.addGroups(moreGroups).build();
+ assertEquals(4, policy2.getGroups().size());
+ assertTrue(policy2.getGroups().contains("group1"));
+ assertTrue(policy2.getGroups().contains("group2"));
+ assertTrue(policy2.getGroups().contains("group3"));
+ assertTrue(policy2.getGroups().contains("group4"));
+
+ final AccessPolicy policy3 = builder.removeGroup("group3").build();
+ assertEquals(3, policy3.getGroups().size());
+ assertTrue(policy3.getGroups().contains("group1"));
+ assertTrue(policy3.getGroups().contains("group2"));
+ assertTrue(policy3.getGroups().contains("group4"));
+
+ final Set<String> removeGroups = new HashSet<>();
+ removeGroups.add("group1");
+ removeGroups.add("group4");
+
+ final AccessPolicy policy4 = builder.removeGroups(removeGroups).build();
+ assertEquals(1, policy4.getGroups().size());
+ assertTrue(policy4.getGroups().contains("group2"));
+
+ final AccessPolicy policy5 = builder.clearGroups().build();
+ assertEquals(0, policy5.getUsers().size());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestGroup.java b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
new file mode 100644
index 0000000..8ccdba5
--- /dev/null
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestGroup.java
@@ -0,0 +1,169 @@
+/*
+ * 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.authorization;
+
+import org.junit.Test;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+public class TestGroup {
+
+ @Test
+ public void testSimpleCreation() {
+ final String id = "1";
+ final String name = "group1";
+ final String user1 = "user1";
+ final String user2 = "user2";
+
+ final Group group = new Group.Builder()
+ .identifier(id)
+ .name(name)
+ .addUser(user1)
+ .addUser(user2)
+ .build();
+
+ assertEquals(id, group.getIdentifier());
+ assertEquals(name, group.getName());
+
+ assertNotNull(group.getUsers());
+ assertEquals(2, group.getUsers().size());
+ assertTrue(group.getUsers().contains(user1));
+ assertTrue(group.getUsers().contains(user2));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingId() {
+ new Group.Builder()
+ .name("group1")
+ .addUser("user1")
+ .addUser("user2")
+ .build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingName() {
+ new Group.Builder()
+ .identifier("1")
+ .addUser("user1")
+ .addUser("user2")
+ .build();
+ }
+
+ @Test
+ public void testMissingUsers() {
+ final String id = "1";
+ final String name = "group1";
+
+ final Group group = new Group.Builder()
+ .identifier(id)
+ .name(name)
+ .build();
+
+ assertEquals(id, group.getIdentifier());
+ assertEquals(name, group.getName());
+
+ assertNotNull(group.getUsers());
+ assertEquals(0, group.getUsers().size());
+ }
+
+ @Test
+ public void testFromGroup() {
+ final String id = "1";
+ final String name = "group1";
+ final String user1 = "user1";
+ final String user2 = "user2";
+
+ final Group group1 = new Group.Builder()
+ .identifier(id)
+ .name(name)
+ .addUser(user1)
+ .addUser(user2)
+ .build();
+
+ assertEquals(id, group1.getIdentifier());
+ assertEquals(name, group1.getName());
+
+ assertNotNull(group1.getUsers());
+ assertEquals(2, group1.getUsers().size());
+ assertTrue(group1.getUsers().contains(user1));
+ assertTrue(group1.getUsers().contains(user2));
+
+ final Group group2 = new Group.Builder(group1).build();
+ assertEquals(group1.getIdentifier(), group2.getIdentifier());
+ assertEquals(group1.getName(), group2.getName());
+ assertEquals(group1.getUsers(), group2.getUsers());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testFromGroupAndChangeIdentifier() {
+ final Group group1 = new Group.Builder()
+ .identifier("1")
+ .name("group1")
+ .addUser("user1")
+ .build();
+
+ new Group.Builder(group1).identifier("2").build();
+ }
+
+ @Test
+ public void testAddRemoveClearUsers() {
+ final Group.Builder builder = new Group.Builder()
+ .identifier("1")
+ .name("group1")
+ .addUser("user1");
+
+ final Group group1 = builder.build();
+ assertNotNull(group1.getUsers());
+ assertEquals(1, group1.getUsers().size());
+ assertTrue(group1.getUsers().contains("user1"));
+
+ final Set<String> moreUsers = new HashSet<>();
+ moreUsers.add("user2");
+ moreUsers.add("user3");
+ moreUsers.add("user4");
+
+ final Group group2 = builder.addUsers(moreUsers).build();
+ assertEquals(4, group2.getUsers().size());
+ assertTrue(group2.getUsers().contains("user1"));
+ assertTrue(group2.getUsers().contains("user2"));
+ assertTrue(group2.getUsers().contains("user3"));
+ assertTrue(group2.getUsers().contains("user4"));
+
+ final Group group3 = builder.removeUser("user2").build();
+ assertEquals(3, group3.getUsers().size());
+ assertTrue(group3.getUsers().contains("user1"));
+ assertTrue(group3.getUsers().contains("user3"));
+ assertTrue(group3.getUsers().contains("user4"));
+
+ final Set<String> removeUsers = new HashSet<>();
+ removeUsers.add("user1");
+ removeUsers.add("user4");
+
+ final Group group4 = builder.removeUsers(removeUsers).build();
+ assertEquals(1, group4.getUsers().size());
+ assertTrue(group4.getUsers().contains("user3"));
+
+ final Group group5 = builder.clearUsers().build();
+ assertEquals(0, group5.getUsers().size());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestUser.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestUser.java b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestUser.java
new file mode 100644
index 0000000..04b1ab1
--- /dev/null
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/authorization/TestUser.java
@@ -0,0 +1,85 @@
+/*
+ * 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.authorization;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class TestUser {
+
+ @Test
+ public void testSimpleCreation() {
+ final String identifier = "1";
+ final String identity = "user1";
+ final String group1 = "group1";
+ final String group2 = "group2";
+
+ final User user = new User.Builder()
+ .identifier(identifier)
+ .identity(identity)
+ .build();
+
+ assertEquals(identifier, user.getIdentifier());
+ assertEquals(identity, user.getIdentity());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingIdentifier() {
+ new User.Builder()
+ .identity("user1")
+ .build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingIdentity() {
+ new User.Builder()
+ .identifier("1")
+ .build();
+ }
+
+ @Test
+ public void testFromUser() {
+ final String identifier = "1";
+ final String identity = "user1";
+ final String group1 = "group1";
+ final String group2 = "group2";
+
+ final User user = new User.Builder()
+ .identifier(identifier)
+ .identity(identity)
+ .build();
+
+ assertEquals(identifier, user.getIdentifier());
+ assertEquals(identity, user.getIdentity());
+
+ final User user2 = new User.Builder(user).build();
+ assertEquals(user.getIdentifier(), user2.getIdentifier());
+ assertEquals(user.getIdentity(), user2.getIdentity());
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testFromUserAndChangeIdentifier() {
+ final User user = new User.Builder()
+ .identifier("1")
+ .identity("user1")
+ .build();
+
+ new User.Builder(user).identifier("2").build();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-framework-api/src/test/java/org/apache/nifi/web/TestRevision.java
----------------------------------------------------------------------
diff --git a/nifi-framework-api/src/test/java/org/apache/nifi/web/TestRevision.java b/nifi-framework-api/src/test/java/org/apache/nifi/web/TestRevision.java
new file mode 100644
index 0000000..6d513fd
--- /dev/null
+++ b/nifi-framework-api/src/test/java/org/apache/nifi/web/TestRevision.java
@@ -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());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-mock/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-mock/pom.xml b/nifi-mock/pom.xml
index dd15fef..53f29ff 100644
--- a/nifi-mock/pom.xml
+++ b/nifi-mock/pom.xml
@@ -28,6 +28,10 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-framework-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-utils</artifactId>
</dependency>
<dependency>
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceEventRepository.java
----------------------------------------------------------------------
diff --git a/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceEventRepository.java b/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceEventRepository.java
deleted file mode 100644
index dc71ed5..0000000
--- a/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceEventRepository.java
+++ /dev/null
@@ -1,139 +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.provenance;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.concurrent.atomic.AtomicLong;
-
-import org.apache.nifi.authorization.Authorizer;
-import org.apache.nifi.authorization.user.NiFiUser;
-import org.apache.nifi.events.EventReporter;
-import org.apache.nifi.provenance.lineage.ComputeLineageSubmission;
-import org.apache.nifi.provenance.search.Query;
-import org.apache.nifi.provenance.search.QuerySubmission;
-import org.apache.nifi.provenance.search.SearchableField;
-
-public class MockProvenanceEventRepository implements ProvenanceEventRepository {
-
- private final List<ProvenanceEventRecord> records = new ArrayList<>();
- private final AtomicLong idGenerator = new AtomicLong(0L);
-
- @Override
- public void registerEvents(final Iterable<ProvenanceEventRecord> events) {
- for (final ProvenanceEventRecord event : events) {
- registerEvent(event);
- }
- }
-
- @Override
- public void registerEvent(final ProvenanceEventRecord event) {
- final StandardProvenanceEventRecord newRecord;
- if (event instanceof StandardProvenanceEventRecord) {
- newRecord = (StandardProvenanceEventRecord) event;
- } else {
- newRecord = new StandardProvenanceEventRecord.Builder().fromEvent(event).build();
- }
- newRecord.setEventId(idGenerator.getAndIncrement());
-
- records.add(newRecord);
- }
-
- @Override
- public void initialize(EventReporter eventReporter, Authorizer authorizer, ProvenanceAuthorizableFactory resourceFactory) throws IOException {
-
- }
-
- @Override
- public List<ProvenanceEventRecord> getEvents(long firstRecordId, int maxRecords) throws IOException {
- if (firstRecordId > records.size()) {
- return Collections.emptyList();
- }
-
- return records.subList((int) firstRecordId, Math.min(records.size(), (int) (firstRecordId + maxRecords)));
- }
-
- @Override
- public List<ProvenanceEventRecord> getEvents(long firstRecordId, int maxRecords, NiFiUser user) throws IOException {
- return getEvents(firstRecordId, maxRecords);
- }
-
- @Override
- public Long getMaxEventId() {
- return Long.valueOf(records.size() - 1);
- }
-
- @Override
- public QuerySubmission submitQuery(Query query, NiFiUser user) {
- throw new UnsupportedOperationException("MockProvenanceEventRepository does not support querying");
- }
-
- @Override
- public QuerySubmission retrieveQuerySubmission(String queryIdentifier, NiFiUser user) {
- throw new UnsupportedOperationException("MockProvenanceEventRepository does not support querying");
- }
-
- @Override
- public ComputeLineageSubmission submitLineageComputation(String flowFileUuid, NiFiUser user) {
- throw new UnsupportedOperationException("MockProvenanceEventRepository does not support Lineage Computation");
- }
-
- @Override
- public ComputeLineageSubmission retrieveLineageSubmission(String lineageIdentifier, NiFiUser user) {
- throw new UnsupportedOperationException("MockProvenanceEventRepository does not support Lineage Computation");
- }
-
- @Override
- public ProvenanceEventRecord getEvent(long id, NiFiUser user) throws IOException {
- if (id > records.size()) {
- return null;
- }
-
- return records.get((int) id);
- }
-
- @Override
- public ComputeLineageSubmission submitExpandParents(long eventId, NiFiUser user) {
- throw new UnsupportedOperationException("MockProvenanceEventRepository does not support Lineage Computation");
- }
-
- @Override
- public ComputeLineageSubmission submitExpandChildren(long eventId, NiFiUser user) {
- throw new UnsupportedOperationException("MockProvenanceEventRepository does not support Lineage Computation");
- }
-
- @Override
- public void close() throws IOException {
- }
-
- @Override
- public List<SearchableField> getSearchableFields() {
- return Collections.emptyList();
- }
-
- @Override
- public List<SearchableField> getSearchableAttributes() {
- return Collections.emptyList();
- }
-
- @Override
- public ProvenanceEventBuilder eventBuilder() {
- return new StandardProvenanceEventRecord.Builder();
- }
-}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceRepository.java
----------------------------------------------------------------------
diff --git a/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceRepository.java b/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceRepository.java
new file mode 100644
index 0000000..a13a338
--- /dev/null
+++ b/nifi-mock/src/main/java/org/apache/nifi/provenance/MockProvenanceRepository.java
@@ -0,0 +1,149 @@
+/*
+ * 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.provenance;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicLong;
+
+import org.apache.nifi.authorization.Authorizer;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.events.EventReporter;
+import org.apache.nifi.provenance.lineage.ComputeLineageSubmission;
+import org.apache.nifi.provenance.search.Query;
+import org.apache.nifi.provenance.search.QuerySubmission;
+import org.apache.nifi.provenance.search.SearchableField;
+
+public class MockProvenanceRepository implements ProvenanceRepository {
+
+ private final List<ProvenanceEventRecord> records = new ArrayList<>();
+ private final AtomicLong idGenerator = new AtomicLong(0L);
+
+ @Override
+ public void registerEvents(final Iterable<ProvenanceEventRecord> events) {
+ for (final ProvenanceEventRecord event : events) {
+ registerEvent(event);
+ }
+ }
+
+ @Override
+ public void registerEvent(final ProvenanceEventRecord event) {
+ final StandardProvenanceEventRecord newRecord;
+ if (event instanceof StandardProvenanceEventRecord) {
+ newRecord = (StandardProvenanceEventRecord) event;
+ } else {
+ newRecord = new StandardProvenanceEventRecord.Builder().fromEvent(event).build();
+ }
+ newRecord.setEventId(idGenerator.getAndIncrement());
+
+ records.add(newRecord);
+ }
+
+ @Override
+ public void initialize(EventReporter eventReporter, Authorizer authorizer, ProvenanceAuthorizableFactory resourceFactory) throws IOException {
+
+ }
+
+ @Override
+ public List<ProvenanceEventRecord> getEvents(long firstRecordId, int maxRecords) throws IOException {
+ if (firstRecordId > records.size()) {
+ return Collections.emptyList();
+ }
+
+ return records.subList((int) firstRecordId, Math.min(records.size(), (int) (firstRecordId + maxRecords)));
+ }
+
+ @Override
+ public List<ProvenanceEventRecord> getEvents(long firstRecordId, int maxRecords, NiFiUser user) throws IOException {
+ return getEvents(firstRecordId, maxRecords);
+ }
+
+ @Override
+ public Long getMaxEventId() {
+ return Long.valueOf(records.size() - 1);
+ }
+
+ @Override
+ public ProvenanceEventRecord getEvent(long id) throws IOException {
+ return null;
+ }
+
+ @Override
+ public QuerySubmission submitQuery(Query query, NiFiUser user) {
+ throw new UnsupportedOperationException("MockProvenanceRepository does not support querying");
+ }
+
+ @Override
+ public QuerySubmission retrieveQuerySubmission(String queryIdentifier, NiFiUser user) {
+ throw new UnsupportedOperationException("MockProvenanceRepository does not support querying");
+ }
+
+ @Override
+ public ComputeLineageSubmission submitLineageComputation(String flowFileUuid, NiFiUser user) {
+ throw new UnsupportedOperationException("MockProvenanceRepository does not support Lineage Computation");
+ }
+
+ @Override
+ public ComputeLineageSubmission retrieveLineageSubmission(String lineageIdentifier, NiFiUser user) {
+ throw new UnsupportedOperationException("MockProvenanceRepository does not support Lineage Computation");
+ }
+
+ @Override
+ public ProvenanceEventRecord getEvent(long id, NiFiUser user) throws IOException {
+ if (id > records.size()) {
+ return null;
+ }
+
+ return records.get((int) id);
+ }
+
+ @Override
+ public ComputeLineageSubmission submitExpandParents(long eventId, NiFiUser user) {
+ throw new UnsupportedOperationException("MockProvenanceRepository does not support Lineage Computation");
+ }
+
+ @Override
+ public ComputeLineageSubmission submitExpandChildren(long eventId, NiFiUser user) {
+ throw new UnsupportedOperationException("MockProvenanceRepository does not support Lineage Computation");
+ }
+
+ @Override
+ public void close() throws IOException {
+ }
+
+ @Override
+ public List<SearchableField> getSearchableFields() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<SearchableField> getSearchableAttributes() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public ProvenanceEventBuilder eventBuilder() {
+ return new StandardProvenanceEventRecord.Builder();
+ }
+
+ @Override
+ public ProvenanceEventRepository getProvenanceEventRepository() {
+ return this;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-mock/src/main/java/org/apache/nifi/util/MockEventAccess.java
----------------------------------------------------------------------
diff --git a/nifi-mock/src/main/java/org/apache/nifi/util/MockEventAccess.java b/nifi-mock/src/main/java/org/apache/nifi/util/MockEventAccess.java
index 8b3bf25..5c9a0ed 100644
--- a/nifi-mock/src/main/java/org/apache/nifi/util/MockEventAccess.java
+++ b/nifi-mock/src/main/java/org/apache/nifi/util/MockEventAccess.java
@@ -65,7 +65,6 @@ public class MockEventAccess implements EventAccess {
this.provenanceRecords.add(record);
}
- @Override
public ProvenanceEventRepository getProvenanceRepository() {
return null;
}
http://git-wip-us.apache.org/repos/asf/nifi/blob/d1129706/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
index 2aac209..5383803 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-administration/pom.xml
@@ -32,6 +32,10 @@
</dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-framework-api</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
<artifactId>nifi-framework-core-api</artifactId>
</dependency>
<dependency>