Merge branch 'develop' into NIFI-250

Conflicts:
        
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
        
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
        
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
        
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml


Project: http://git-wip-us.apache.org/repos/asf/incubator-nifi/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-nifi/commit/65e35e49
Tree: http://git-wip-us.apache.org/repos/asf/incubator-nifi/tree/65e35e49
Diff: http://git-wip-us.apache.org/repos/asf/incubator-nifi/diff/65e35e49

Branch: refs/heads/NIFI-250
Commit: 65e35e49a5bb1d81cf0933220bf1204131dc72d5
Parents: a4555d1 e05c9fd
Author: Matt Gilman <[email protected]>
Authored: Mon Mar 23 08:09:33 2015 -0400
Committer: Matt Gilman <[email protected]>
Committed: Mon Mar 23 08:09:33 2015 -0400

----------------------------------------------------------------------
 .../annotation/behavior/DynamicProperties.java  |  42 +++
 .../annotation/behavior/DynamicProperty.java    |  67 ++++
 .../behavior/DynamicRelationship.java           |  56 ++++
 .../annotation/behavior/ReadsAttribute.java     |  50 +++
 .../annotation/behavior/ReadsAttributes.java    |  44 +++
 .../annotation/behavior/WritesAttribute.java    |  51 +++
 .../annotation/behavior/WritesAttributes.java   |  44 +++
 .../nifi/annotation/documentation/SeeAlso.java  |  59 ++++
 .../apache/nifi/processor/ProcessSession.java   |  40 ++-
 .../org/apache/nifi/web/ViewableContent.java    |  74 +++++
 nifi/nifi-assembly/pom.xml                      |   1 -
 .../nifi/processor/util/StandardValidators.java |  22 ++
 .../processor/util/TestStandardValidators.java  |  31 ++
 .../src/main/asciidoc/developer-guide.adoc      |  35 ++
 .../html/HtmlDocumentationWriter.java           | 271 ++++++++++++----
 .../html/HtmlProcessorDocumentationWriter.java  | 207 ++++++++++++
 .../example/FullyDocumentedProcessor.java       |  15 +-
 .../org/apache/nifi/groups/ProcessGroup.java    |  44 ++-
 .../apache/nifi/controller/FlowController.java  |  77 +++--
 .../nifi/controller/StandardFlowService.java    |  21 +-
 .../controller/StandardFlowSynchronizer.java    |   6 +-
 .../repository/StandardProcessSession.java      |  11 +-
 .../io/DisableOnCloseInputStream.java           |  93 ++++++
 .../nifi/groups/StandardProcessGroup.java       |  58 +---
 .../repository/TestStandardProcessSession.java  | 149 +++++++++
 .../nifi-framework/nifi-web/nifi-jetty/pom.xml  |  10 +
 .../org/apache/nifi/web/server/JettyServer.java | 112 +++++--
 .../nifi-web/nifi-web-api/pom.xml               |   5 +
 .../org/apache/nifi/web/NiFiServiceFacade.java  |   1 -
 .../nifi/web/StandardNiFiContentAccess.java     | 141 ++++++++
 .../nifi/web/StandardNiFiServiceFacade.java     |   1 -
 .../apache/nifi/web/StandardNiFiWebContext.java |   2 +-
 .../apache/nifi/web/api/ProvenanceResource.java |   2 +-
 .../ApplicationStartupContextListener.java      |   6 +-
 .../nifi/web/controller/ControllerFacade.java   |   8 +-
 .../nifi/web/util/DownloadableContent.java      |  47 ---
 .../src/main/resources/nifi-web-api-context.xml |   7 +
 .../nifi-web/nifi-web-content-access/pom.xml    |  25 ++
 .../java/org/apache/nifi/web/ContentAccess.java |  33 ++
 .../apache/nifi/web/ContentRequestContext.java  |  51 +++
 .../apache/nifi/web/DownloadableContent.java    |  62 ++++
 .../nifi-web/nifi-web-content-viewer/.gitignore |   1 +
 .../nifi-web/nifi-web-content-viewer/pom.xml    |  91 ++++++
 .../nifi/web/ContentViewerController.java       | 284 +++++++++++++++++
 .../src/main/resources/META-INF/NOTICE          |  19 ++
 .../src/main/webapp/WEB-INF/jsp/footer.jsp      |  20 ++
 .../src/main/webapp/WEB-INF/jsp/header.jsp      |  92 ++++++
 .../src/main/webapp/WEB-INF/jsp/hexview.jsp     |  32 ++
 .../src/main/webapp/WEB-INF/jsp/no-viewer.jsp   |  20 ++
 .../src/main/webapp/WEB-INF/web.xml             |  26 ++
 .../src/main/webapp/css/main.css                | 113 +++++++
 .../src/main/webapp/js/hexview/LICENSE          |  32 ++
 .../main/webapp/js/hexview/hexview.default.css  |  10 +
 .../src/main/webapp/js/hexview/hexview.js       | 199 ++++++++++++
 .../nifi-web-ui/src/main/webapp/WEB-INF/web.xml |  11 +
 .../js/codemirror/addon/fold/foldgutter.css     |  20 ++
 .../js/codemirror/lib/codemirror-compressed.js  |  14 +-
 .../webapp/js/jquery/combo/jquery.combo.css     |   8 +
 .../nifi-framework/nifi-web/pom.xml             |   6 +-
 .../nifi-framework-bundle/pom.xml               |   5 +
 .../hadoop/CreateHadoopSequenceFile.java        |   2 +
 .../apache/nifi/processors/hadoop/GetHDFS.java  |  21 +-
 .../processors/hadoop/GetHDFSSequenceFile.java  |   2 +
 .../apache/nifi/processors/hadoop/PutHDFS.java  |  20 +-
 .../additionalDetails.html                      |   7 -
 .../additionalDetails.html                      |  57 ----
 .../additionalDetails.html                      |  32 --
 .../additionalDetails.html                      |  51 ---
 .../apache/nifi/processors/kafka/GetKafka.java  |   6 +
 .../apache/nifi/processors/kafka/PutKafka.java  |  90 +++---
 .../additionalDetails.html                      |  33 --
 .../nifi/processors/kafka/TestPutKafka.java     |  76 ++++-
 .../TestPersistentProvenanceRepository.java     |  42 +--
 .../nifi-standard-content-viewer/pom.xml        |  71 +++++
 .../web/StandardContentViewerController.java    | 103 ++++++
 .../src/main/resources/META-INF/NOTICE          |  19 ++
 .../main/webapp/META-INF/nifi-content-viewer    |   3 +
 .../src/main/webapp/WEB-INF/jsp/codemirror.jsp  |  47 +++
 .../src/main/webapp/WEB-INF/web.xml             |  29 ++
 .../src/main/webapp/css/main.css                |  20 ++
 .../nifi-standard-nar/pom.xml                   |   5 +
 .../standard/Base64EncodeContent.java           |   2 +-
 .../processors/standard/CompressContent.java    |   4 +
 .../processors/standard/DetectDuplicate.java    |  15 +-
 .../processors/standard/DistributeLoad.java     |  22 +-
 .../processors/standard/EvaluateJsonPath.java   |   5 +
 .../standard/EvaluateRegularExpression.java     |  19 +-
 .../nifi/processors/standard/EvaluateXPath.java |   5 +
 .../processors/standard/EvaluateXQuery.java     |  22 +-
 .../processors/standard/ExecuteProcess.java     |   2 +
 .../standard/ExecuteStreamCommand.java          |  25 +-
 .../nifi/processors/standard/ExtractText.java   | 316 ++++++++++++++++++
 .../apache/nifi/processors/standard/GetFTP.java |  12 +
 .../nifi/processors/standard/GetFile.java       |  21 +-
 .../nifi/processors/standard/GetHTTP.java       |   8 +-
 .../nifi/processors/standard/GetJMSQueue.java   |   2 +
 .../nifi/processors/standard/GetJMSTopic.java   |   2 +
 .../nifi/processors/standard/GetSFTP.java       |  17 +-
 .../processors/standard/HandleHttpRequest.java  |  19 ++
 .../processors/standard/HandleHttpResponse.java |   6 +
 .../nifi/processors/standard/HashAttribute.java |  23 +-
 .../nifi/processors/standard/HashContent.java   |   2 +
 .../processors/standard/IdentifyMimeType.java   |  13 +-
 .../nifi/processors/standard/InvokeHTTP.java    |  21 +-
 .../nifi/processors/standard/MergeContent.java  |  17 +
 .../processors/standard/MonitorActivity.java    |  15 +-
 .../nifi/processors/standard/PostHTTP.java      |  12 +-
 .../apache/nifi/processors/standard/PutFTP.java |  22 +-
 .../nifi/processors/standard/PutFile.java       |   8 +-
 .../apache/nifi/processors/standard/PutJMS.java |   6 +-
 .../nifi/processors/standard/PutSFTP.java       |  10 +-
 .../processors/standard/RouteOnAttribute.java   |  15 +-
 .../processors/standard/RouteOnContent.java     |   5 +
 .../nifi/processors/standard/ScanContent.java   |  18 +-
 .../processors/standard/SegmentContent.java     |  12 +
 .../nifi/processors/standard/SplitContent.java  |  23 +-
 .../nifi/processors/standard/SplitText.java     |  10 +
 .../nifi/processors/standard/TransformXml.java  |  15 +-
 .../nifi/processors/standard/UnpackContent.java |  37 ++-
 .../org.apache.nifi.processor.Processor         |   1 +
 .../additionalDetails.html                      |  68 ----
 .../additionalDetails.html                      |  58 ----
 .../additionalDetails.html                      |  40 ---
 .../additionalDetails.html                      |  27 --
 .../additionalDetails.html                      |  34 --
 .../additionalDetails.html                      |  18 +-
 .../additionalDetails.html                      |  57 ----
 .../additionalDetails.html                      |  74 -----
 .../additionalDetails.html                      |  79 -----
 .../additionalDetails.html                      |  45 ---
 .../additionalDetails.html                      |  80 -----
 .../additionalDetails.html                      |  86 +----
 .../additionalDetails.html                      |  13 -
 .../additionalDetails.html                      |  35 --
 .../additionalDetails.html                      |  35 --
 .../additionalDetails.html                      |  51 +--
 .../additionalDetails.html                      |  64 ----
 .../additionalDetails.html                      | 115 -------
 .../additionalDetails.html                      |  49 ---
 .../additionalDetails.html                      |  48 ---
 .../additionalDetails.html                      |  48 ---
 .../additionalDetails.html                      |  34 --
 .../additionalDetails.html                      |  45 ---
 .../additionalDetails.html                      |  82 -----
 .../additionalDetails.html                      |  67 ----
 .../additionalDetails.html                      |  72 -----
 .../additionalDetails.html                      | 106 ------
 .../standard/TestEvaluateRegularExpression.java | 319 -------------------
 .../processors/standard/TestExtractText.java    | 314 ++++++++++++++++++
 .../nifi-standard-bundle/pom.xml                |  10 +-
 .../DistributedMapCacheClientService.java       |   2 +
 .../DistributedSetCacheClientService.java       |   2 +
 .../additionalDetails.html                      |   7 -
 .../additionalDetails.html                      |  31 --
 .../server/map/DistributedMapCacheServer.java   |   2 +
 .../additionalDetails.html                      |   7 -
 .../processors/attributes/UpdateAttribute.java  |   5 +
 157 files changed, 4313 insertions(+), 2545 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
