You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by ma...@apache.org on 2019/09/06 19:20:52 UTC

[nifi] branch master updated: NIFI-6384: - Adding auditing of parameter contexts.

This is an automated email from the ASF dual-hosted git repository.

markap14 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nifi.git


The following commit(s) were added to refs/heads/master by this push:
     new f867e92  NIFI-6384: - Adding auditing of parameter contexts.
f867e92 is described below

commit f867e9260656bad306612b0a94219370c8390525
Author: Matt Gilman <ma...@gmail.com>
AuthorDate: Tue Sep 3 16:38:35 2019 -0400

    NIFI-6384:
    - Adding auditing of parameter contexts.
    
    This closes #3699.
    
    Signed-off-by: Mark Payne <ma...@hotmail.com>
---
 .../java/org/apache/nifi/action/Component.java     |   1 +
 .../apache/nifi/audit/ParameterContextAuditor.java | 284 +++++++++++++++++++++
 .../org/apache/nifi/audit/ProcessGroupAuditor.java |  35 ++-
 .../apache/nifi/web/StandardNiFiServiceFacade.java |   3 +
 .../src/main/resources/nifi-web-api-context.xml    |   5 +
 5 files changed, 326 insertions(+), 2 deletions(-)

diff --git a/nifi-api/src/main/java/org/apache/nifi/action/Component.java b/nifi-api/src/main/java/org/apache/nifi/action/Component.java
index a25525f..95d8ba0 100644
--- a/nifi-api/src/main/java/org/apache/nifi/action/Component.java
+++ b/nifi-api/src/main/java/org/apache/nifi/action/Component.java
@@ -31,6 +31,7 @@ public enum Component {
     Connection,
     ControllerService,
     ReportingTask,
+    ParameterContext,
     AccessPolicy,
     User,
     UserGroup;
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ParameterContextAuditor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ParameterContextAuditor.java
new file mode 100644
index 0000000..223ada6
--- /dev/null
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ParameterContextAuditor.java
@@ -0,0 +1,284 @@
+/*
+ * 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.audit;
+
+import org.apache.nifi.action.Action;
+import org.apache.nifi.action.Component;
+import org.apache.nifi.action.FlowChangeAction;
+import org.apache.nifi.action.Operation;
+import org.apache.nifi.action.details.FlowChangeConfigureDetails;
+import org.apache.nifi.authorization.user.NiFiUser;
+import org.apache.nifi.authorization.user.NiFiUserUtils;
+import org.apache.nifi.parameter.Parameter;
+import org.apache.nifi.parameter.ParameterContext;
+import org.apache.nifi.web.api.dto.ParameterContextDTO;
+import org.apache.nifi.web.api.dto.ParameterDTO;
+import org.apache.nifi.web.dao.ParameterContextDAO;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Audits processor creation/removal and configuration changes.
+ */
+@Aspect
+public class ParameterContextAuditor extends NiFiAuditor {
+
+    private static final Logger logger = LoggerFactory.getLogger(ParameterContextAuditor.class);
+
+    /**
+     * Audits the creation of parameter contexts via createParameterContext().
+     *
+     * @param proceedingJoinPoint join point
+     * @param parameterContextDTO dto
+     * @param parameterContextDAO dao
+     * @return context
+     * @throws Throwable ex
+     */
+    @Around("within(org.apache.nifi.web.dao.ParameterContextDAO+) && "
+            + "execution(org.apache.nifi.parameter.ParameterContext createParameterContext(org.apache.nifi.web.api.dto.ParameterContextDTO)) && "
+            + "args(parameterContextDTO) && "
+            + "target(parameterContextDAO)")
+    public ParameterContext createParameterContextAdvice(ProceedingJoinPoint proceedingJoinPoint, ParameterContextDTO parameterContextDTO, ParameterContextDAO parameterContextDAO) throws Throwable {
+        // update the processor state
+        ParameterContext parameterContext = (ParameterContext) proceedingJoinPoint.proceed();
+
+        // get the current user
+        NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+        // ensure the user was found
+        if (user != null) {
+            // create a parameter context action
+            Collection<Action> actions = new ArrayList<>();
+
+            // if no exceptions were thrown, add the processor action...
+            final Action createAction = generateAuditRecord(parameterContext, Operation.Add);
+            actions.add(createAction);
+
+            // determine the updated values
+            Map<String, String> updatedValues = extractConfiguredParameterContextValues(parameterContext, parameterContextDTO);
+
+            // determine the actions performed in this request
+            final Date actionTimestamp = new Date(createAction.getTimestamp().getTime() + 1);
+            determineActions(user, parameterContext, actions, actionTimestamp, updatedValues, Collections.EMPTY_MAP);
+
+            // save the actions
+            saveActions(actions, logger);
+        }
+
+        return parameterContext;
+    }
+
+    /**
+     * Audits the configuration of a parameter context via updateParameterContext().
+     *
+     * @param proceedingJoinPoint join point
+     * @param parameterContextDTO dto
+     * @param parameterContextDAO dao
+     * @return parameter context
+     * @throws Throwable ex
+     */
+    @Around("within(org.apache.nifi.web.dao.ParameterContextDAO+) && "
+            + "execution(org.apache.nifi.parameter.ParameterContext updateParameterContext(org.apache.nifi.web.api.dto.ParameterContextDTO)) && "
+            + "args(parameterContextDTO) && "
+            + "target(parameterContextDAO)")
+    public ParameterContext updateParameterContextAdvice(ProceedingJoinPoint proceedingJoinPoint, ParameterContextDTO parameterContextDTO, ParameterContextDAO parameterContextDAO) throws Throwable {
+        // determine the initial values for each property/setting that's changing
+        ParameterContext parameterContext = parameterContextDAO.getParameterContext(parameterContextDTO.getId());
+        final Map<String, String> values = extractConfiguredParameterContextValues(parameterContext, parameterContextDTO);
+
+        // update the processor state
+        final ParameterContext updatedParameterContext = (ParameterContext) proceedingJoinPoint.proceed();
+
+        // if no exceptions were thrown, add the processor action...
+        parameterContext = parameterContextDAO.getParameterContext(updatedParameterContext.getIdentifier());
+
+        // get the current user
+        NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+        // ensure the user was found
+        if (user != null) {
+            // determine the updated values
+            Map<String, String> updatedValues = extractConfiguredParameterContextValues(parameterContext, parameterContextDTO);
+
+            // create a parameter context action
+            Date actionTimestamp = new Date();
+            Collection<Action> actions = new ArrayList<>();
+
+            // determine the actions performed in this request
+            determineActions(user, parameterContext, actions, actionTimestamp, updatedValues, values);
+
+            // ensure there are actions to record
+            if (!actions.isEmpty()) {
+                // save the actions
+                saveActions(actions, logger);
+            }
+        }
+
+        return updatedParameterContext;
+    }
+
+    /**
+     * Extract configuration changes.
+     *
+     * @param user the user
+     * @param parameterContext the parameter context
+     * @param actions actions list
+     * @param actionTimestamp timestamp of the request
+     * @param updatedValues the updated values
+     * @param values the current values
+     */
+    private void determineActions(final NiFiUser user, final ParameterContext parameterContext, final Collection<Action> actions,
+                                   final Date actionTimestamp, final Map<String, String> updatedValues, final Map<String, String> values) {
+
+        // go through each updated value
+        for (String key : updatedValues.keySet()) {
+            String newValue = updatedValues.get(key);
+            String oldValue = values.get(key);
+            Operation operation = null;
+
+            // determine the type of operation
+            if (oldValue == null || newValue == null || !newValue.equals(oldValue)) {
+                operation = Operation.Configure;
+            }
+
+            // create a configuration action accordingly
+            if (operation != null) {
+                // clear the value if this property is sensitive
+                final Parameter parameter = parameterContext.getParameter(key).orElse(null);
+                if (parameter != null && parameter.getDescriptor().isSensitive()) {
+                    if (newValue != null) {
+                        newValue = "********";
+                    }
+                    if (oldValue != null) {
+                        oldValue = "********";
+                    }
+                }
+
+                final FlowChangeConfigureDetails actionDetails = new FlowChangeConfigureDetails();
+                actionDetails.setName(key);
+                actionDetails.setValue(newValue);
+                actionDetails.setPreviousValue(oldValue);
+
+                // create a configuration action
+                FlowChangeAction configurationAction = new FlowChangeAction();
+                configurationAction.setUserIdentity(user.getIdentity());
+                configurationAction.setOperation(operation);
+                configurationAction.setTimestamp(actionTimestamp);
+                configurationAction.setSourceId(parameterContext.getIdentifier());
+                configurationAction.setSourceName(parameterContext.getName());
+                configurationAction.setSourceType(Component.ParameterContext);
+                configurationAction.setActionDetails(actionDetails);
+                actions.add(configurationAction);
+            }
+        }
+    }
+
+    /**
+     * Audits the removal of a parameter context via deleteParameterContext().
+     *
+     * @param proceedingJoinPoint join point
+     * @param parameterContextId parameterContextId
+     * @param parameterContextDAO dao
+     * @throws Throwable ex
+     */
+    @Around("within(org.apache.nifi.web.dao.ParameterContextDAO+) && "
+            + "execution(void deleteParameterContext(java.lang.String)) && "
+            + "args(parameterContextId) && "
+            + "target(parameterContextDAO)")
+    public void removeParameterContextAdvice(ProceedingJoinPoint proceedingJoinPoint, String parameterContextId, ParameterContextDAO parameterContextDAO) throws Throwable {
+        // get the parameter context before removing it
+        ParameterContext parameterContext = parameterContextDAO.getParameterContext(parameterContextId);
+
+        // remove the processor
+        proceedingJoinPoint.proceed();
+
+        // if no exceptions were thrown, add removal actions...
+        // audit the processor removal
+        final Action action = generateAuditRecord(parameterContext, Operation.Remove);
+
+        // save the actions
+        if (action != null) {
+            saveAction(action, logger);
+        }
+    }
+
+    /**
+     * Generates an audit record for the creation of a ParameterContext.
+     *
+     * @param parameterContext parameterContext
+     * @param operation operation
+     * @return action
+     */
+    private Action generateAuditRecord(ParameterContext parameterContext, Operation operation) {
+        FlowChangeAction action = null;
+
+        // get the current user
+        NiFiUser user = NiFiUserUtils.getNiFiUser();
+
+        // ensure the user was found
+        if (user != null) {
+            // create the processor action for adding this processor
+            action = new FlowChangeAction();
+            action.setUserIdentity(user.getIdentity());
+            action.setOperation(operation);
+            action.setTimestamp(new Date());
+            action.setSourceId(parameterContext.getIdentifier());
+            action.setSourceName(parameterContext.getName());
+            action.setSourceType(Component.ParameterContext);
+        }
+
+        return action;
+    }
+
+    /**
+     * Extracts the values for the configured fields from the specified ParameterContext.
+     */
+    private Map<String, String> extractConfiguredParameterContextValues(ParameterContext parameterContext, ParameterContextDTO parameterContextDTO) {
+        Map<String, String> values = new HashMap<>();
+
+        if (parameterContextDTO.getDescription() != null) {
+            values.put("Name", parameterContext.getName());
+        }
+        if (parameterContextDTO.getDescription() != null) {
+            values.put("Description", parameterContext.getDescription());
+        }
+        if (parameterContextDTO.getParameters() != null) {
+            parameterContextDTO.getParameters().forEach(parameterEntity -> {
+                final ParameterDTO parameterDTO = parameterEntity.getParameter();
+                final Parameter parameter = parameterContext.getParameter(parameterDTO.getName()).orElse(null);
+                if (parameter == null) {
+                    values.put(parameterDTO.getName(), null);
+                } else {
+                    values.put(parameterDTO.getName(), parameter.getValue());
+                }
+            });
+        }
+
+        return values;
+    }
+
+}
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
index 3d92f5b..c1b43aa 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/audit/ProcessGroupAuditor.java
@@ -28,6 +28,7 @@ import org.apache.nifi.authorization.user.NiFiUserUtils;
 import org.apache.nifi.controller.ScheduledState;
 import org.apache.nifi.controller.service.ControllerServiceState;
 import org.apache.nifi.groups.ProcessGroup;
+import org.apache.nifi.parameter.ParameterContext;
 import org.apache.nifi.registry.flow.VersionControlInformation;
 import org.apache.nifi.web.api.dto.ProcessGroupDTO;
 import org.apache.nifi.web.api.dto.VariableRegistryDTO;
@@ -97,6 +98,7 @@ public class ProcessGroupAuditor extends NiFiAuditor {
         ProcessGroup processGroup = processGroupDAO.getProcessGroup(processGroupDTO.getId());
 
         String name = processGroup.getName();
+        ParameterContext parameterContext = processGroup.getParameterContext();
         String comments = processGroup.getComments();
 
         // perform the underlying operation
@@ -113,7 +115,7 @@ public class ProcessGroupAuditor extends NiFiAuditor {
             if (name != null && updatedProcessGroup.getName() != null && !name.equals(updatedProcessGroup.getName())) {
                 // create the config details
                 FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
-                configDetails.setName("name");
+                configDetails.setName("Name");
                 configDetails.setValue(updatedProcessGroup.getName());
                 configDetails.setPreviousValue(name);
 
@@ -124,13 +126,42 @@ public class ProcessGroupAuditor extends NiFiAuditor {
             if (comments != null && updatedProcessGroup.getComments() != null && !comments.equals(updatedProcessGroup.getComments())) {
                 // create the config details
                 FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
-                configDetails.setName("comments");
+                configDetails.setName("Comments");
                 configDetails.setValue(updatedProcessGroup.getComments());
                 configDetails.setPreviousValue(comments);
 
                 details.add(configDetails);
             }
 
+            // see if the parameter context has changed
+            if (parameterContext != null && updatedProcessGroup.getParameterContext() != null) {
+                if (!parameterContext.getIdentifier().equals(updatedProcessGroup.getParameterContext().getIdentifier())) {
+                    // create the config details
+                    FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
+                    configDetails.setName("Parameter Context");
+                    configDetails.setValue(updatedProcessGroup.getParameterContext().getIdentifier());
+                    configDetails.setPreviousValue(parameterContext.getIdentifier());
+
+                    details.add(configDetails);
+                }
+            } else if (updatedProcessGroup.getParameterContext() != null) {
+                // create the config details
+                FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
+                configDetails.setName("Parameter Context");
+                configDetails.setValue(updatedProcessGroup.getParameterContext().getIdentifier());
+                configDetails.setPreviousValue(null);
+
+                details.add(configDetails);
+            } else if (parameterContext != null) {
+                // create the config details
+                FlowChangeConfigureDetails configDetails = new FlowChangeConfigureDetails();
+                configDetails.setName("Parameter Context");
+                configDetails.setValue(null);
+                configDetails.setPreviousValue(parameterContext.getIdentifier());
+
+                details.add(configDetails);
+            }
+
             // hold all actions
             Collection<Action> actions = new ArrayList<>();
 
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
index 8ebeec9..1dba3f1 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java
@@ -5016,6 +5016,9 @@ public class StandardNiFiServiceFacade implements NiFiServiceFacade {
                 case Connection:
                     authorizable = authorizableLookup.getConnection(sourceId).getAuthorizable();
                     break;
+                case ParameterContext:
+                    authorizable = authorizableLookup.getParameterContext(sourceId);
+                    break;
                 case AccessPolicy:
                     authorizable = authorizableLookup.getAccessPolicyById(sourceId);
                     break;
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
index c2b2b68..72ffc2c 100644
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
+++ b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-api/src/main/resources/nifi-web-api-context.xml
@@ -546,6 +546,11 @@
         <property name="auditService" ref="auditService"/>
         <property name="processGroupDAO" ref="processGroupDAO"/>
     </bean>
+    <bean id="parameterContextAuditor" class="org.apache.nifi.audit.ParameterContextAuditor">
+        <property name="serviceFacade" ref="serviceFacade"/>
+        <property name="auditService" ref="auditService"/>
+        <property name="processGroupDAO" ref="processGroupDAO"/>
+    </bean>
     <bean id="policyAuditor" class="org.apache.nifi.audit.AccessPolicyAuditor">
         <property name="serviceFacade" ref="serviceFacade"/>
         <property name="auditService" ref="auditService"/>