You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by mc...@apache.org on 2015/03/20 15:51:34 UTC
[2/2] incubator-nifi git commit: NIFI-250: - Updating the way in
which UI extensions interact with the underlying NiFi instance.
NIFI-250:
- Updating the way in which UI extensions interact with the underlying NiFi instance.
Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/24d787e5
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/24d787e5
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/24d787e5
Branch: refs/heads/NIFI-250
Commit: 24d787e5d40949659427e72d126dd2a225b6ff86
Parents: ffa919a
Author: Matt Gilman <ma...@gmail.com>
Authored: Fri Mar 20 10:51:15 2015 -0400
Committer: Matt Gilman <ma...@gmail.com>
Committed: Fri Mar 20 10:51:15 2015 -0400
----------------------------------------------------------------------
.../apache/nifi/web/ComponentConfiguration.java | 122 ------
.../org/apache/nifi/web/ComponentDetails.java | 122 ++++++
.../apache/nifi/web/ConfigurationAction.java | 51 +++
.../apache/nifi/web/ConfigurationContext.java | 96 +++++
.../nifi/web/ConfigurationRequestContext.java | 29 ++
.../org/apache/nifi/web/RequestContext.java | 58 +++
.../nifi/web/UiExtensionRequestContext.java | 95 -----
.../org/apache/nifi/web/UiExtensionType.java | 26 ++
.../nifi/web/api/dto/ControllerServiceDTO.java | 15 +
.../nifi/web/api/dto/ProcessorConfigDTO.java | 3 +-
.../nifi/web/api/dto/ReportingTaskDTO.java | 15 +
.../org/apache/nifi/web/server/JettyServer.java | 147 ++++++-
.../extension/ConfigureComponentController.java | 9 +-
.../apache/nifi/ui/extension/UiExtension.java | 10 +-
.../nifi/ui/extension/UiExtensionMapping.java | 7 +-
.../nifi/ui/extension/UiExtensionType.java | 26 --
.../controller/UiExtensionControllerFacade.java | 101 -----
.../UiExtensionControllerRequest.java | 64 ---
.../nifi/web/StandardConfigurationContext.java | 417 +++++++++++++++++++
.../nifi/web/api/ControllerServiceResource.java | 19 +
.../apache/nifi/web/api/ProcessorResource.java | 15 +
.../nifi/web/api/ReportingTaskResource.java | 21 +-
.../StandardUiExtensionControllerFacade.java | 377 -----------------
.../src/main/resources/nifi-web-api-context.xml | 2 +-
.../nifi/integration/util/NiFiTestServer.java | 5 +
.../nifi-framework/nifi-web/pom.xml | 1 -
26 files changed, 1041 insertions(+), 812 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentConfiguration.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentConfiguration.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentConfiguration.java
deleted file mode 100644
index bb47760..0000000
--- a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentConfiguration.java
+++ /dev/null
@@ -1,122 +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;
-
-import java.util.Collection;
-import java.util.Map;
-
-/**
- *
- */
-public class ComponentConfiguration {
-
- 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 Collection<String> validationErrors;
-
- private ComponentConfiguration(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.validationErrors = builder.validationErrors;
- }
-
- public String getId() {
- return id;
- }
-
- public String getName() {
- return name;
- }
-
- public String getType() {
- return type;
- }
-
- public String getState() {
- return state;
- }
-
- public String getAnnotationData() {
- return annotationData;
- }
-
- public Map<String, String> getProperties() {
- return properties;
- }
-
- 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 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 ComponentConfiguration build() {
- return new ComponentConfiguration(this);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentDetails.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentDetails.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentDetails.java
new file mode 100644
index 0000000..af5f5bd
--- /dev/null
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ComponentDetails.java
@@ -0,0 +1,122 @@
+/*
+ * 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;
+
+/**
+ *
+ */
+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 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.validationErrors = builder.validationErrors;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getState() {
+ return state;
+ }
+
+ public String getAnnotationData() {
+ return annotationData;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ 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 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 ComponentDetails build() {
+ return new ComponentDetails(this);
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
index d46d489..ca3af44 100644
--- a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationAction.java
@@ -21,17 +21,50 @@ package org.apache.nifi.web;
*/
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;
}
/**
+ * The id of the component being modified.
+ *
+ * @return
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * The name of the component being modified.
+ *
+ * @return
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * The type of the component being modified.
+ *
+ * @return
+ */
+ public String getType() {
+ return type;
+ }
+
+ /**
* Gets the name of the field, property, etc that has been modified.
*
* @return
@@ -60,10 +93,28 @@ public class ConfigurationAction {
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;
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationContext.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationContext.java
new file mode 100644
index 0000000..422b262
--- /dev/null
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationContext.java
@@ -0,0 +1,96 @@
+/*
+ * 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 org.apache.nifi.controller.ControllerService;
+
+/**
+ * NiFi web context providing limited access to dataflow configuration for
+ * component custom UIs.
+ */
+public interface ConfigurationContext {
+
+ /**
+ * Gets 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.
+ *
+ * @param serviceIdentifier
+ * @return
+ */
+ ControllerService getControllerService(String serviceIdentifier);
+
+ /**
+ * 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
+ * @param actions
+ */
+ void saveActions(RequestContext requestContext, Collection<ConfigurationAction> actions);
+
+ /**
+ * Gets the current user dn. Returns null if no user is found.
+ *
+ * @return
+ */
+ String getCurrentUserDn();
+
+ /**
+ * Gets the current user name. Returns null if no user is found.
+ *
+ * @return
+ */
+ String getCurrentUserName();
+
+ /**
+ * Sets the annotation data for the underlying component.
+ *
+ * @param configurationContext
+ * @param annotationData
+ * @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.
+ */
+ ComponentDetails setAnnotationData(ConfigurationRequestContext configurationContext, String annotationData) throws ResourceNotFoundException, InvalidRevisionException, ClusterRequestException;
+
+ /**
+ * Gets the details for the underlying component (including configuration, validation errors, and annotation data).
+ *
+ * @param requestContext
+ * @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.
+ */
+ ComponentDetails getComponentDetails(RequestContext requestContext) throws ResourceNotFoundException, ClusterRequestException;
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationRequestContext.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationRequestContext.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationRequestContext.java
new file mode 100644
index 0000000..701e25e
--- /dev/null
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/ConfigurationRequestContext.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Context around about a configuration request.
+ */
+public interface ConfigurationRequestContext extends RequestContext {
+
+ /**
+ * @return the revision
+ */
+ Revision getRevision();
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/RequestContext.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/RequestContext.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/RequestContext.java
new file mode 100644
index 0000000..1bfe16a
--- /dev/null
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/RequestContext.java
@@ -0,0 +1,58 @@
+/*
+ * 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 RequestContext {
+
+ /**
+ * Returns the type of UI extension is making the request.
+ *
+ * @return
+ */
+ 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/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionRequestContext.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionRequestContext.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionRequestContext.java
deleted file mode 100644
index 24c4226..0000000
--- a/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionRequestContext.java
+++ /dev/null
@@ -1,95 +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;
-
-import java.util.Collection;
-
-import org.apache.nifi.controller.ControllerService;
-
-/**
- * NiFi web context providing limited access to dataflow configuration for
- * processor custom UIs.
- */
-public interface UiExtensionRequestContext {
-
- public static final String ATTRIBUTE_KEY = "ui-extension-request-context";
-
- /**
- * Gets 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.
- *
- * @param serviceIdentifier
- * @return
- */
- ControllerService getControllerService(String serviceIdentifier);
-
- /**
- * 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 actions
- */
- void saveActions(Collection<ConfigurationAction> actions);
-
- /**
- * Gets the current user dn. Returns null if no user is found.
- *
- * @return
- */
- String getCurrentUserDn();
-
- /**
- * Gets the current user name. Returns null if no user is found.
- *
- * @return
- */
- String getCurrentUserName();
-
- /**
- * Sets the annotation data for the underlying component.
- *
- * @param annotationData
- * @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.
- */
- ComponentConfiguration setAnnotationData(String annotationData) throws ResourceNotFoundException, InvalidRevisionException, ClusterRequestException;
-
- /**
- * Gets the configuration for the underlying component (including annotation data).
- *
- * @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.
- */
- ComponentConfiguration getComponentDetails() throws ResourceNotFoundException, ClusterRequestException;
-}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionType.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionType.java b/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionType.java
new file mode 100644
index 0000000..e25d8ca
--- /dev/null
+++ b/nifi/nifi-api/src/main/java/org/apache/nifi/web/UiExtensionType.java
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+public enum UiExtensionType {
+ ProcessorConfiguration,
+ ControllerServiceConfiguration,
+ ReportingTaskConfiguration
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceDTO.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceDTO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceDTO.java
index 76f1f62..75d18a2 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceDTO.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ControllerServiceDTO.java
@@ -36,6 +36,7 @@ public class ControllerServiceDTO extends NiFiComponentDTO {
private Map<String, String> properties;
private Map<String, PropertyDescriptorDTO> descriptors;
+ private String customUiUrl;
private String annotationData;
private Set<ControllerServiceReferencingComponentDTO> referencingComponents;
@@ -133,6 +134,20 @@ public class ControllerServiceDTO extends NiFiComponentDTO {
}
/**
+ * Returns the URL for this controller services custom configuration UI
+ * if applicable. Null otherwise.
+ *
+ * @return
+ */
+ public String getCustomUiUrl() {
+ return customUiUrl;
+ }
+
+ public void setCustomUiUrl(String customUiUrl) {
+ this.customUiUrl = customUiUrl;
+ }
+
+ /**
* The annotation data for this controller service.
*
* @return
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessorConfigDTO.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessorConfigDTO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessorConfigDTO.java
index d1a44b8..63ed005 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessorConfigDTO.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ProcessorConfigDTO.java
@@ -207,7 +207,8 @@ public class ProcessorConfigDTO {
}
/**
- * Whether of not this processor has a custom UI.
+ * Returns the URL for this processors custom configuration UI
+ * if applicable. Null otherwise.
*
* @return
*/
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReportingTaskDTO.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReportingTaskDTO.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReportingTaskDTO.java
index b9e7ff1..7cb24ca 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReportingTaskDTO.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-client-dto/src/main/java/org/apache/nifi/web/api/dto/ReportingTaskDTO.java
@@ -39,6 +39,7 @@ public class ReportingTaskDTO extends NiFiComponentDTO {
private Map<String, String> properties;
private Map<String, PropertyDescriptorDTO> descriptors;
+ private String customUiUrl;
private String annotationData;
private Collection<String> validationErrors;
@@ -157,6 +158,20 @@ public class ReportingTaskDTO extends NiFiComponentDTO {
this.descriptors = descriptors;
}
+ /**
+ * Returns the URL for this reporting task custom configuration UI
+ * if applicable. Null otherwise.
+ *
+ * @return
+ */
+ public String getCustomUiUrl() {
+ return customUiUrl;
+ }
+
+ public void setCustomUiUrl(String customUiUrl) {
+ this.customUiUrl = customUiUrl;
+ }
+
/**
* The currently configured annotation data for the reporting task
* @return
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
index 95052a7..60345ae 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
@@ -52,6 +52,10 @@ import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.web.NiFiWebContext;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.ui.extension.UiExtension;
+import org.apache.nifi.ui.extension.UiExtensionMapping;
+import org.apache.nifi.web.ConfigurationContext;
+import org.apache.nifi.web.UiExtensionType;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConfiguration;
@@ -99,9 +103,14 @@ public class JettyServer implements NiFiServer {
private ExtensionMapping extensionMapping;
private WebAppContext webApiContext;
private WebAppContext webDocsContext;
- private Collection<WebAppContext> customUiWebContexts;
private final NiFiProperties props;
+ private UiExtensionMapping uiExtensions;
+ private Collection<WebAppContext> uiExtensionWebContexts;
+
+ @Deprecated
+ private Collection<WebAppContext> customUiWebContexts;
+
/**
* Creates and configures a new Jetty instance.
*
@@ -192,19 +201,32 @@ public class JettyServer implements NiFiServer {
// handlers for each war and init params for the web api
final HandlerCollection handlers = new HandlerCollection();
- final Map<String, String> initParams = new HashMap<>();
final ClassLoader frameworkClassLoader = getClass().getClassLoader();
final ClassLoader jettyClassLoader = frameworkClassLoader.getParent();
+ @Deprecated
+ final Map<String, String> initParams = new HashMap<>();
+
// deploy the other wars
if (CollectionUtils.isNotEmpty(otherWars)) {
+ // hold onto to the web contexts for all ui extensions
customUiWebContexts = new ArrayList<>();
+ uiExtensionWebContexts = new ArrayList<>();
+
+ // ui extension organized by component type
+ final Map<String, List<UiExtension>> uiExtensionsByType = new HashMap<>();
for (File war : otherWars) {
// see if this war is a custom processor ui
+ @Deprecated
List<String> customUiProcessorTypes = getCustomUiProcessorTypes(war);
+ // identify all known extension types in the war
+ final Map<UiExtensionType, List<String>> uiExtensionInWar = new HashMap<>();
+ identifyUiExtensions(uiExtensionInWar, war);
+
// only include wars that are for custom processor ui's
- if (CollectionUtils.isNotEmpty(customUiProcessorTypes)) {
+ if (CollectionUtils.isNotEmpty(customUiProcessorTypes) || !uiExtensionInWar.isEmpty()) {
+ // get the context path
String warName = StringUtils.substringBeforeLast(war.getName(), ".");
String warContextPath = String.format("/%s", warName);
@@ -220,18 +242,53 @@ public class JettyServer implements NiFiServer {
WebAppContext customUiContext = loadWar(war, warContextPath, narClassLoaderForWar);
// hold on to a reference to all custom ui web app contexts
- customUiWebContexts.add(customUiContext);
-
- // include custom ui web context in the handlers
- handlers.addHandler(customUiContext);
+ if (CollectionUtils.isNotEmpty(customUiProcessorTypes)) {
+ customUiWebContexts.add(customUiContext);
+ } else {
+ uiExtensionWebContexts.add(customUiContext);
+ }
+ // create the ui extensions
+ for (final Map.Entry<UiExtensionType, List<String>> entry : uiExtensionInWar.entrySet()) {
+ final UiExtensionType extensionType = entry.getKey();
+ final List<String> componentTypes = entry.getValue();
+
+ // consider each type identified
+ for (final String componentType : componentTypes) {
+ logger.info(String.format("Loading UI extension [%s, %s] for %s", extensionType, warContextPath, componentTypes));
+
+ // record the extension definition
+ final UiExtension uiExtension = new UiExtension(extensionType, warContextPath);
+
+ // create if this is the first extension for this component type
+ List<UiExtension> uiExtensionsForType = uiExtensionsByType.get(componentType);
+ if (uiExtensionsForType == null) {
+ uiExtensionsForType = new ArrayList<>();
+ uiExtensionsByType.put(componentType, uiExtensionsForType);
+ }
+
+ // record this extension
+ uiExtensionsForType.add(uiExtension);
+ }
+ }
+
// add the initialization paramters
+ // @Deprecated
for (String customUiProcessorType : customUiProcessorTypes) {
// map the processor type to the custom ui path
initParams.put(customUiProcessorType, warContextPath);
}
+
+ // include custom ui web context in the handlers
+ handlers.addHandler(customUiContext);
}
+
}
+
+ // record all ui extensions
+ uiExtensions = new UiExtensionMapping(uiExtensionsByType);
+ } else {
+ uiExtensions = new UiExtensionMapping(Collections.EMPTY_MAP);
}
// load the web ui app
@@ -291,12 +348,57 @@ public class JettyServer implements NiFiServer {
return wars;
}
+ private void readUiExtensions(final Map<UiExtensionType, List<String>> uiExtensions, final UiExtensionType uiExtensionType, final JarFile jarFile, final JarEntry jarEntry) throws IOException {
+ if (jarEntry == null) {
+ return;
+ }
+
+ // get an input stream for the nifi-processor configuration file
+ BufferedReader in = new BufferedReader(new InputStreamReader(jarFile.getInputStream(jarEntry)));
+
+ // read in each configured type
+ String componentType;
+ while ((componentType = in.readLine()) != null) {
+ // ensure the line isn't blank
+ if (StringUtils.isNotBlank(componentType)) {
+ List<String> extensions = uiExtensions.get(uiExtensionType);
+
+ // if there are currently no extensions for this type create it
+ if (extensions == null) {
+ extensions = new ArrayList<>();
+ uiExtensions.put(uiExtensionType, extensions);
+ }
+
+ // add the specified type
+ extensions.add(componentType);
+ }
+ }
+ }
+
+ /**
+ * Identifies all known UI extensions and stores them in the specified map.
+ *
+ * @param uiExtensions
+ * @param warFile
+ */
+ private void identifyUiExtensions(final Map<UiExtensionType, List<String>> uiExtensions, final File warFile) {
+ try (final JarFile jarFile = new JarFile(warFile)) {
+ // locate the ui extensions
+ readUiExtensions(uiExtensions, UiExtensionType.ProcessorConfiguration, jarFile, jarFile.getJarEntry("META-INF/nifi-processor-configuration"));
+ readUiExtensions(uiExtensions, UiExtensionType.ControllerServiceConfiguration, jarFile, jarFile.getJarEntry("META-INF/nifi-controller-service-configuration"));
+ readUiExtensions(uiExtensions, UiExtensionType.ReportingTaskConfiguration, jarFile, jarFile.getJarEntry("META-INF/nifi-reporting-task-configuration"));
+ } catch (IOException ioe) {
+ logger.warn(String.format("Unable to inspect %s for a UI extensions.", warFile));
+ }
+ }
+
/**
* Loads the processor types that the specified war file is a custom UI for.
*
* @param warFile
* @return
*/
+ @Deprecated
private List<String> getCustomUiProcessorTypes(final File warFile) {
List<String> processorTypes = new ArrayList<>();
JarFile jarFile = null;
@@ -534,18 +636,25 @@ public class JettyServer implements NiFiServer {
}
}
}
+
+ // ensure web api is loaded and inject the ui extensions
+ if (webApiContext != null) {
+ final ServletContext webApiServletContext = webApiContext.getServletHandler().getServletContext();
+ webApiServletContext.setAttribute("nifi-ui-extensions", uiExtensions);
+ }
// ensure the appropriate wars deployed successfully before injecting the NiFi context and security filters -
// this must be done after starting the server (and ensuring there were no start up failures)
+ // @Deprecated
if (webApiContext != null && CollectionUtils.isNotEmpty(customUiWebContexts)) {
final ServletContext webApiServletContext = webApiContext.getServletHandler().getServletContext();
final WebApplicationContext webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(webApiServletContext);
- final NiFiWebContext NiFiWebContext = webApplicationContext.getBean("nifiWebContext", NiFiWebContext.class);
+ final NiFiWebContext niFiWebContext = webApplicationContext.getBean("nifiWebContext", NiFiWebContext.class);
for (final WebAppContext customUiContext : customUiWebContexts) {
// set the NiFi context in each custom ui servlet context
final ServletContext customUiServletContext = customUiContext.getServletHandler().getServletContext();
- customUiServletContext.setAttribute("nifi-web-context", NiFiWebContext);
+ customUiServletContext.setAttribute("nifi-web-context", niFiWebContext);
// add the security filter to any custom ui wars
final FilterHolder securityFilter = webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
@@ -554,6 +663,26 @@ public class JettyServer implements NiFiServer {
}
}
}
+
+ // ensure the appropriate wars deployed successfully before injecting the NiFi context and security filters -
+ // this must be done after starting the server (and ensuring there were no start up failures)
+ if (webApiContext != null && CollectionUtils.isNotEmpty(uiExtensionWebContexts)) {
+ final ServletContext webApiServletContext = webApiContext.getServletHandler().getServletContext();
+ final WebApplicationContext webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(webApiServletContext);
+ final ConfigurationContext configurationContext = webApplicationContext.getBean("nifiWebConfigurationContext", ConfigurationContext.class);
+
+ for (final WebAppContext customUiContext : uiExtensionWebContexts) {
+ // set the NiFi context in each custom ui servlet context
+ final ServletContext customUiServletContext = customUiContext.getServletHandler().getServletContext();
+ customUiServletContext.setAttribute("nifi-web-configuration-context", configurationContext);
+
+ // add the security filter to any ui extensions wars
+ final FilterHolder securityFilter = webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
+ if (securityFilter != null) {
+ customUiContext.addFilter(securityFilter, "/*", EnumSet.of(DispatcherType.REQUEST));
+ }
+ }
+ }
// ensure the web document war was loaded and provide the extension mapping
if (webDocsContext != null) {
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension-controller/src/main/java/org/apache/nifi/ui/extension/ConfigureComponentController.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension-controller/src/main/java/org/apache/nifi/ui/extension/ConfigureComponentController.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension-controller/src/main/java/org/apache/nifi/ui/extension/ConfigureComponentController.java
index 8fa43db..c876686 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension-controller/src/main/java/org/apache/nifi/ui/extension/ConfigureComponentController.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension-controller/src/main/java/org/apache/nifi/ui/extension/ConfigureComponentController.java
@@ -16,6 +16,7 @@
*/
package org.apache.nifi.ui.extension;
+import org.apache.nifi.web.UiExtensionType;
import org.apache.nifi.web.controller.UiExtensionControllerRequest;
import org.apache.nifi.web.controller.UiExtensionControllerFacade;
import java.io.IOException;
@@ -36,7 +37,7 @@ import org.apache.nifi.action.component.details.ExtensionDetails;
import org.apache.nifi.action.details.ConfigureDetails;
import org.apache.nifi.controller.ControllerService;
import org.apache.nifi.web.ClusterRequestException;
-import org.apache.nifi.web.ComponentConfiguration;
+import org.apache.nifi.web.ComponentDetails;
import org.apache.nifi.web.ConfigurationAction;
import org.apache.nifi.web.InvalidRevisionException;
import org.apache.nifi.web.ResourceNotFoundException;
@@ -83,7 +84,7 @@ public class ConfigureComponentController extends HttpServlet {
final UiExtensionControllerRequest config = getRequestContextConig(extensionType, request);
// get the initial component details
- final ComponentConfiguration details = controllerFacade.getComponentDetails(config);
+ final ComponentDetails details = controllerFacade.getComponentDetails(config);
// lookup a viewer for the content
final String uiExtensionUri = servletContext.getInitParameter(type);
@@ -153,12 +154,12 @@ public class ConfigureComponentController extends HttpServlet {
}
@Override
- public ComponentConfiguration setAnnotationData(String annotationData) throws ClusterRequestException, InvalidRevisionException, ResourceNotFoundException{
+ public ComponentDetails setAnnotationData(String annotationData) throws ClusterRequestException, InvalidRevisionException, ResourceNotFoundException{
return controllerFacade.setAnnotationData(config, annotationData);
}
@Override
- public ComponentConfiguration getComponentDetails() throws ClusterRequestException, ResourceNotFoundException {
+ public ComponentDetails getComponentDetails() throws ClusterRequestException, ResourceNotFoundException {
return controllerFacade.getComponentDetails(config);
}
});
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtension.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtension.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtension.java
index 9040896..61efed5 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtension.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtension.java
@@ -16,6 +16,8 @@
*/
package org.apache.nifi.ui.extension;
+import org.apache.nifi.web.UiExtensionType;
+
/**
* Information about a UI extension required to be invoked.
*/
@@ -23,12 +25,10 @@ public class UiExtension {
private final UiExtensionType extensionType;
private final String contextPath;
- private final ClassLoader classloader;
- public UiExtension(final UiExtensionType extensionType, final String contextPath, final ClassLoader classloader) {
+ public UiExtension(final UiExtensionType extensionType, final String contextPath) {
this.extensionType = extensionType;
this.contextPath = contextPath;
- this.classloader = classloader;
}
public UiExtensionType getExtensionType() {
@@ -39,8 +39,4 @@ public class UiExtension {
return contextPath;
}
- public ClassLoader getClassloader() {
- return classloader;
- }
-
}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionMapping.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionMapping.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionMapping.java
index 6431686..e62ef6e 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionMapping.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionMapping.java
@@ -16,6 +16,7 @@
*/
package org.apache.nifi.ui.extension;
+import java.util.List;
import java.util.Map;
/**
@@ -23,9 +24,9 @@ import java.util.Map;
*/
public class UiExtensionMapping {
- private final Map<String, UiExtension> uiExtensions;
+ private final Map<String, List<UiExtension>> uiExtensions;
- public UiExtensionMapping(Map<String, UiExtension> uiExtensions) {
+ public UiExtensionMapping(Map<String, List<UiExtension>> uiExtensions) {
this.uiExtensions = uiExtensions;
}
@@ -33,7 +34,7 @@ public class UiExtensionMapping {
return uiExtensions.containsKey(type);
}
- public UiExtension getUiExtension(final String type) {
+ public List<UiExtension> getUiExtension(final String type) {
return uiExtensions.get(type);
}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionType.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionType.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionType.java
deleted file mode 100644
index 1beeea6..0000000
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/ui/extension/UiExtensionType.java
+++ /dev/null
@@ -1,26 +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.ui.extension;
-
-/**
- * Types of UI extensions.
- */
-public enum UiExtensionType {
- ProcessorConfiguration,
- ControllerServiceConfiguration,
- ReportingTaskConfiguration
-}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerFacade.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerFacade.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerFacade.java
deleted file mode 100644
index cf53b7b..0000000
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerFacade.java
+++ /dev/null
@@ -1,101 +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.controller;
-
-import java.util.Collection;
-import org.apache.nifi.action.Action;
-
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.web.ClusterRequestException;
-import org.apache.nifi.web.ComponentConfiguration;
-import org.apache.nifi.web.InvalidRevisionException;
-import org.apache.nifi.web.ResourceNotFoundException;
-
-/**
- * Provides limited access to the controller for UI extensions.
- */
-public interface UiExtensionControllerFacade {
-
- /**
- * Gets 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.
- *
- * @param serviceIdentifier
- * @return
- */
- ControllerService getControllerService(String serviceIdentifier);
-
- /**
- * 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 actions
- */
- void saveActions(Collection<Action> actions);
-
- /**
- * Gets the current user dn. Returns null if no user is found.
- *
- * @return
- */
- String getCurrentUserDn();
-
- /**
- * Gets the current user name. Returns null if no user is found.
- *
- * @return
- */
- String getCurrentUserName();
-
- /**
- * Sets the annotation data for the component in the specified request.
- *
- * @param configurationRequest
- * @param annotationData
- * @return the configuration for the component specified request
- * @throws ResourceNotFoundException if the specified 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 component. This exception will only be thrown when operating
- * in a cluster.
- */
- ComponentConfiguration setAnnotationData(UiExtensionControllerRequest configurationRequest, String annotationData)
- throws ResourceNotFoundException, InvalidRevisionException, ClusterRequestException;
-
- /**
- * Gets the configuration for the underlying component.
- *
- * @param configurationRequest
- * @return the configuration for the component specified in request
- * @throws ResourceNotFoundException if the processor does not exit
- * @throws ClusterRequestException if the component was unable to be
- * retrieved from the cluster. This exception will only be thrown when
- * operating in a cluster.
- */
- ComponentConfiguration getComponentDetails(UiExtensionControllerRequest configurationRequest)
- throws ResourceNotFoundException, ClusterRequestException;
-}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerRequest.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerRequest.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerRequest.java
deleted file mode 100644
index f3d591f..0000000
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-ui-extension/src/main/java/org/apache/nifi/web/controller/UiExtensionControllerRequest.java
+++ /dev/null
@@ -1,64 +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.controller;
-
-import org.apache.nifi.ui.extension.UiExtensionType;
-import org.apache.nifi.web.Revision;
-
-/**
- * A UI extensions request object containing required items to querying the controller.
- */
-public interface UiExtensionControllerRequest {
-
- /**
- * The type of UI extension supports.
- *
- * @return
- */
- 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();
-
- /**
- * @return the component ID
- */
- String getId();
-
- /**
- * @return the revision
- */
- Revision getRevision();
-
- /**
- * 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/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardConfigurationContext.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardConfigurationContext.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardConfigurationContext.java
new file mode 100644
index 0000000..576ab30
--- /dev/null
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardConfigurationContext.java
@@ -0,0 +1,417 @@
+/*
+ * 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;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+
+import org.apache.nifi.action.Action;
+import org.apache.nifi.action.Component;
+import org.apache.nifi.action.Operation;
+import org.apache.nifi.action.component.details.ExtensionDetails;
+import org.apache.nifi.action.details.ConfigureDetails;
+import org.apache.nifi.admin.service.AuditService;
+import org.apache.nifi.cluster.manager.NodeResponse;
+import org.apache.nifi.cluster.manager.impl.WebClusterManager;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.web.security.user.NiFiUserDetails;
+import org.apache.nifi.web.security.user.NiFiUserUtils;
+import org.apache.nifi.user.NiFiUser;
+import org.apache.nifi.util.NiFiProperties;
+import org.apache.nifi.web.api.dto.ProcessorConfigDTO;
+import org.apache.nifi.web.api.dto.ProcessorDTO;
+import org.apache.nifi.web.api.dto.RevisionDTO;
+import org.apache.nifi.web.api.entity.ProcessorEntity;
+import org.apache.nifi.web.util.WebUtils;
+
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import com.sun.jersey.core.util.MultivaluedMapImpl;
+import org.apache.nifi.controller.ControllerServiceLookup;
+import org.apache.nifi.web.util.ClientResponseUtils;
+
+/**
+ * Implements the NiFiWebContext interface to support a context in both
+ * standalone and clustered environments.
+ */
+public class StandardConfigurationContext implements ConfigurationContext {
+
+ private static final Logger logger = LoggerFactory.getLogger(StandardConfigurationContext.class);
+ public static final String CLIENT_ID_PARAM = "clientId";
+ public static final String REVISION_PARAM = "revision";
+ public static final String VERBOSE_PARAM = "verbose";
+
+ private NiFiProperties properties;
+ private NiFiServiceFacade serviceFacade;
+ private WebClusterManager clusterManager;
+ private ControllerServiceLookup controllerServiceLookup;
+ private AuditService auditService;
+
+ @Override
+ public ControllerService getControllerService(String serviceIdentifier) {
+ return controllerServiceLookup.getControllerService(serviceIdentifier);
+ }
+
+ @Override
+ @PreAuthorize("hasAnyRole('ROLE_DFM')")
+ public void saveActions(final RequestContext requestContext, final Collection<ConfigurationAction> configurationActions) {
+ Objects.requireNonNull(configurationActions, "Actions cannot be null.");
+
+ Component componentType = null;
+ switch (requestContext.getExtensionType()) {
+ case ProcessorConfiguration:
+ componentType = Component.Processor;
+ break;
+ case ControllerServiceConfiguration:
+ componentType = Component.ControllerService;
+ break;
+ case ReportingTaskConfiguration:
+ componentType = Component.ReportingTask;
+ break;
+ }
+
+ if (componentType == null) {
+ throw new IllegalArgumentException("UI extension must support Processor, ControllerService, or ReportingTask configuration");
+ }
+
+ // - when running standalone or cluster ncm - actions from custom UIs are stored locally
+ // - clustered nodes do not serve custom UIs directly to users so they should never be invoking this method
+ final Date now = new Date();
+ final Collection<Action> actions = new HashSet<>(configurationActions.size());
+ for (final ConfigurationAction configurationAction : configurationActions) {
+ final ExtensionDetails extensionDetails = new ExtensionDetails();
+ extensionDetails.setType(configurationAction.getType());
+
+ final ConfigureDetails configureDetails = new ConfigureDetails();
+ configureDetails.setName(configurationAction.getName());
+ configureDetails.setPreviousValue(configurationAction.getPreviousValue());
+ configureDetails.setValue(configurationAction.getValue());
+
+ final Action action = new Action();
+ action.setTimestamp(now);
+ action.setSourceId(configurationAction.getId());
+ action.setSourceName(configurationAction.getName());
+ action.setSourceType(componentType);
+ action.setOperation(Operation.Configure);
+ action.setUserDn(getCurrentUserDn());
+ action.setUserName(getCurrentUserName());
+ action.setComponentDetails(extensionDetails);
+ action.setActionDetails(configureDetails);
+ actions.add(action);
+ }
+
+ if (!actions.isEmpty()) {
+ try {
+ // record the operations
+ auditService.addActions(actions);
+ } catch (Throwable t) {
+ logger.warn("Unable to record actions: " + t.getMessage());
+ if (logger.isDebugEnabled()) {
+ logger.warn(StringUtils.EMPTY, t);
+ }
+ }
+ }
+ }
+
+ @Override
+ public String getCurrentUserDn() {
+ String userDn = NiFiUser.ANONYMOUS_USER_DN;
+
+ final NiFiUser user = NiFiUserUtils.getNiFiUser();
+ if (user != null) {
+ userDn = user.getDn();
+ }
+
+ return userDn;
+ }
+
+ @Override
+ public String getCurrentUserName() {
+ String userName = NiFiUser.ANONYMOUS_USER_DN;
+
+ final NiFiUser user = NiFiUserUtils.getNiFiUser();
+ if (user != null) {
+ userName = user.getUserName();
+ }
+
+ return userName;
+ }
+
+ @Override
+ public ComponentDetails getComponentDetails(final RequestContext requestContext) throws ResourceNotFoundException, ClusterRequestException {
+ final String id = requestContext.getId();
+
+ if (StringUtils.isBlank(id)) {
+ throw new ResourceNotFoundException(String.format("Context config did not have a component ID."));
+ }
+
+ // ensure the path could be
+ if (requestContext.getExtensionType() == null) {
+ throw new ResourceNotFoundException(String.format("The type must be one of ['%s']", StringUtils.join(UiExtensionType.values(), "', '")));
+ }
+
+ // get the component facade for interacting directly with that type of object
+ ComponentFacade componentFacade = null;
+ switch (requestContext.getExtensionType()) {
+ case ProcessorConfiguration:
+ componentFacade = new ProcessorFacade();
+ break;
+ case ControllerServiceConfiguration:
+ break;
+ case ReportingTaskConfiguration:
+ break;
+ }
+
+ if (componentFacade == null) {
+ throw new ResourceNotFoundException(String.format("The type must be one of ['%s']", StringUtils.join(UiExtensionType.values(), "', '")));
+ }
+
+ return componentFacade.getComponentDetails(requestContext);
+ }
+
+ @Override
+ @PreAuthorize("hasAnyRole('ROLE_DFM')")
+ public ComponentDetails setAnnotationData(final ConfigurationRequestContext requestContext, final String annotationData)
+ throws ResourceNotFoundException, InvalidRevisionException, ClusterRequestException {
+
+ final String id = requestContext.getId();
+
+ if (StringUtils.isBlank(id)) {
+ throw new ResourceNotFoundException(String.format("Context config did not have a component ID."));
+ }
+
+ // get the component facade for interacting directly with that type of object
+ ComponentFacade componentFacade = null;
+ switch (requestContext.getExtensionType()) {
+ case ProcessorConfiguration:
+ componentFacade = new ProcessorFacade();
+ break;
+ case ControllerServiceConfiguration:
+ break;
+ case ReportingTaskConfiguration:
+ break;
+ }
+
+ if (componentFacade == null) {
+ throw new ResourceNotFoundException(String.format("The type must be one of ['%s']", StringUtils.join(UiExtensionType.values(), "', '")));
+ }
+
+ return componentFacade.setAnnotationData(requestContext, annotationData);
+ }
+
+ private interface ComponentFacade {
+ ComponentDetails getComponentDetails(RequestContext requestContext);
+ ComponentDetails setAnnotationData(ConfigurationRequestContext requestContext, String annotationData);
+ }
+
+ private class ProcessorFacade implements ComponentFacade {
+ @Override
+ public ComponentDetails getComponentDetails(final RequestContext requestContext) {
+ final String id = requestContext.getId();
+
+ final ProcessorDTO processor;
+ if (properties.isClusterManager()) {
+ // create the request URL
+ URI requestUrl;
+ try {
+ String path = "/nifi-api/cluster/processors/" + URLEncoder.encode(id, "UTF-8");
+ requestUrl = new URI(requestContext.getScheme(), null, "localhost", 0, path, null, null);
+ } catch (final URISyntaxException | UnsupportedEncodingException use) {
+ throw new ClusterRequestException(use);
+ }
+
+ // set the request parameters
+ MultivaluedMap<String, String> parameters = new MultivaluedMapImpl();
+ parameters.add(VERBOSE_PARAM, "true");
+
+ // replicate request
+ NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.GET, requestUrl, parameters, getHeaders(requestContext));
+
+ // check for issues replicating request
+ checkResponse(nodeResponse, id);
+
+ // return processor
+ final ProcessorEntity entity = nodeResponse.getClientResponse().getEntity(ProcessorEntity.class);
+ processor = entity.getProcessor();
+ } else {
+ processor = serviceFacade.getProcessor(id);
+ }
+
+ // return the processor info
+ return getComponentConfiguration(processor);
+ }
+
+ @Override
+ public ComponentDetails setAnnotationData(final ConfigurationRequestContext requestContext, final String annotationData) {
+ final Revision revision = requestContext.getRevision();
+ final String id = requestContext.getId();
+
+ final ProcessorDTO processor;
+ if (properties.isClusterManager()) {
+ // create the request URL
+ URI requestUrl;
+ try {
+ String path = "/nifi-api/cluster/processors/" + URLEncoder.encode(id, "UTF-8");
+ requestUrl = new URI(requestContext.getScheme(), null, "localhost", 0, path, null, null);
+ } catch (final URISyntaxException | UnsupportedEncodingException use) {
+ throw new ClusterRequestException(use);
+ }
+
+ // create the revision
+ RevisionDTO revisionDto = new RevisionDTO();
+ revisionDto.setClientId(revision.getClientId());
+ revisionDto.setVersion(revision.getVersion());
+
+ // create the processor entity
+ ProcessorEntity processorEntity = new ProcessorEntity();
+ processorEntity.setRevision(revisionDto);
+
+ // create the processor dto
+ ProcessorDTO processorDto = new ProcessorDTO();
+ processorEntity.setProcessor(processorDto);
+ processorDto.setId(id);
+
+ // create the processor configuration with the given annotation data
+ ProcessorConfigDTO configDto = new ProcessorConfigDTO();
+ processorDto.setConfig(configDto);
+ configDto.setAnnotationData(annotationData);
+
+ // set the content type to json
+ final Map<String, String> headers = getHeaders(requestContext);
+ headers.put("Content-Type", "application/json");
+
+ // replicate request
+ NodeResponse nodeResponse = clusterManager.applyRequest(HttpMethod.PUT, requestUrl, processorEntity, headers);
+
+ // check for issues replicating request
+ checkResponse(nodeResponse, id);
+
+ // return processor
+ final ProcessorEntity entity = nodeResponse.getClientResponse().getEntity(ProcessorEntity.class);
+ processor = entity.getProcessor();
+ } else {
+ final ConfigurationSnapshot<ProcessorDTO> response = serviceFacade.setProcessorAnnotationData(revision, id, annotationData);
+ processor = response.getConfiguration();
+ }
+
+ // return the processor info
+ return getComponentConfiguration(processor);
+ }
+
+ private ComponentDetails getComponentConfiguration(final ProcessorDTO processor) {
+ final ProcessorConfigDTO processorConfig = processor.getConfig();
+ return new ComponentDetails.Builder()
+ .id(processor.getId())
+ .name(processor.getName())
+ .state(processor.getState())
+ .annotationData(processorConfig.getAnnotationData())
+ .properties(processorConfig.getProperties())
+ .validateErrors(processor.getValidationErrors()).build();
+ }
+ }
+
+ /**
+ * Gets the headers for the request to replicate to each node while
+ * clustered.
+ *
+ * @param config
+ * @return
+ */
+ private Map<String, String> getHeaders(final RequestContext config) {
+ final Map<String, String> headers = new HashMap<>();
+ headers.put("Accept", "application/json,application/xml");
+ if (StringUtils.isNotBlank(config.getProxiedEntitiesChain())) {
+ headers.put("X-ProxiedEntitiesChain", config.getProxiedEntitiesChain());
+ }
+
+ // add the user's authorities (if any) to the headers
+ final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication != null) {
+ final Object userDetailsObj = authentication.getPrincipal();
+ if (userDetailsObj instanceof NiFiUserDetails) {
+ // serialize user details object
+ final String hexEncodedUserDetails = WebUtils.serializeObjectToHex((Serializable) userDetailsObj);
+
+ // put serialized user details in header
+ headers.put("X-ProxiedEntityUserDetails", hexEncodedUserDetails);
+ }
+ }
+ return headers;
+ }
+
+ /**
+ * Checks the specified response and drains the stream appropriately.
+ *
+ * @param nodeResponse
+ * @param revision
+ * @param id
+ */
+ private void checkResponse(final NodeResponse nodeResponse, final String id) {
+ if (nodeResponse.hasThrowable()) {
+ ClientResponseUtils.drainClientResponse(nodeResponse.getClientResponse());
+ throw new ClusterRequestException(nodeResponse.getThrowable());
+ } else if (nodeResponse.getClientResponse().getStatus() == Response.Status.CONFLICT.getStatusCode()) {
+ ClientResponseUtils.drainClientResponse(nodeResponse.getClientResponse());
+ throw new InvalidRevisionException(String.format("Conflict: the flow may have been updated by another user."));
+ } else if (nodeResponse.getClientResponse().getStatus() == Response.Status.NOT_FOUND.getStatusCode()) {
+ ClientResponseUtils.drainClientResponse(nodeResponse.getClientResponse());
+ throw new ResourceNotFoundException("Unable to find component with id: " + id);
+ } else if (nodeResponse.getClientResponse().getStatus() != Response.Status.OK.getStatusCode()) {
+ ClientResponseUtils.drainClientResponse(nodeResponse.getClientResponse());
+ throw new ClusterRequestException("Method resulted in an unsuccessful HTTP response code: " + nodeResponse.getClientResponse().getStatus());
+ }
+ }
+
+ public void setClusterManager(WebClusterManager clusterManager) {
+ this.clusterManager = clusterManager;
+ }
+
+ public void setProperties(NiFiProperties properties) {
+ this.properties = properties;
+ }
+
+ public void setServiceFacade(NiFiServiceFacade serviceFacade) {
+ this.serviceFacade = serviceFacade;
+ }
+
+ public void setAuditService(AuditService auditService) {
+ this.auditService = auditService;
+ }
+
+ public void setControllerServiceLookup(ControllerServiceLookup controllerServiceLookup) {
+ this.controllerServiceLookup = controllerServiceLookup;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
index a77e376..8ca9a35 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ControllerServiceResource.java
@@ -24,6 +24,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
+import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
@@ -53,6 +54,9 @@ import org.apache.nifi.web.api.request.LongParameter;
import org.apache.commons.lang3.StringUtils;
import org.apache.nifi.controller.ScheduledState;
import org.apache.nifi.controller.service.ControllerServiceState;
+import org.apache.nifi.ui.extension.UiExtension;
+import org.apache.nifi.ui.extension.UiExtensionMapping;
+import org.apache.nifi.web.UiExtensionType;
import org.apache.nifi.web.api.dto.ControllerServiceDTO;
import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO;
import org.apache.nifi.web.api.entity.ControllerServiceEntity;
@@ -75,6 +79,9 @@ public class ControllerServiceResource extends ApplicationResource {
private WebClusterManager clusterManager;
private NiFiProperties properties;
+ @Context
+ private ServletContext servletContext;
+
/**
* Populates the uri for the specified controller service.
*
@@ -95,6 +102,18 @@ public class ControllerServiceResource extends ApplicationResource {
// populate the controller service href
controllerService.setUri(generateResourceUri("controller", "controller-services", availability, controllerService.getId()));
controllerService.setAvailability(availability);
+
+ // see if this processor has any ui extensions
+ final UiExtensionMapping uiExtensionMapping = (UiExtensionMapping) servletContext.getAttribute("nifi-ui-extensions");
+ if (uiExtensionMapping.hasUiExtension(controllerService.getType())) {
+ final List<UiExtension> uiExtensions = uiExtensionMapping.getUiExtension(controllerService.getType());
+ for (final UiExtension uiExtension : uiExtensions) {
+ if (UiExtensionType.ProcessorConfiguration.equals(uiExtension.getExtensionType())) {
+ controllerService.setCustomUiUrl(uiExtension.getContextPath() + "/configure");
+ }
+ }
+ }
+
return controllerService;
}
http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/24d787e5/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
----------------------------------------------------------------------
diff --git a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
index 75995dd..6fa6f21 100644
--- a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
+++ b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/api/ProcessorResource.java
@@ -70,6 +70,9 @@ import org.apache.nifi.web.api.request.IntegerParameter;
import org.apache.nifi.web.api.request.LongParameter;
import org.apache.commons.lang3.StringUtils;
+import org.apache.nifi.ui.extension.UiExtension;
+import org.apache.nifi.ui.extension.UiExtensionMapping;
+import org.apache.nifi.web.UiExtensionType;
import org.codehaus.enunciate.jaxrs.TypeHint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -118,9 +121,21 @@ public class ProcessorResource extends ApplicationResource {
// get the config details and see if there is a custom ui for this processor type
ProcessorConfigDTO config = processor.getConfig();
if (config != null) {
+ // consider legacy custom ui fist
String customUiUrl = servletContext.getInitParameter(processor.getType());
if (StringUtils.isNotBlank(customUiUrl)) {
config.setCustomUiUrl(customUiUrl);
+ } else {
+ // see if this processor has any ui extensions
+ final UiExtensionMapping uiExtensionMapping = (UiExtensionMapping) servletContext.getAttribute("nifi-ui-extensions");
+ if (uiExtensionMapping.hasUiExtension(processor.getType())) {
+ final List<UiExtension> uiExtensions = uiExtensionMapping.getUiExtension(processor.getType());
+ for (final UiExtension uiExtension : uiExtensions) {
+ if (UiExtensionType.ProcessorConfiguration.equals(uiExtension.getExtensionType())) {
+ config.setCustomUiUrl(uiExtension.getContextPath() + "/configure");
+ }
+ }
+ }
}
}