----------------------------------------------------------------------
diff --cc 
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
index 3b8dd06,06ef203..b396039
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/FlowController.java
@@@ -583,43 -576,57 +583,60 @@@ public class FlowController implements 
       * flag of true to now start
       * </p>
       */
-     public void startDelayed() {
+     public void onFlowInitialized(final boolean startDelayedComponents) {
          writeLock.lock();
          try {
-             LOG.info("Starting {} processors/ports/funnels", 
(startConnectablesAfterInitialization.size() + 
startRemoteGroupPortsAfterInitialization.size()));
-             for (final Connectable connectable : 
startConnectablesAfterInitialization) {
-                 if (connectable.getScheduledState() == 
ScheduledState.DISABLED) {
-                     continue;
-                 }
- 
-                 try {
-                     if (connectable instanceof ProcessorNode) {
-                         
connectable.getProcessGroup().startProcessor((ProcessorNode) connectable);
-                     } else {
-                         startConnectable(connectable);
+             if ( startDelayedComponents ) {
+                 LOG.info("Starting {} processors/ports/funnels", 
(startConnectablesAfterInitialization.size() + 
startRemoteGroupPortsAfterInitialization.size()));
+                 for (final Connectable connectable : 
startConnectablesAfterInitialization) {
+                     if (connectable.getScheduledState() == 
ScheduledState.DISABLED) {
+                         continue;
                      }
-                 } catch (final Throwable t) {
-                     LOG.error("Unable to start {} due to {}", new 
Object[]{connectable, t.toString()});
-                     if ( LOG.isDebugEnabled() ) {
-                         LOG.error("", t);
+     
+                     try {
+                         if (connectable instanceof ProcessorNode) {
+                             
connectable.getProcessGroup().startProcessor((ProcessorNode) connectable);
+                         } else {
+                             startConnectable(connectable);
+                         }
+                     } catch (final Throwable t) {
 -                        LOG.error("Unable to start {} due to {}", new 
Object[]{connectable, t});
++                        LOG.error("Unable to start {} due to {}", new 
Object[]{connectable, t.toString()});
++                        if ( LOG.isDebugEnabled() ) {
++                            LOG.error("", t);
++                        }
                      }
                  }
-             }
- 
-             startConnectablesAfterInitialization.clear();
- 
-             int startedTransmitting = 0;
-             for (final RemoteGroupPort remoteGroupPort : 
startRemoteGroupPortsAfterInitialization) {
-                 try {
-                     
remoteGroupPort.getRemoteProcessGroup().startTransmitting(remoteGroupPort);
-                     startedTransmitting++;
-                 } catch (final Throwable t) {
-                     LOG.error("Unable to start transmitting with {} due to 
{}", new Object[]{remoteGroupPort, t});
+     
+                 startConnectablesAfterInitialization.clear();
+     
+                 int startedTransmitting = 0;
+                 for (final RemoteGroupPort remoteGroupPort : 
startRemoteGroupPortsAfterInitialization) {
+                     try {
+                         
remoteGroupPort.getRemoteProcessGroup().startTransmitting(remoteGroupPort);
+                         startedTransmitting++;
+                     } catch (final Throwable t) {
+                         LOG.error("Unable to start transmitting with {} due 
to {}", new Object[]{remoteGroupPort, t});
+                     }
                  }
+     
+                 LOG.info("Started {} Remote Group Ports transmitting", 
startedTransmitting);
+                 startRemoteGroupPortsAfterInitialization.clear();
+             } else {
+                 // We don't want to start all of the delayed components. 
However, funnels need to be started anyway
+                 // because we don't provide users the ability to start or 
stop them - they are just notional.
+                 for (final Connectable connectable : 
startConnectablesAfterInitialization) {
+                     try {
+                         if (connectable instanceof Funnel) {
+                             startConnectable(connectable);
+                         }
+                     } catch (final Throwable t) {
+                         LOG.error("Unable to start {} due to {}", new 
Object[]{connectable, t});
+                     }
+                 }
+                 
+                 startConnectablesAfterInitialization.clear();
+                 startRemoteGroupPortsAfterInitialization.clear();
              }
- 
-             LOG.info("Started {} Remote Group Ports transmitting", 
startedTransmitting);
-             startRemoteGroupPortsAfterInitialization.clear();
          } finally {
              writeLock.unlock();
          }

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowService.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/StandardFlowSynchronizer.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/groups/StandardProcessGroup.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
----------------------------------------------------------------------
diff --cc 
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-jetty/src/main/java/org/apache/nifi/web/server/JettyServer.java
index b9f0f7e,54111a1..16a213d
--- 
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,10 -52,7 +52,11 @@@ import org.apache.nifi.util.NiFiPropert
  import org.apache.nifi.web.NiFiWebContext;
  import org.apache.commons.collections4.CollectionUtils;
  import org.apache.commons.lang3.StringUtils;
+ import org.apache.nifi.web.ContentAccess;
 +import org.apache.nifi.ui.extension.UiExtension;
 +import org.apache.nifi.ui.extension.UiExtensionMapping;
 +import org.apache.nifi.web.NiFiWebConfigurationContext;
 +import org.apache.nifi.web.UiExtensionType;
  import org.eclipse.jetty.server.Connector;
  import org.eclipse.jetty.server.Handler;
  import org.eclipse.jetty.server.HttpConfiguration;
@@@ -103,14 -100,11 +104,16 @@@ public class JettyServer implements NiF
      private ExtensionMapping extensionMapping;
      private WebAppContext webApiContext;
      private WebAppContext webDocsContext;
+     private WebAppContext webContentViewerContext;
 -    private Collection<WebAppContext> customUiWebContexts;
+     private Collection<WebAppContext> contentViewerWebContexts;
      private final NiFiProperties props;
  
 +    private UiExtensionMapping uiExtensions;
 +    private Collection<WebAppContext> uiExtensionWebContexts;
 +    
 +    @Deprecated
 +    private Collection<WebAppContext> customUiWebContexts;
 +    
      /**
       * Creates and configures a new Jetty instance.
       *
@@@ -204,29 -205,18 +214,33 @@@
          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<>();
+             contentViewerWebContexts = 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);
+                 List<String> customUiProcessorTypes = getWarExtensions(war, 
"META-INF/nifi-processor");
 -                List<String> contentViewerMimeTypes = getWarExtensions(war, 
"META-INF/nifi-content-viewer");
  
 -                // only include wars that are for extensions
 -                if (!customUiProcessorTypes.isEmpty() || 
!contentViewerMimeTypes.isEmpty()) {
++                // see if this war is a custom processor ui
++                List<String> contentViewerMimeTypes = getWarExtensions(war, 
"META-INF/nifi-content-viewer");
++                
 +                // 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) || 
!uiExtensionInWar.isEmpty()) {
++                if (!customUiProcessorTypes.isEmpty() || 
!uiExtensionInWar.isEmpty() || !contentViewerMimeTypes.isEmpty()) {
 +                    // get the context path
                      String warName = 
StringUtils.substringBeforeLast(war.getName(), ".");
                      String warContextPath = String.format("/%s", warName);
  
@@@ -238,57 -228,30 +252,63 @@@
                          narClassLoaderForWar = jettyClassLoader;
                      }
  
-                     // create the custom ui web app context
-                     WebAppContext customUiContext = loadWar(war, 
warContextPath, narClassLoaderForWar);
+                     // create the extension web app context
+                     WebAppContext extensionUiContext = loadWar(war, 
warContextPath, narClassLoaderForWar);
  
-                     // hold on to a reference to all custom ui web app 
contexts
-                     if (CollectionUtils.isNotEmpty(customUiProcessorTypes)) {
-                         customUiWebContexts.add(customUiContext);
+                     // also store it by type so we can populate the 
appropriate initialization parameters
+                     if (!customUiProcessorTypes.isEmpty()) {
+                         customUiWebContexts.add(extensionUiContext);
 -                    } else {
++                    } else if (!contentViewerMimeTypes.isEmpty()) {
+                         // record the mime type to web app mapping (need to 
handle type collision)
+                         contentViewerWebContexts.add(extensionUiContext);
 +                    } else {
-                         uiExtensionWebContexts.add(customUiContext);
++                        uiExtensionWebContexts.add(extensionUiContext);
                      }
  
 -                    // include custom ui web context in the handlers
 -                    handlers.addHandler(extensionUiContext);
 -
 +                    // 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);
+                         customUiMappings.put(customUiProcessorType, 
warContextPath);
+                     }
+                     for (final String contentViewerMimeType : 
contentViewerMimeTypes) {
+                         mimeTypeMappings.put(contentViewerMimeType, 
warContextPath);
                      }
 +                    
 +                    // include custom ui web context in the handlers
-                     handlers.addHandler(customUiContext);
++                    handlers.addHandler(extensionUiContext);
                  }
 +                
              }
 +            
 +            // record all ui extensions
 +            uiExtensions = new UiExtensionMapping(uiExtensionsByType);
 +        } else {
 +            uiExtensions = new UiExtensionMapping(Collections.EMPTY_MAP);
          }
  
          // load the web ui app
@@@ -348,74 -315,13 +372,73 @@@
          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 rawComponentType;
 +        while ((rawComponentType = in.readLine()) != null) {
 +            // extract the component type
 +            final String componentType = 
extractComponentType(rawComponentType);
 +            if (componentType != null) {
 +                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));
 +        }
 +    }
 +    
 +    /**
 +     * Extracts the component type. Trims the line and considers comments. 
Returns null if no type was found.
 +     * 
 +     * @param line
 +     * @return 
 +     */
 +    private String extractComponentType(final String line) {
 +        final String trimmedLine = line.trim();
 +        if (!trimmedLine.isEmpty() && !trimmedLine.startsWith("#")) {
 +            final int indexOfPound = trimmedLine.indexOf("#");
 +            return (indexOfPound > 0) ? trimmedLine.substring(0, 
indexOfPound) : trimmedLine;
 +        }
 +        return null;
 +    }
 +    
      /**
-      * Loads the processor types that the specified war file is a custom UI 
for.
+      * Returns the extension in the specified WAR using the specified path.
       *
-      * @param warFile
+      * @param war
       * @return
       */
-     @Deprecated
-     private List<String> getCustomUiProcessorTypes(final File warFile) {
+     private List<String> getWarExtensions(final File war, final String path) {
          List<String> processorTypes = new ArrayList<>();
          JarFile jarFile = null;
          try {
@@@ -662,21 -561,48 +685,48 @@@
  
              // 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)) {
+             if (webApiContext != null) {
                  final ServletContext webApiServletContext = 
webApiContext.getServletHandler().getServletContext();
                  final WebApplicationContext webApplicationContext = 
WebApplicationContextUtils.getRequiredWebApplicationContext(webApiServletContext);
-                 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);
- 
-                     // add the security filter to any custom ui wars
++                // @Deprecated
+                 if (CollectionUtils.isNotEmpty(customUiWebContexts)) {
+                     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);
+ 
+                         // add the security filter to any custom ui wars
+                         final FilterHolder securityFilter = 
webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
+                         if (securityFilter != null) {
+                             customUiContext.addFilter(securityFilter, "/*", 
EnumSet.of(DispatcherType.REQUEST));
+                         }
+                     }
+                 }
+                 
+                 if (CollectionUtils.isNotEmpty(contentViewerWebContexts)) {
+                     for (final WebAppContext contentViewerContext : 
contentViewerWebContexts) {
+                         // add the security filter to any content viewer  wars
+                         final FilterHolder securityFilter = 
webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
+                         if (securityFilter != null) {
+                             contentViewerContext.addFilter(securityFilter, 
"/*", EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, 
DispatcherType.INCLUDE));
+                         }
+                     }
+                 }
+                 
+                 // ensure the web content viewer war was loaded
+                 if (webContentViewerContext != null) {
+                     final ContentAccess contentAccess = 
webApplicationContext.getBean("contentAccess", ContentAccess.class);
+                     
+                     // add the content access
+                     final ServletContext webContentViewerServletContext = 
webContentViewerContext.getServletHandler().getServletContext();
+                     
webContentViewerServletContext.setAttribute("nifi-content-access", 
contentAccess);
+                     
 -                    // add the security filter to the content viewer 
controller
                      final FilterHolder securityFilter = 
webApiContext.getServletHandler().getFilter("springSecurityFilterChain");
                      if (securityFilter != null) {
-                         customUiContext.addFilter(securityFilter, "/*", 
EnumSet.of(DispatcherType.REQUEST));
+                         webContentViewerContext.addFilter(securityFilter, 
"/*", EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, 
DispatcherType.INCLUDE));
                      }
                  }
              }
@@@ -829,4 -735,4 +879,4 @@@
              logger.warn("Failed to stop web server", ex);
          }
      }
--}
++}

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/pom.xml
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/NiFiServiceFacade.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiWebContext.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/controller/ControllerFacade.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
----------------------------------------------------------------------
diff --cc 
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
index 3df231e,a822442..af733a5
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
@@@ -24,18 -24,19 +24,25 @@@
      http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.1.xsd
      http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd";>
  
 +    <!-- controller service / reporting task -->
 +    <bean id="controllerServiceProvider" 
class="org.apache.nifi.web.spring.ControllerServiceProviderFactoryBean" 
depends-on="clusterManager flowController">
 +        <property name="properties" ref="nifiProperties"/>
 +    </bean>
 +    <bean id="reportingTaskProvider" 
class="org.apache.nifi.web.spring.ReportingTaskProviderFactoryBean" 
depends-on="clusterManager flowController">
 +        <property name="properties" ref="nifiProperties"/>
 +    </bean>
 +    
      <!-- optimistic locking manager -->
 -    <bean id="optimisticLockingManager" 
class="org.apache.nifi.web.ClusterAwareOptimisticLockingManager">
 -        <constructor-arg>
 -            <bean 
class="org.apache.nifi.web.StandardOptimisticLockingManager" />
 -        </constructor-arg>
 +    <bean id="webOptimisticLockingManager" 
class="org.apache.nifi.web.spring.OptimisticLockingManagerFactoryBean" 
depends-on="clusterManagerOptimisticLockingManager">
 +        <property name="properties" ref="nifiProperties"/>
      </bean>
+     
+     <!-- content access -->
+     <bean id="contentAccess" 
class="org.apache.nifi.web.StandardNiFiContentAccess">
+         <property name="serviceFacade" ref="serviceFacade"/>
+         <property name="properties" ref="nifiProperties"/>
+         <property name="clusterManager" ref="clusterManager"/>
+     </bean>
  
      <!-- dto factory -->
      <bean id="dtoFactory" class="org.apache.nifi.web.api.dto.DtoFactory">

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
----------------------------------------------------------------------
diff --cc 
nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
index ac201e5,1218f6c..d9098f3
--- 
a/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
+++ 
b/nifi/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/pom.xml
@@@ -28,9 -29,10 +28,11 @@@
          <module>nifi-web-api</module>
          <module>nifi-web-error</module>
          <module>nifi-web-docs</module>
+         <module>nifi-web-content-viewer</module>
          <module>nifi-web-ui</module>
          <module>nifi-jetty</module>
+         <module>nifi-web-content-access</module>
 +        <module>nifi-ui-extension</module>
      </modules>
      <dependencyManagement>
          <dependencies>

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/src/main/java/org/apache/nifi/distributed/cache/client/DistributedMapCacheClientService.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-nifi/blob/65e35e49/nifi/nifi-nar-bundles/nifi-standard-services/nifi-distributed-cache-services-bundle/nifi-distributed-cache-client-service/src/main/java/org/apache/nifi/distributed/cache/client/DistributedSetCacheClientService.java
----------------------------------------------------------------------

Reply via email to