diff options
author | Vijay Venkatesh Kumar <vv770d@att.com> | 2020-03-20 17:30:51 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2020-03-20 17:30:51 +0000 |
commit | bcccdb62fe0dd1f7d9fb356363ef8889ebfdf5e8 (patch) | |
tree | 83cff89b2cebcbcd52a53901a2a4816ec5dfcf3a /mod/designtool/designtool-web/src/main | |
parent | 27507bb81f6bcfc66fd88d23b7b44ec2deffb027 (diff) | |
parent | 2d1528b34c45a650e2407bbc90737cc4ca6ec042 (diff) |
Merge "Link DCAE MOD design tool to Acumos Adapter"
Diffstat (limited to 'mod/designtool/designtool-web/src/main')
16 files changed, 962 insertions, 5680 deletions
diff --git a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/NiFi.java b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/NiFi.java deleted file mode 100644 index 0b033db..0000000 --- a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/NiFi.java +++ /dev/null @@ -1,446 +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. - * - * Modifications to the original nifi code for the ONAP project are made - * available under the Apache License, Version 2.0 - */ -package org.apache.nifi; - -import org.apache.nifi.bundle.Bundle; -import org.apache.nifi.nar.ExtensionMapping; -import org.apache.nifi.nar.NarClassLoaders; -import org.apache.nifi.nar.NarClassLoadersHolder; -import org.apache.nifi.nar.NarUnpacker; -import org.apache.nifi.nar.SystemBundle; -import org.apache.nifi.util.FileUtils; -import org.apache.nifi.util.NiFiProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.slf4j.bridge.SLF4JBridgeHandler; - -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.lang.Thread.UncaughtExceptionHandler; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.Random; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicLong; - -public class NiFi { - - private static final Logger LOGGER = LoggerFactory.getLogger(NiFi.class); - private static final String KEY_FILE_FLAG = "-K"; - private final NiFiServer nifiServer; - private final BootstrapListener bootstrapListener; - - public static final String BOOTSTRAP_PORT_PROPERTY = "nifi.bootstrap.listen.port"; - private volatile boolean shutdown = false; - - public NiFi(final NiFiProperties properties) - throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - - this(properties, ClassLoader.getSystemClassLoader()); - - } - - public NiFi(final NiFiProperties properties, ClassLoader rootClassLoader) - throws ClassNotFoundException, IOException, NoSuchMethodException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { - - // There can only be one krb5.conf for the overall Java process so set this globally during - // start up so that processors and our Kerberos authentication code don't have to set this - final File kerberosConfigFile = properties.getKerberosConfigurationFile(); - if (kerberosConfigFile != null) { - final String kerberosConfigFilePath = kerberosConfigFile.getAbsolutePath(); - LOGGER.info("Setting java.security.krb5.conf to {}", new Object[]{kerberosConfigFilePath}); - System.setProperty("java.security.krb5.conf", kerberosConfigFilePath); - } - - setDefaultUncaughtExceptionHandler(); - - // register the shutdown hook - addShutdownHook(); - - final String bootstrapPort = System.getProperty(BOOTSTRAP_PORT_PROPERTY); - if (bootstrapPort != null) { - try { - final int port = Integer.parseInt(bootstrapPort); - - if (port < 1 || port > 65535) { - throw new RuntimeException("Failed to start NiFi because system property '" + BOOTSTRAP_PORT_PROPERTY + "' is not a valid integer in the range 1 - 65535"); - } - - bootstrapListener = new BootstrapListener(this, port); - bootstrapListener.start(); - } catch (final NumberFormatException nfe) { - throw new RuntimeException("Failed to start NiFi because system property '" + BOOTSTRAP_PORT_PROPERTY + "' is not a valid integer in the range 1 - 65535"); - } - } else { - LOGGER.info("NiFi started without Bootstrap Port information provided; will not listen for requests from Bootstrap"); - bootstrapListener = null; - } - - // delete the web working dir - if the application does not start successfully - // the web app directories might be in an invalid state. when this happens - // jetty will not attempt to re-extract the war into the directory. by removing - // the working directory, we can be assured that it will attempt to extract the - // war every time the application starts. - File webWorkingDir = properties.getWebWorkingDirectory(); - FileUtils.deleteFilesInDirectory(webWorkingDir, null, LOGGER, true, true); - FileUtils.deleteFile(webWorkingDir, LOGGER, 3); - - detectTimingIssues(); - - // redirect JUL log events - initLogging(); - - final Bundle systemBundle = SystemBundle.create(properties); - - // expand the nars - final ExtensionMapping extensionMapping = NarUnpacker.unpackNars(properties, systemBundle); - - // load the extensions classloaders - NarClassLoaders narClassLoaders = NarClassLoadersHolder.getInstance(); - - narClassLoaders.init(rootClassLoader, - properties.getFrameworkWorkingDirectory(), properties.getExtensionsWorkingDirectory()); - - // load the framework classloader - final ClassLoader frameworkClassLoader = narClassLoaders.getFrameworkBundle().getClassLoader(); - if (frameworkClassLoader == null) { - throw new IllegalStateException("Unable to find the framework NAR ClassLoader."); - } - - final Set<Bundle> narBundles = narClassLoaders.getBundles(); - - // load the server from the framework classloader - Thread.currentThread().setContextClassLoader(frameworkClassLoader); - Class<?> jettyServer = Class.forName("org.apache.nifi.web.server.JettyServer", true, frameworkClassLoader); - Constructor<?> jettyConstructor = jettyServer.getConstructor(NiFiProperties.class, Set.class); - - final long startTime = System.nanoTime(); - nifiServer = (NiFiServer) jettyConstructor.newInstance(properties, narBundles); - nifiServer.setExtensionMapping(extensionMapping); - nifiServer.setBundles(systemBundle, narBundles); - - if (shutdown) { - LOGGER.info("NiFi has been shutdown via NiFi Bootstrap. Will not start Controller"); - } else { - nifiServer.start(); - - if (bootstrapListener != null) { - bootstrapListener.sendStartedStatus(true); - } - - final long duration = System.nanoTime() - startTime; - LOGGER.info("Controller initialization took " + duration + " nanoseconds " - + "(" + (int) TimeUnit.SECONDS.convert(duration, TimeUnit.NANOSECONDS) + " seconds)."); - } - } - - protected void setDefaultUncaughtExceptionHandler() { - Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { - @Override - public void uncaughtException(final Thread t, final Throwable e) { - LOGGER.error("An Unknown Error Occurred in Thread {}: {}", t, e.toString()); - LOGGER.error("", e); - } - }); - } - - protected void addShutdownHook() { - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - @Override - public void run() { - // shutdown the jetty server - shutdownHook(); - } - })); - } - - protected void initLogging() { - SLF4JBridgeHandler.removeHandlersForRootLogger(); - SLF4JBridgeHandler.install(); - } - - private static ClassLoader createBootstrapClassLoader() { - //Get list of files in bootstrap folder - final List<URL> urls = new ArrayList<>(); - try { - Files.list(Paths.get("lib/bootstrap")).forEach(p -> { - try { - urls.add(p.toUri().toURL()); - } catch (final MalformedURLException mef) { - LOGGER.warn("Unable to load " + p.getFileName() + " due to " + mef, mef); - } - }); - } catch (IOException ioe) { - LOGGER.warn("Unable to access lib/bootstrap to create bootstrap classloader", ioe); - } - //Create the bootstrap classloader - return new URLClassLoader(urls.toArray(new URL[0]), Thread.currentThread().getContextClassLoader()); - } - - protected void shutdownHook() { - try { - shutdown(); - } catch (final Throwable t) { - LOGGER.warn("Problem occurred ensuring Jetty web server was properly terminated due to " + t); - } - } - - protected void shutdown() { - this.shutdown = true; - - LOGGER.info("Initiating shutdown of Jetty web server..."); - if (nifiServer != null) { - nifiServer.stop(); - } - if (bootstrapListener != null) { - bootstrapListener.stop(); - } - LOGGER.info("Jetty web server shutdown completed (nicely or otherwise)."); - } - - /** - * Determine if the machine we're running on has timing issues. - */ - private void detectTimingIssues() { - final int minRequiredOccurrences = 25; - final int maxOccurrencesOutOfRange = 15; - final AtomicLong lastTriggerMillis = new AtomicLong(System.currentTimeMillis()); - - final ScheduledExecutorService service = Executors.newScheduledThreadPool(1, new ThreadFactory() { - private final ThreadFactory defaultFactory = Executors.defaultThreadFactory(); - - @Override - public Thread newThread(final Runnable r) { - final Thread t = defaultFactory.newThread(r); - t.setDaemon(true); - t.setName("Detect Timing Issues"); - return t; - } - }); - - final AtomicInteger occurrencesOutOfRange = new AtomicInteger(0); - final AtomicInteger occurrences = new AtomicInteger(0); - final Runnable command = new Runnable() { - @Override - public void run() { - final long curMillis = System.currentTimeMillis(); - final long difference = curMillis - lastTriggerMillis.get(); - final long millisOff = Math.abs(difference - 2000L); - occurrences.incrementAndGet(); - if (millisOff > 500L) { - occurrencesOutOfRange.incrementAndGet(); - } - lastTriggerMillis.set(curMillis); - } - }; - - final ScheduledFuture<?> future = service.scheduleWithFixedDelay(command, 2000L, 2000L, TimeUnit.MILLISECONDS); - - final TimerTask timerTask = new TimerTask() { - @Override - public void run() { - future.cancel(true); - service.shutdownNow(); - - if (occurrences.get() < minRequiredOccurrences || occurrencesOutOfRange.get() > maxOccurrencesOutOfRange) { - LOGGER.warn("NiFi has detected that this box is not responding within the expected timing interval, which may cause " - + "Processors to be scheduled erratically. Please see the NiFi documentation for more information."); - } - } - }; - final Timer timer = new Timer(true); - timer.schedule(timerTask, 60000L); - } - - /** - * Main entry point of the application. - * - * @param args things which are ignored - */ - public static void main(String[] args) { - LOGGER.info("Launching NiFi..."); - try { - NiFiProperties properties = convertArgumentsToValidatedNiFiProperties(args); - new NiFi(properties); - } catch (final Throwable t) { - LOGGER.error("Failure to launch NiFi due to " + t, t); - } - } - - protected static NiFiProperties convertArgumentsToValidatedNiFiProperties(String[] args) { - final ClassLoader bootstrap = createBootstrapClassLoader(); - NiFiProperties properties = initializeProperties(args, bootstrap); - properties.validate(); - return properties; - } - - private static NiFiProperties initializeProperties(final String[] args, final ClassLoader boostrapLoader) { - // Try to get key - // If key doesn't exist, instantiate without - // Load properties - // If properties are protected and key missing, throw RuntimeException - - final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - final String key; - try { - key = loadFormattedKey(args); - // The key might be empty or null when it is passed to the loader - } catch (IllegalArgumentException e) { - final String msg = "The bootstrap process did not provide a valid key"; - throw new IllegalArgumentException(msg, e); - } - Thread.currentThread().setContextClassLoader(boostrapLoader); - - try { - final Class<?> propsLoaderClass = Class.forName("org.apache.nifi.properties.NiFiPropertiesLoader", true, boostrapLoader); - final Method withKeyMethod = propsLoaderClass.getMethod("withKey", String.class); - final Object loaderInstance = withKeyMethod.invoke(null, key); - final Method getMethod = propsLoaderClass.getMethod("get"); - final NiFiProperties properties = (NiFiProperties) getMethod.invoke(loaderInstance); - LOGGER.info("Loaded {} properties", properties.size()); - return properties; - } catch (InvocationTargetException wrappedException) { - final String msg = "There was an issue decrypting protected properties"; - throw new IllegalArgumentException(msg, wrappedException.getCause() == null ? wrappedException : wrappedException.getCause()); - } catch (final IllegalAccessException | NoSuchMethodException | ClassNotFoundException reex) { - final String msg = "Unable to access properties loader in the expected manner - apparent classpath or build issue"; - throw new IllegalArgumentException(msg, reex); - } catch (final RuntimeException e) { - final String msg = "There was an issue decrypting protected properties"; - throw new IllegalArgumentException(msg, e); - } finally { - Thread.currentThread().setContextClassLoader(contextClassLoader); - } - } - - private static String loadFormattedKey(String[] args) { - String key = null; - List<String> parsedArgs = parseArgs(args); - // Check if args contain protection key - if (parsedArgs.contains(KEY_FILE_FLAG)) { - key = getKeyFromKeyFileAndPrune(parsedArgs); - // Format the key (check hex validity and remove spaces) - key = formatHexKey(key); - - } - - if (null == key) { - return ""; - } else if (!isHexKeyValid(key)) { - throw new IllegalArgumentException("The key was not provided in valid hex format and of the correct length"); - } else { - return key; - } - } - - private static String getKeyFromKeyFileAndPrune(List<String> parsedArgs) { - String key = null; - LOGGER.debug("The bootstrap process provided the " + KEY_FILE_FLAG + " flag"); - int i = parsedArgs.indexOf(KEY_FILE_FLAG); - if (parsedArgs.size() <= i + 1) { - LOGGER.error("The bootstrap process passed the {} flag without a filename", KEY_FILE_FLAG); - throw new IllegalArgumentException("The bootstrap process provided the " + KEY_FILE_FLAG + " flag but no key"); - } - try { - String passwordfile_path = parsedArgs.get(i + 1); - // Slurp in the contents of the file: - byte[] encoded = Files.readAllBytes(Paths.get(passwordfile_path)); - key = new String(encoded,StandardCharsets.UTF_8); - if (0 == key.length()) - throw new IllegalArgumentException("Key in keyfile " + passwordfile_path + " yielded an empty key"); - - LOGGER.info("Now overwriting file in "+passwordfile_path); - - // Overwrite the contents of the file (to avoid littering file system - // unlinked with key material): - File password_file = new File(passwordfile_path); - FileWriter overwriter = new FileWriter(password_file,false); - - // Construe a random pad: - Random r = new Random(); - StringBuffer sb = new StringBuffer(); - // Note on correctness: this pad is longer, but equally sufficient. - while(sb.length() < encoded.length){ - sb.append(Integer.toHexString(r.nextInt())); - } - String pad = sb.toString(); - LOGGER.info("Overwriting key material with pad: "+pad); - overwriter.write(pad); - overwriter.close(); - - LOGGER.info("Removing/unlinking file: "+passwordfile_path); - password_file.delete(); - - } catch (IOException e) { - LOGGER.error("Caught IOException while retrieving the "+KEY_FILE_FLAG+"-passed keyfile; aborting: "+e.toString()); - System.exit(1); - } - - LOGGER.info("Read property protection key from key file provided by bootstrap process"); - return key; - } - - private static List<String> parseArgs(String[] args) { - List<String> parsedArgs = new ArrayList<>(Arrays.asList(args)); - for (int i = 0; i < parsedArgs.size(); i++) { - if (parsedArgs.get(i).startsWith(KEY_FILE_FLAG + " ")) { - String[] split = parsedArgs.get(i).split(" ", 2); - parsedArgs.set(i, split[0]); - parsedArgs.add(i + 1, split[1]); - break; - } - } - return parsedArgs; - } - - private static String formatHexKey(String input) { - if (input == null || input.trim().isEmpty()) { - return ""; - } - return input.replaceAll("[^0-9a-fA-F]", "").toLowerCase(); - } - - private static boolean isHexKeyValid(String key) { - if (key == null || key.trim().isEmpty()) { - return false; - } - // Key length is in "nibbles" (i.e. one hex char = 4 bits) - return Arrays.asList(128, 196, 256).contains(key.length() * 4) && key.matches("^[0-9a-fA-F]*$"); - } -} diff --git a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/util/NiFiProperties.java b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/util/NiFiProperties.java index 3b341ec..b1b41c1 100644 --- a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/util/NiFiProperties.java +++ b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/util/NiFiProperties.java @@ -192,7 +192,6 @@ public abstract class NiFiProperties { // ui properties public static final String UI_BANNER_TEXT = "nifi.ui.banner.text"; public static final String UI_AUTO_REFRESH_INTERVAL = "nifi.ui.autorefresh.interval"; - public static final String UI_DCAE_DISTRIBUTOR_API_URL="nifi.ui.dcae.distibutor.api.url"; // cluster common properties public static final String CLUSTER_PROTOCOL_HEARTBEAT_INTERVAL = "nifi.cluster.protocol.heartbeat.interval"; @@ -717,15 +716,6 @@ public abstract class NiFiProperties { return this.getProperty(UI_BANNER_TEXT, StringUtils.EMPTY); } - - /** - * @author Renu - * @return the IP address where the nifi-app is being hosted - */ - public String getDcaeDistributorApiHostname() { - return getProperty(UI_DCAE_DISTRIBUTOR_API_URL); - } - /** * Returns the auto refresh interval in seconds. * diff --git a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java deleted file mode 100644 index 8ad05bd..0000000 --- a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/StandardNiFiServiceFacade.java +++ /dev/null @@ -1,4899 +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. - * - * Modifications to the original nifi code for the ONAP project are made - * available under the Apache License, Version 2.0 - */ -package org.apache.nifi.web; - -import com.google.common.collect.Sets; -import org.apache.commons.collections4.CollectionUtils; -import org.apache.nifi.action.Action; -import org.apache.nifi.action.Component; -import org.apache.nifi.action.FlowChangeAction; -import org.apache.nifi.action.Operation; -import org.apache.nifi.action.details.FlowChangePurgeDetails; -import org.apache.nifi.admin.service.AuditService; -import org.apache.nifi.authorization.AccessDeniedException; -import org.apache.nifi.authorization.AccessPolicy; -import org.apache.nifi.authorization.AuthorizableLookup; -import org.apache.nifi.authorization.AuthorizationRequest; -import org.apache.nifi.authorization.AuthorizationResult; -import org.apache.nifi.authorization.AuthorizationResult.Result; -import org.apache.nifi.authorization.AuthorizeAccess; -import org.apache.nifi.authorization.Authorizer; -import org.apache.nifi.authorization.Group; -import org.apache.nifi.authorization.RequestAction; -import org.apache.nifi.authorization.Resource; -import org.apache.nifi.authorization.User; -import org.apache.nifi.authorization.UserContextKeys; -import org.apache.nifi.authorization.resource.Authorizable; -import org.apache.nifi.authorization.resource.EnforcePolicyPermissionsThroughBaseResource; -import org.apache.nifi.authorization.resource.OperationAuthorizable; -import org.apache.nifi.authorization.resource.ResourceFactory; -import org.apache.nifi.authorization.user.NiFiUser; -import org.apache.nifi.authorization.user.NiFiUserUtils; -import org.apache.nifi.bundle.BundleCoordinate; -import org.apache.nifi.cluster.coordination.ClusterCoordinator; -import org.apache.nifi.cluster.coordination.heartbeat.HeartbeatMonitor; -import org.apache.nifi.cluster.coordination.heartbeat.NodeHeartbeat; -import org.apache.nifi.cluster.coordination.node.ClusterRoles; -import org.apache.nifi.cluster.coordination.node.DisconnectionCode; -import org.apache.nifi.cluster.coordination.node.NodeConnectionState; -import org.apache.nifi.cluster.coordination.node.NodeConnectionStatus; -import org.apache.nifi.cluster.coordination.node.OffloadCode; -import org.apache.nifi.cluster.event.NodeEvent; -import org.apache.nifi.cluster.manager.exception.IllegalNodeDeletionException; -import org.apache.nifi.cluster.manager.exception.UnknownNodeException; -import org.apache.nifi.cluster.protocol.NodeIdentifier; -import org.apache.nifi.components.ConfigurableComponent; -import org.apache.nifi.components.PropertyDescriptor; -import org.apache.nifi.components.RequiredPermission; -import org.apache.nifi.components.ValidationResult; -import org.apache.nifi.components.Validator; -import org.apache.nifi.components.state.Scope; -import org.apache.nifi.components.state.StateMap; -import org.apache.nifi.connectable.Connectable; -import org.apache.nifi.connectable.Connection; -import org.apache.nifi.connectable.Funnel; -import org.apache.nifi.connectable.Port; -import org.apache.nifi.controller.ComponentNode; -import org.apache.nifi.controller.Counter; -import org.apache.nifi.controller.FlowController; -import org.apache.nifi.controller.ProcessorNode; -import org.apache.nifi.controller.ReportingTaskNode; -import org.apache.nifi.controller.ScheduledState; -import org.apache.nifi.controller.Snippet; -import org.apache.nifi.controller.Template; -import org.apache.nifi.controller.label.Label; -import org.apache.nifi.controller.leader.election.LeaderElectionManager; -import org.apache.nifi.controller.repository.claim.ContentDirection; -import org.apache.nifi.controller.service.ControllerServiceNode; -import org.apache.nifi.controller.service.ControllerServiceReference; -import org.apache.nifi.controller.service.ControllerServiceState; -import org.apache.nifi.controller.status.ProcessGroupStatus; -import org.apache.nifi.controller.status.ProcessorStatus; -import org.apache.nifi.diagnostics.SystemDiagnostics; -import org.apache.nifi.events.BulletinFactory; -import org.apache.nifi.groups.ProcessGroup; -import org.apache.nifi.groups.ProcessGroupCounts; -import org.apache.nifi.groups.RemoteProcessGroup; -import org.apache.nifi.history.History; -import org.apache.nifi.history.HistoryQuery; -import org.apache.nifi.history.PreviousValue; -import org.apache.nifi.registry.ComponentVariableRegistry; -import org.apache.nifi.registry.authorization.Permissions; -import org.apache.nifi.registry.bucket.Bucket; -import org.apache.nifi.registry.client.NiFiRegistryException; -import org.apache.nifi.registry.flow.FlowRegistry; -import org.apache.nifi.registry.flow.FlowRegistryClient; -import org.apache.nifi.registry.flow.VersionControlInformation; -import org.apache.nifi.registry.flow.VersionedComponent; -import org.apache.nifi.registry.flow.VersionedConnection; -import org.apache.nifi.registry.flow.VersionedFlow; -import org.apache.nifi.registry.flow.VersionedFlowCoordinates; -import org.apache.nifi.registry.flow.VersionedFlowSnapshot; -import org.apache.nifi.registry.flow.VersionedFlowSnapshotMetadata; -import org.apache.nifi.registry.flow.VersionedFlowState; -import org.apache.nifi.registry.flow.VersionedProcessGroup; -import org.apache.nifi.registry.flow.diff.ComparableDataFlow; -import org.apache.nifi.registry.flow.diff.ConciseEvolvingDifferenceDescriptor; -import org.apache.nifi.registry.flow.diff.DifferenceType; -import org.apache.nifi.registry.flow.diff.FlowComparator; -import org.apache.nifi.registry.flow.diff.FlowComparison; -import org.apache.nifi.registry.flow.diff.FlowDifference; -import org.apache.nifi.registry.flow.diff.StandardComparableDataFlow; -import org.apache.nifi.registry.flow.diff.StandardFlowComparator; -import org.apache.nifi.registry.flow.diff.StaticDifferenceDescriptor; -import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedComponent; -import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedControllerService; -import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedProcessGroup; -import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedProcessor; -import org.apache.nifi.registry.flow.mapping.InstantiatedVersionedRemoteGroupPort; -import org.apache.nifi.registry.flow.mapping.NiFiRegistryFlowMapper; -import org.apache.nifi.remote.RemoteGroupPort; -import org.apache.nifi.remote.RootGroupPort; -import org.apache.nifi.reporting.Bulletin; -import org.apache.nifi.reporting.BulletinQuery; -import org.apache.nifi.reporting.BulletinRepository; -import org.apache.nifi.reporting.ComponentType; -import org.apache.nifi.util.BundleUtils; -import org.apache.nifi.util.FlowDifferenceFilters; -import org.apache.nifi.util.NiFiProperties; -import org.apache.nifi.web.api.dto.AccessPolicyDTO; -import org.apache.nifi.web.api.dto.AccessPolicySummaryDTO; -import org.apache.nifi.web.api.dto.AffectedComponentDTO; -import org.apache.nifi.web.api.dto.BucketDTO; -import org.apache.nifi.web.api.dto.BulletinBoardDTO; -import org.apache.nifi.web.api.dto.BulletinDTO; -import org.apache.nifi.web.api.dto.BulletinQueryDTO; -import org.apache.nifi.web.api.dto.BundleDTO; -import org.apache.nifi.web.api.dto.ClusterDTO; -import org.apache.nifi.web.api.dto.ComponentDTO; -import org.apache.nifi.web.api.dto.ComponentDifferenceDTO; -import org.apache.nifi.web.api.dto.ComponentHistoryDTO; -import org.apache.nifi.web.api.dto.ComponentReferenceDTO; -import org.apache.nifi.web.api.dto.ComponentRestrictionPermissionDTO; -import org.apache.nifi.web.api.dto.ComponentStateDTO; -import org.apache.nifi.web.api.dto.ConnectionDTO; -import org.apache.nifi.web.api.dto.ControllerConfigurationDTO; -import org.apache.nifi.web.api.dto.ControllerDTO; -import org.apache.nifi.web.api.dto.ControllerServiceDTO; -import org.apache.nifi.web.api.dto.ControllerServiceReferencingComponentDTO; -import org.apache.nifi.web.api.dto.CounterDTO; -import org.apache.nifi.web.api.dto.CountersDTO; -import org.apache.nifi.web.api.dto.CountersSnapshotDTO; -import org.apache.nifi.web.api.dto.DocumentedTypeDTO; -import org.apache.nifi.web.api.dto.DropRequestDTO; -import org.apache.nifi.web.api.dto.DtoFactory; -import org.apache.nifi.web.api.dto.EntityFactory; -import org.apache.nifi.web.api.dto.FlowConfigurationDTO; -import org.apache.nifi.web.api.dto.FlowFileDTO; -import org.apache.nifi.web.api.dto.FlowSnippetDTO; -import org.apache.nifi.web.api.dto.FunnelDTO; -import org.apache.nifi.web.api.dto.LabelDTO; -import org.apache.nifi.web.api.dto.ListingRequestDTO; -import org.apache.nifi.web.api.dto.NodeDTO; -import org.apache.nifi.web.api.dto.PermissionsDTO; -import org.apache.nifi.web.api.dto.PortDTO; -import org.apache.nifi.web.api.dto.PreviousValueDTO; -import org.apache.nifi.web.api.dto.ProcessGroupDTO; -import org.apache.nifi.web.api.dto.ProcessorConfigDTO; -import org.apache.nifi.web.api.dto.ProcessorDTO; -import org.apache.nifi.web.api.dto.PropertyDescriptorDTO; -import org.apache.nifi.web.api.dto.PropertyHistoryDTO; -import org.apache.nifi.web.api.dto.RegistryDTO; -import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO; -import org.apache.nifi.web.api.dto.RemoteProcessGroupPortDTO; -import org.apache.nifi.web.api.dto.ReportingTaskDTO; -import org.apache.nifi.web.api.dto.RequiredPermissionDTO; -import org.apache.nifi.web.api.dto.ResourceDTO; -import org.apache.nifi.web.api.dto.RevisionDTO; -import org.apache.nifi.web.api.dto.SnippetDTO; -import org.apache.nifi.web.api.dto.SystemDiagnosticsDTO; -import org.apache.nifi.web.api.dto.TemplateDTO; -import org.apache.nifi.web.api.dto.UserDTO; -import org.apache.nifi.web.api.dto.UserGroupDTO; -import org.apache.nifi.web.api.dto.VariableRegistryDTO; -import org.apache.nifi.web.api.dto.VersionControlInformationDTO; -import org.apache.nifi.web.api.dto.VersionedFlowDTO; -import org.apache.nifi.web.api.dto.action.HistoryDTO; -import org.apache.nifi.web.api.dto.action.HistoryQueryDTO; -import org.apache.nifi.web.api.dto.diagnostics.ConnectionDiagnosticsDTO; -import org.apache.nifi.web.api.dto.diagnostics.ControllerServiceDiagnosticsDTO; -import org.apache.nifi.web.api.dto.diagnostics.JVMDiagnosticsDTO; -import org.apache.nifi.web.api.dto.diagnostics.JVMDiagnosticsSnapshotDTO; -import org.apache.nifi.web.api.dto.diagnostics.ProcessorDiagnosticsDTO; -import org.apache.nifi.web.api.dto.flow.FlowDTO; -import org.apache.nifi.web.api.dto.provenance.ProvenanceDTO; -import org.apache.nifi.web.api.dto.provenance.ProvenanceEventDTO; -import org.apache.nifi.web.api.dto.provenance.ProvenanceOptionsDTO; -import org.apache.nifi.web.api.dto.provenance.lineage.LineageDTO; -import org.apache.nifi.web.api.dto.search.SearchResultsDTO; -import org.apache.nifi.web.api.dto.status.ConnectionStatusDTO; -import org.apache.nifi.web.api.dto.status.ControllerStatusDTO; -import org.apache.nifi.web.api.dto.status.NodeProcessGroupStatusSnapshotDTO; -import org.apache.nifi.web.api.dto.status.PortStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.ProcessGroupStatusSnapshotDTO; -import org.apache.nifi.web.api.dto.status.ProcessorStatusDTO; -import org.apache.nifi.web.api.dto.status.RemoteProcessGroupStatusDTO; -import org.apache.nifi.web.api.dto.status.StatusHistoryDTO; -import org.apache.nifi.web.api.entity.AccessPolicyEntity; -import org.apache.nifi.web.api.entity.AccessPolicySummaryEntity; -import org.apache.nifi.web.api.entity.ActionEntity; -import org.apache.nifi.web.api.entity.ActivateControllerServicesEntity; -import org.apache.nifi.web.api.entity.AffectedComponentEntity; -import org.apache.nifi.web.api.entity.BucketEntity; -import org.apache.nifi.web.api.entity.BulletinEntity; -import org.apache.nifi.web.api.entity.ComponentReferenceEntity; -import org.apache.nifi.web.api.entity.ConnectionEntity; -import org.apache.nifi.web.api.entity.ConnectionStatusEntity; -import org.apache.nifi.web.api.entity.ControllerBulletinsEntity; -import org.apache.nifi.web.api.entity.ControllerConfigurationEntity; -import org.apache.nifi.web.api.entity.ControllerServiceEntity; -import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentEntity; -import org.apache.nifi.web.api.entity.ControllerServiceReferencingComponentsEntity; -import org.apache.nifi.web.api.entity.CurrentUserEntity; -import org.apache.nifi.web.api.entity.FlowComparisonEntity; -import org.apache.nifi.web.api.entity.FlowConfigurationEntity; -import org.apache.nifi.web.api.entity.FlowEntity; -import org.apache.nifi.web.api.entity.FunnelEntity; -import org.apache.nifi.web.api.entity.LabelEntity; -import org.apache.nifi.web.api.entity.PortEntity; -import org.apache.nifi.web.api.entity.PortStatusEntity; -import org.apache.nifi.web.api.entity.ProcessGroupEntity; -import org.apache.nifi.web.api.entity.ProcessGroupFlowEntity; -import org.apache.nifi.web.api.entity.ProcessGroupStatusEntity; -import org.apache.nifi.web.api.entity.ProcessGroupStatusSnapshotEntity; -import org.apache.nifi.web.api.entity.ProcessorDiagnosticsEntity; -import org.apache.nifi.web.api.entity.ProcessorEntity; -import org.apache.nifi.web.api.entity.ProcessorStatusEntity; -import org.apache.nifi.web.api.entity.RegistryClientEntity; -import org.apache.nifi.web.api.entity.RegistryEntity; -import org.apache.nifi.web.api.entity.RemoteProcessGroupEntity; -import org.apache.nifi.web.api.entity.RemoteProcessGroupPortEntity; -import org.apache.nifi.web.api.entity.RemoteProcessGroupStatusEntity; -import org.apache.nifi.web.api.entity.ReportingTaskEntity; -import org.apache.nifi.web.api.entity.ScheduleComponentsEntity; -import org.apache.nifi.web.api.entity.SnippetEntity; -import org.apache.nifi.web.api.entity.StartVersionControlRequestEntity; -import org.apache.nifi.web.api.entity.StatusHistoryEntity; -import org.apache.nifi.web.api.entity.TemplateEntity; -import org.apache.nifi.web.api.entity.TenantEntity; -import org.apache.nifi.web.api.entity.UserEntity; -import org.apache.nifi.web.api.entity.UserGroupEntity; -import org.apache.nifi.web.api.entity.VariableEntity; -import org.apache.nifi.web.api.entity.VariableRegistryEntity; -import org.apache.nifi.web.api.entity.VersionControlComponentMappingEntity; -import org.apache.nifi.web.api.entity.VersionControlInformationEntity; -import org.apache.nifi.web.api.entity.VersionedFlowEntity; -import org.apache.nifi.web.api.entity.VersionedFlowSnapshotMetadataEntity; -import org.apache.nifi.web.controller.ControllerFacade; -import org.apache.nifi.web.dao.AccessPolicyDAO; -import org.apache.nifi.web.dao.ConnectionDAO; -import org.apache.nifi.web.dao.ControllerServiceDAO; -import org.apache.nifi.web.dao.FunnelDAO; -import org.apache.nifi.web.dao.LabelDAO; -import org.apache.nifi.web.dao.PortDAO; -import org.apache.nifi.web.dao.ProcessGroupDAO; -import org.apache.nifi.web.dao.ProcessorDAO; -import org.apache.nifi.web.dao.RegistryDAO; -import org.apache.nifi.web.dao.RemoteProcessGroupDAO; -import org.apache.nifi.web.dao.ReportingTaskDAO; -import org.apache.nifi.web.dao.SnippetDAO; -import org.apache.nifi.web.dao.TemplateDAO; -import org.apache.nifi.web.dao.UserDAO; -import org.apache.nifi.web.dao.UserGroupDAO; -import org.apache.nifi.web.revision.DeleteRevisionTask; -import org.apache.nifi.web.revision.ExpiredRevisionClaimException; -import org.apache.nifi.web.revision.RevisionClaim; -import org.apache.nifi.web.revision.RevisionManager; -import org.apache.nifi.web.revision.RevisionUpdate; -import org.apache.nifi.web.revision.StandardRevisionClaim; -import org.apache.nifi.web.revision.StandardRevisionUpdate; -import org.apache.nifi.web.revision.UpdateRevisionTask; -import org.apache.nifi.web.util.SnippetUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; -import java.util.function.Function; -import java.util.function.Predicate; -import java.util.function.Supplier; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -/** - * Implementation of NiFiServiceFacade that performs revision checking. - */ -public class StandardNiFiServiceFacade implements NiFiServiceFacade { - private static final Logger logger = LoggerFactory.getLogger(StandardNiFiServiceFacade.class); - private static final int VALIDATION_WAIT_MILLIS = 50; - - // nifi core components - private ControllerFacade controllerFacade; - private SnippetUtils snippetUtils; - - // revision manager - private RevisionManager revisionManager; - private BulletinRepository bulletinRepository; - - // data access objects - private ProcessorDAO processorDAO; - private ProcessGroupDAO processGroupDAO; - private RemoteProcessGroupDAO remoteProcessGroupDAO; - private LabelDAO labelDAO; - private FunnelDAO funnelDAO; - private SnippetDAO snippetDAO; - private PortDAO inputPortDAO; - private PortDAO outputPortDAO; - private ConnectionDAO connectionDAO; - private ControllerServiceDAO controllerServiceDAO; - private ReportingTaskDAO reportingTaskDAO; - private TemplateDAO templateDAO; - private UserDAO userDAO; - private UserGroupDAO userGroupDAO; - private AccessPolicyDAO accessPolicyDAO; - private RegistryDAO registryDAO; - private ClusterCoordinator clusterCoordinator; - private HeartbeatMonitor heartbeatMonitor; - private LeaderElectionManager leaderElectionManager; - - // administrative services - private AuditService auditService; - - // flow registry - private FlowRegistryClient flowRegistryClient; - - // properties - private NiFiProperties properties; - private DtoFactory dtoFactory; - private EntityFactory entityFactory; - - private Authorizer authorizer; - - private AuthorizableLookup authorizableLookup; - - // ----------------------------------------- - // Synchronization methods - // ----------------------------------------- - @Override - public void authorizeAccess(final AuthorizeAccess authorizeAccess) { - authorizeAccess.authorize(authorizableLookup); - } - - @Override - public void verifyRevision(final Revision revision, final NiFiUser user) { - final Revision curRevision = revisionManager.getRevision(revision.getComponentId()); - if (revision.equals(curRevision)) { - return; - } - - throw new InvalidRevisionException(revision + " is not the most up-to-date revision. This component appears to have been modified"); - } - - @Override - public void verifyRevisions(final Set<Revision> revisions, final NiFiUser user) { - for (final Revision revision : revisions) { - verifyRevision(revision, user); - } - } - - @Override - public Set<Revision> getRevisionsFromGroup(final String groupId, final Function<ProcessGroup, Set<String>> getComponents) { - final ProcessGroup group = processGroupDAO.getProcessGroup(groupId); - final Set<String> componentIds = getComponents.apply(group); - return componentIds.stream().map(id -> revisionManager.getRevision(id)).collect(Collectors.toSet()); - } - - @Override - public Set<Revision> getRevisionsFromSnippet(final String snippetId) { - final Snippet snippet = snippetDAO.getSnippet(snippetId); - final Set<String> componentIds = new HashSet<>(); - componentIds.addAll(snippet.getProcessors().keySet()); - componentIds.addAll(snippet.getFunnels().keySet()); - componentIds.addAll(snippet.getLabels().keySet()); - componentIds.addAll(snippet.getConnections().keySet()); - componentIds.addAll(snippet.getInputPorts().keySet()); - componentIds.addAll(snippet.getOutputPorts().keySet()); - componentIds.addAll(snippet.getProcessGroups().keySet()); - componentIds.addAll(snippet.getRemoteProcessGroups().keySet()); - return componentIds.stream().map(id -> revisionManager.getRevision(id)).collect(Collectors.toSet()); - } - - // ----------------------------------------- - // Verification Operations - // ----------------------------------------- - - @Override - public void verifyListQueue(final String connectionId) { - connectionDAO.verifyList(connectionId); - } - - @Override - public void verifyCreateConnection(final String groupId, final ConnectionDTO connectionDTO) { - connectionDAO.verifyCreate(groupId, connectionDTO); - } - - @Override - public void verifyUpdateConnection(final ConnectionDTO connectionDTO) { - // if connection does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (connectionDAO.hasConnection(connectionDTO.getId())) { - connectionDAO.verifyUpdate(connectionDTO); - } else { - connectionDAO.verifyCreate(connectionDTO.getParentGroupId(), connectionDTO); - } - } - - @Override - public void verifyDeleteConnection(final String connectionId) { - connectionDAO.verifyDelete(connectionId); - } - - @Override - public void verifyDeleteFunnel(final String funnelId) { - funnelDAO.verifyDelete(funnelId); - } - - @Override - public void verifyUpdateInputPort(final PortDTO inputPortDTO) { - // if connection does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (inputPortDAO.hasPort(inputPortDTO.getId())) { - inputPortDAO.verifyUpdate(inputPortDTO); - } - } - - @Override - public void verifyDeleteInputPort(final String inputPortId) { - inputPortDAO.verifyDelete(inputPortId); - } - - @Override - public void verifyUpdateOutputPort(final PortDTO outputPortDTO) { - // if connection does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (outputPortDAO.hasPort(outputPortDTO.getId())) { - outputPortDAO.verifyUpdate(outputPortDTO); - } - } - - @Override - public void verifyDeleteOutputPort(final String outputPortId) { - outputPortDAO.verifyDelete(outputPortId); - } - - @Override - public void verifyCreateProcessor(ProcessorDTO processorDTO) { - processorDAO.verifyCreate(processorDTO); - } - - @Override - public void verifyUpdateProcessor(final ProcessorDTO processorDTO) { - // if group does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (processorDAO.hasProcessor(processorDTO.getId())) { - processorDAO.verifyUpdate(processorDTO); - } else { - verifyCreateProcessor(processorDTO); - } - } - - @Override - public void verifyDeleteProcessor(final String processorId) { - processorDAO.verifyDelete(processorId); - } - - @Override - public void verifyScheduleComponents(final String groupId, final ScheduledState state, final Set<String> componentIds) { - processGroupDAO.verifyScheduleComponents(groupId, state, componentIds); - } - - @Override - public void verifyEnableComponents(String processGroupId, ScheduledState state, Set<String> componentIds) { - processGroupDAO.verifyEnableComponents(processGroupId, state, componentIds); - } - - @Override - public void verifyActivateControllerServices(final String groupId, final ControllerServiceState state, final Collection<String> serviceIds) { - processGroupDAO.verifyActivateControllerServices(state, serviceIds); - } - - @Override - public void verifyDeleteProcessGroup(final String groupId) { - processGroupDAO.verifyDelete(groupId); - } - - @Override - public void verifyUpdateRemoteProcessGroup(final RemoteProcessGroupDTO remoteProcessGroupDTO) { - // if remote group does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (remoteProcessGroupDAO.hasRemoteProcessGroup(remoteProcessGroupDTO.getId())) { - remoteProcessGroupDAO.verifyUpdate(remoteProcessGroupDTO); - } - } - - @Override - public void verifyUpdateRemoteProcessGroupInputPort(final String remoteProcessGroupId, final RemoteProcessGroupPortDTO remoteProcessGroupPortDTO) { - remoteProcessGroupDAO.verifyUpdateInputPort(remoteProcessGroupId, remoteProcessGroupPortDTO); - } - - @Override - public void verifyUpdateRemoteProcessGroupOutputPort(final String remoteProcessGroupId, final RemoteProcessGroupPortDTO remoteProcessGroupPortDTO) { - remoteProcessGroupDAO.verifyUpdateOutputPort(remoteProcessGroupId, remoteProcessGroupPortDTO); - } - - @Override - public void verifyDeleteRemoteProcessGroup(final String remoteProcessGroupId) { - remoteProcessGroupDAO.verifyDelete(remoteProcessGroupId); - } - - @Override - public void verifyCreateControllerService(ControllerServiceDTO controllerServiceDTO) { - controllerServiceDAO.verifyCreate(controllerServiceDTO); - } - - @Override - public void verifyUpdateControllerService(final ControllerServiceDTO controllerServiceDTO) { - // if service does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (controllerServiceDAO.hasControllerService(controllerServiceDTO.getId())) { - controllerServiceDAO.verifyUpdate(controllerServiceDTO); - } else { - verifyCreateControllerService(controllerServiceDTO); - } - } - - @Override - public void verifyUpdateControllerServiceReferencingComponents(final String controllerServiceId, final ScheduledState scheduledState, final ControllerServiceState controllerServiceState) { - controllerServiceDAO.verifyUpdateReferencingComponents(controllerServiceId, scheduledState, controllerServiceState); - } - - @Override - public void verifyDeleteControllerService(final String controllerServiceId) { - controllerServiceDAO.verifyDelete(controllerServiceId); - } - - @Override - public void verifyCreateReportingTask(ReportingTaskDTO reportingTaskDTO) { - reportingTaskDAO.verifyCreate(reportingTaskDTO); - } - - @Override - public void verifyUpdateReportingTask(final ReportingTaskDTO reportingTaskDTO) { - // if tasks does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (reportingTaskDAO.hasReportingTask(reportingTaskDTO.getId())) { - reportingTaskDAO.verifyUpdate(reportingTaskDTO); - } else { - verifyCreateReportingTask(reportingTaskDTO); - } - } - - @Override - public void verifyDeleteReportingTask(final String reportingTaskId) { - reportingTaskDAO.verifyDelete(reportingTaskId); - } - - // ----------------------------------------- - // Write Operations - // ----------------------------------------- - - @Override - public AccessPolicyEntity updateAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) { - final Authorizable authorizable = authorizableLookup.getAccessPolicyById(accessPolicyDTO.getId()); - final RevisionUpdate<AccessPolicyDTO> snapshot = updateComponent(revision, - authorizable, - () -> accessPolicyDAO.updateAccessPolicy(accessPolicyDTO), - accessPolicy -> { - final Set<TenantEntity> users = accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()); - final Set<TenantEntity> userGroups = accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()); - final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource()); - return dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users, componentReference); - }); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizable); - return entityFactory.createAccessPolicyEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - @Override - public UserEntity updateUser(final Revision revision, final UserDTO userDTO) { - final Authorizable usersAuthorizable = authorizableLookup.getTenant(); - final Set<Group> groups = userGroupDAO.getUserGroupsForUser(userDTO.getId()); - final Set<AccessPolicy> policies = userGroupDAO.getAccessPoliciesForUser(userDTO.getId()); - final RevisionUpdate<UserDTO> snapshot = updateComponent(revision, - usersAuthorizable, - () -> userDAO.updateUser(userDTO), - user -> { - final Set<TenantEntity> tenantEntities = groups.stream().map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()); - final Set<AccessPolicySummaryEntity> policyEntities = policies.stream().map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - return dtoFactory.createUserDto(user, tenantEntities, policyEntities); - }); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(usersAuthorizable); - return entityFactory.createUserEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - @Override - public UserGroupEntity updateUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) { - final Authorizable userGroupsAuthorizable = authorizableLookup.getTenant(); - final Set<AccessPolicy> policies = userGroupDAO.getAccessPoliciesForUserGroup(userGroupDTO.getId()); - final RevisionUpdate<UserGroupDTO> snapshot = updateComponent(revision, - userGroupsAuthorizable, - () -> userGroupDAO.updateUserGroup(userGroupDTO), - userGroup -> { - final Set<TenantEntity> tenantEntities = userGroup.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()); - final Set<AccessPolicySummaryEntity> policyEntities = policies.stream().map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - return dtoFactory.createUserGroupDto(userGroup, tenantEntities, policyEntities); - } - ); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(userGroupsAuthorizable); - return entityFactory.createUserGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - @Override - public ConnectionEntity updateConnection(final Revision revision, final ConnectionDTO connectionDTO) { - final Connection connectionNode = connectionDAO.getConnection(connectionDTO.getId()); - - final RevisionUpdate<ConnectionDTO> snapshot = updateComponent( - revision, - connectionNode, - () -> connectionDAO.updateConnection(connectionDTO), - connection -> dtoFactory.createConnectionDto(connection)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connectionNode); - final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionNode.getIdentifier())); - return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status); - } - - @Override - public ProcessorEntity updateProcessor(final Revision revision, final ProcessorDTO processorDTO) { - // get the component, ensure we have access to it, and perform the update request - final ProcessorNode processorNode = processorDAO.getProcessor(processorDTO.getId()); - final RevisionUpdate<ProcessorDTO> snapshot = updateComponent(revision, - processorNode, - () -> processorDAO.updateProcessor(processorDTO), - proc -> { - awaitValidationCompletion(proc); - return dtoFactory.createProcessorDto(proc); - }); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processorNode); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(processorNode)); - final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processorNode.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processorNode.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, status, bulletinEntities); - } - - private void awaitValidationCompletion(final ComponentNode component) { - component.getValidationStatus(VALIDATION_WAIT_MILLIS, TimeUnit.MILLISECONDS); - } - - @Override - public LabelEntity updateLabel(final Revision revision, final LabelDTO labelDTO) { - final Label labelNode = labelDAO.getLabel(labelDTO.getId()); - final RevisionUpdate<LabelDTO> snapshot = updateComponent(revision, - labelNode, - () -> labelDAO.updateLabel(labelDTO), - label -> dtoFactory.createLabelDto(label)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(labelNode); - return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - @Override - public FunnelEntity updateFunnel(final Revision revision, final FunnelDTO funnelDTO) { - final Funnel funnelNode = funnelDAO.getFunnel(funnelDTO.getId()); - final RevisionUpdate<FunnelDTO> snapshot = updateComponent(revision, - funnelNode, - () -> funnelDAO.updateFunnel(funnelDTO), - funnel -> dtoFactory.createFunnelDto(funnel)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnelNode); - return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - - /** - * Updates a component with the given revision, using the provided supplier to call - * into the appropriate DAO and the provided function to convert the component into a DTO. - * - * @param revision the current revision - * @param daoUpdate a Supplier that will update the component via the appropriate DAO - * @param dtoCreation a Function to convert a component into a dao - * @param <D> the DTO Type of the updated component - * @param <C> the Component Type of the updated component - * @return A RevisionUpdate that represents the new configuration - */ - private <D, C> RevisionUpdate<D> updateComponent(final Revision revision, final Authorizable authorizable, final Supplier<C> daoUpdate, final Function<C, D> dtoCreation) { - try { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - final RevisionUpdate<D> updatedComponent = revisionManager.updateRevision(new StandardRevisionClaim(revision), user, new UpdateRevisionTask<D>() { - @Override - public RevisionUpdate<D> update() { - // get the updated component - final C component = daoUpdate.get(); - - // save updated controller - controllerFacade.save(); - - final D dto = dtoCreation.apply(component); - - final Revision updatedRevision = revisionManager.getRevision(revision.getComponentId()).incrementRevision(revision.getClientId()); - final FlowModification lastModification = new FlowModification(updatedRevision, user.getIdentity()); - return new StandardRevisionUpdate<>(dto, lastModification); - } - }); - - return updatedComponent; - } catch (final ExpiredRevisionClaimException erce) { - throw new InvalidRevisionException("Failed to update component " + authorizable, erce); - } - } - - - @Override - public void verifyUpdateSnippet(final SnippetDTO snippetDto, final Set<String> affectedComponentIds) { - // if snippet does not exist, then the update request is likely creating it - // so we don't verify since it will fail - if (snippetDAO.hasSnippet(snippetDto.getId())) { - snippetDAO.verifyUpdateSnippetComponent(snippetDto); - } - } - - @Override - public SnippetEntity updateSnippet(final Set<Revision> revisions, final SnippetDTO snippetDto) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final RevisionClaim revisionClaim = new StandardRevisionClaim(revisions); - - final RevisionUpdate<SnippetDTO> snapshot; - try { - snapshot = revisionManager.updateRevision(revisionClaim, user, new UpdateRevisionTask<SnippetDTO>() { - @Override - public RevisionUpdate<SnippetDTO> update() { - // get the updated component - final Snippet snippet = snippetDAO.updateSnippetComponents(snippetDto); - - // drop the snippet - snippetDAO.dropSnippet(snippet.getId()); - - // save updated controller - controllerFacade.save(); - - // increment the revisions - final Set<Revision> updatedRevisions = revisions.stream().map(revision -> { - final Revision currentRevision = revisionManager.getRevision(revision.getComponentId()); - return currentRevision.incrementRevision(revision.getClientId()); - }).collect(Collectors.toSet()); - - final SnippetDTO dto = dtoFactory.createSnippetDto(snippet); - return new StandardRevisionUpdate<>(dto, null, updatedRevisions); - } - }); - } catch (final ExpiredRevisionClaimException e) { - throw new InvalidRevisionException("Failed to update Snippet", e); - } - - return entityFactory.createSnippetEntity(snapshot.getComponent()); - } - - @Override - public PortEntity updateInputPort(final Revision revision, final PortDTO inputPortDTO) { - final Port inputPortNode = inputPortDAO.getPort(inputPortDTO.getId()); - final RevisionUpdate<PortDTO> snapshot = updateComponent(revision, - inputPortNode, - () -> inputPortDAO.updatePort(inputPortDTO), - port -> dtoFactory.createPortDto(port)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(inputPortNode); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(inputPortNode)); - final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortNode.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(inputPortNode.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public PortEntity updateOutputPort(final Revision revision, final PortDTO outputPortDTO) { - final Port outputPortNode = outputPortDAO.getPort(outputPortDTO.getId()); - final RevisionUpdate<PortDTO> snapshot = updateComponent(revision, - outputPortNode, - () -> outputPortDAO.updatePort(outputPortDTO), - port -> dtoFactory.createPortDto(port)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(outputPortNode); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(outputPortNode), NiFiUserUtils.getNiFiUser()); - final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortNode.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(outputPortNode.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public RemoteProcessGroupEntity updateRemoteProcessGroup(final Revision revision, final RemoteProcessGroupDTO remoteProcessGroupDTO) { - final RemoteProcessGroup remoteProcessGroupNode = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupDTO.getId()); - final RevisionUpdate<RemoteProcessGroupDTO> snapshot = updateComponent( - revision, - remoteProcessGroupNode, - () -> remoteProcessGroupDAO.updateRemoteProcessGroup(remoteProcessGroupDTO), - remoteProcessGroup -> dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroupNode); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(remoteProcessGroupNode)); - final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification()); - final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(remoteProcessGroupNode, - controllerFacade.getRemoteProcessGroupStatus(remoteProcessGroupNode.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(remoteProcessGroupNode.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), updateRevision, permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public RemoteProcessGroupPortEntity updateRemoteProcessGroupInputPort( - final Revision revision, final String remoteProcessGroupId, final RemoteProcessGroupPortDTO remoteProcessGroupPortDTO) { - - final RemoteProcessGroup remoteProcessGroupNode = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupPortDTO.getGroupId()); - final RevisionUpdate<RemoteProcessGroupPortDTO> snapshot = updateComponent( - revision, - remoteProcessGroupNode, - () -> remoteProcessGroupDAO.updateRemoteProcessGroupInputPort(remoteProcessGroupId, remoteProcessGroupPortDTO), - remoteGroupPort -> dtoFactory.createRemoteProcessGroupPortDto(remoteGroupPort)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroupNode); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(remoteProcessGroupNode)); - final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification()); - return entityFactory.createRemoteProcessGroupPortEntity(snapshot.getComponent(), updatedRevision, permissions, operatePermissions); - } - - @Override - public RemoteProcessGroupPortEntity updateRemoteProcessGroupOutputPort( - final Revision revision, final String remoteProcessGroupId, final RemoteProcessGroupPortDTO remoteProcessGroupPortDTO) { - - final RemoteProcessGroup remoteProcessGroupNode = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupPortDTO.getGroupId()); - final RevisionUpdate<RemoteProcessGroupPortDTO> snapshot = updateComponent( - revision, - remoteProcessGroupNode, - () -> remoteProcessGroupDAO.updateRemoteProcessGroupOutputPort(remoteProcessGroupId, remoteProcessGroupPortDTO), - remoteGroupPort -> dtoFactory.createRemoteProcessGroupPortDto(remoteGroupPort)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroupNode); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(remoteProcessGroupNode)); - final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification()); - return entityFactory.createRemoteProcessGroupPortEntity(snapshot.getComponent(), updatedRevision, permissions, operatePermissions); - } - - @Override - public Set<AffectedComponentDTO> getActiveComponentsAffectedByVariableRegistryUpdate(final VariableRegistryDTO variableRegistryDto) { - final ProcessGroup group = processGroupDAO.getProcessGroup(variableRegistryDto.getProcessGroupId()); - if (group == null) { - throw new ResourceNotFoundException("Could not find Process Group with ID " + variableRegistryDto.getProcessGroupId()); - } - - final Map<String, String> variableMap = new HashMap<>(); - variableRegistryDto.getVariables().stream() // have to use forEach here instead of using Collectors.toMap because value may be null - .map(VariableEntity::getVariable) - .forEach(var -> variableMap.put(var.getName(), var.getValue())); - - final Set<AffectedComponentDTO> affectedComponentDtos = new HashSet<>(); - - final Set<String> updatedVariableNames = getUpdatedVariables(group, variableMap); - for (final String variableName : updatedVariableNames) { - final Set<ComponentNode> affectedComponents = group.getComponentsAffectedByVariable(variableName); - - for (final ComponentNode component : affectedComponents) { - if (component instanceof ProcessorNode) { - final ProcessorNode procNode = (ProcessorNode) component; - if (procNode.isRunning()) { - affectedComponentDtos.add(dtoFactory.createAffectedComponentDto(procNode)); - } - } else if (component instanceof ControllerServiceNode) { - final ControllerServiceNode serviceNode = (ControllerServiceNode) component; - if (serviceNode.isActive()) { - affectedComponentDtos.add(dtoFactory.createAffectedComponentDto(serviceNode)); - } - } else { - throw new RuntimeException("Found unexpected type of Component [" + component.getCanonicalClassName() + "] dependending on variable"); - } - } - } - - return affectedComponentDtos; - } - - @Override - public Set<AffectedComponentEntity> getComponentsAffectedByVariableRegistryUpdate(final VariableRegistryDTO variableRegistryDto) { - final ProcessGroup group = processGroupDAO.getProcessGroup(variableRegistryDto.getProcessGroupId()); - if (group == null) { - throw new ResourceNotFoundException("Could not find Process Group with ID " + variableRegistryDto.getProcessGroupId()); - } - - final Map<String, String> variableMap = new HashMap<>(); - variableRegistryDto.getVariables().stream() // have to use forEach here instead of using Collectors.toMap because value may be null - .map(VariableEntity::getVariable) - .forEach(var -> variableMap.put(var.getName(), var.getValue())); - - final Set<AffectedComponentEntity> affectedComponentEntities = new HashSet<>(); - - final Set<String> updatedVariableNames = getUpdatedVariables(group, variableMap); - for (final String variableName : updatedVariableNames) { - final Set<ComponentNode> affectedComponents = group.getComponentsAffectedByVariable(variableName); - affectedComponentEntities.addAll(dtoFactory.createAffectedComponentEntities(affectedComponents, revisionManager)); - } - - return affectedComponentEntities; - } - - private Set<String> getUpdatedVariables(final ProcessGroup group, final Map<String, String> newVariableValues) { - final Set<String> updatedVariableNames = new HashSet<>(); - - final ComponentVariableRegistry registry = group.getVariableRegistry(); - for (final Map.Entry<String, String> entry : newVariableValues.entrySet()) { - final String varName = entry.getKey(); - final String newValue = entry.getValue(); - - final String curValue = registry.getVariableValue(varName); - if (!Objects.equals(newValue, curValue)) { - updatedVariableNames.add(varName); - } - } - - return updatedVariableNames; - } - - - @Override - public VariableRegistryEntity updateVariableRegistry(Revision revision, VariableRegistryDTO variableRegistryDto) { - final ProcessGroup processGroupNode = processGroupDAO.getProcessGroup(variableRegistryDto.getProcessGroupId()); - final RevisionUpdate<VariableRegistryDTO> snapshot = updateComponent(revision, - processGroupNode, - () -> processGroupDAO.updateVariableRegistry(variableRegistryDto), - processGroup -> dtoFactory.createVariableRegistryDto(processGroup, revisionManager)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroupNode); - final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification()); - return entityFactory.createVariableRegistryEntity(snapshot.getComponent(), updatedRevision, permissions); - } - - - @Override - public ProcessGroupEntity updateProcessGroup(final Revision revision, final ProcessGroupDTO processGroupDTO) { - final ProcessGroup processGroupNode = processGroupDAO.getProcessGroup(processGroupDTO.getId()); - final RevisionUpdate<ProcessGroupDTO> snapshot = updateComponent(revision, - processGroupNode, - () -> processGroupDAO.updateProcessGroup(processGroupDTO), - processGroup -> dtoFactory.createProcessGroupDto(processGroup)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroupNode); - final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(snapshot.getLastModification()); - final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroupNode.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroupNode.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createProcessGroupEntity(snapshot.getComponent(), updatedRevision, permissions, status, bulletinEntities); - } - - @Override - public void verifyUpdateProcessGroup(ProcessGroupDTO processGroupDTO) { - if (processGroupDAO.hasProcessGroup(processGroupDTO.getId())) { - processGroupDAO.verifyUpdate(processGroupDTO); - } - } - - @Override - public ScheduleComponentsEntity enableComponents(String processGroupId, ScheduledState state, Map<String, Revision> componentRevisions) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - final RevisionUpdate<ScheduleComponentsEntity> updatedComponent = revisionManager.updateRevision(new StandardRevisionClaim(componentRevisions.values()), user, new - UpdateRevisionTask<ScheduleComponentsEntity>() { - @Override - public RevisionUpdate<ScheduleComponentsEntity> update() { - // schedule the components - processGroupDAO.enableComponents(processGroupId, state, componentRevisions.keySet()); - - // update the revisions - final Map<String, Revision> updatedRevisions = new HashMap<>(); - for (final Revision revision : componentRevisions.values()) { - final Revision currentRevision = revisionManager.getRevision(revision.getComponentId()); - updatedRevisions.put(revision.getComponentId(), currentRevision.incrementRevision(revision.getClientId())); - } - - // save - controllerFacade.save(); - - // gather details for response - final ScheduleComponentsEntity entity = new ScheduleComponentsEntity(); - entity.setId(processGroupId); - entity.setState(state.name()); - return new StandardRevisionUpdate<>(entity, null, new HashSet<>(updatedRevisions.values())); - } - }); - - return updatedComponent.getComponent(); - } - - @Override - public ScheduleComponentsEntity scheduleComponents(final String processGroupId, final ScheduledState state, final Map<String, Revision> componentRevisions) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final RevisionUpdate<ScheduleComponentsEntity> updatedComponent = revisionManager.updateRevision(new StandardRevisionClaim(componentRevisions.values()), user, new - UpdateRevisionTask<ScheduleComponentsEntity>() { - @Override - public RevisionUpdate<ScheduleComponentsEntity> update() { - // schedule the components - processGroupDAO.scheduleComponents(processGroupId, state, componentRevisions.keySet()); - - // update the revisions - final Map<String, Revision> updatedRevisions = new HashMap<>(); - for (final Revision revision : componentRevisions.values()) { - final Revision currentRevision = revisionManager.getRevision(revision.getComponentId()); - updatedRevisions.put(revision.getComponentId(), currentRevision.incrementRevision(revision.getClientId())); - } - - // save - controllerFacade.save(); - - // gather details for response - final ScheduleComponentsEntity entity = new ScheduleComponentsEntity(); - entity.setId(processGroupId); - entity.setState(state.name()); - return new StandardRevisionUpdate<>(entity, null, new HashSet<>(updatedRevisions.values())); - } - }); - - return updatedComponent.getComponent(); - } - - @Override - public ActivateControllerServicesEntity activateControllerServices(final String processGroupId, final ControllerServiceState state, final Map<String, Revision> serviceRevisions) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final RevisionUpdate<ActivateControllerServicesEntity> updatedComponent = revisionManager.updateRevision(new StandardRevisionClaim(serviceRevisions.values()), user, - new UpdateRevisionTask<ActivateControllerServicesEntity>() { - @Override - public RevisionUpdate<ActivateControllerServicesEntity> update() { - // schedule the components - processGroupDAO.activateControllerServices(processGroupId, state, serviceRevisions.keySet()); - - // update the revisions - final Map<String, Revision> updatedRevisions = new HashMap<>(); - for (final Revision revision : serviceRevisions.values()) { - final Revision currentRevision = revisionManager.getRevision(revision.getComponentId()); - updatedRevisions.put(revision.getComponentId(), currentRevision.incrementRevision(revision.getClientId())); - } - - // save - controllerFacade.save(); - - // gather details for response - final ActivateControllerServicesEntity entity = new ActivateControllerServicesEntity(); - entity.setId(processGroupId); - entity.setState(state.name()); - return new StandardRevisionUpdate<>(entity, null, new HashSet<>(updatedRevisions.values())); - } - }); - - return updatedComponent.getComponent(); - } - - - @Override - public ControllerConfigurationEntity updateControllerConfiguration(final Revision revision, final ControllerConfigurationDTO controllerConfigurationDTO) { - final RevisionUpdate<ControllerConfigurationDTO> updatedComponent = updateComponent( - revision, - controllerFacade, - () -> { - if (controllerConfigurationDTO.getMaxTimerDrivenThreadCount() != null) { - controllerFacade.setMaxTimerDrivenThreadCount(controllerConfigurationDTO.getMaxTimerDrivenThreadCount()); - } - if (controllerConfigurationDTO.getMaxEventDrivenThreadCount() != null) { - controllerFacade.setMaxEventDrivenThreadCount(controllerConfigurationDTO.getMaxEventDrivenThreadCount()); - } - - return controllerConfigurationDTO; - }, - controller -> dtoFactory.createControllerConfigurationDto(controllerFacade)); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerFacade); - final RevisionDTO updateRevision = dtoFactory.createRevisionDTO(updatedComponent.getLastModification()); - return entityFactory.createControllerConfigurationEntity(updatedComponent.getComponent(), updateRevision, permissions); - } - - - @Override - public NodeDTO updateNode(final NodeDTO nodeDTO) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - if (user == null) { - throw new WebApplicationException(new Throwable("Unable to access details for current user.")); - } - final String userDn = user.getIdentity(); - - final NodeIdentifier nodeId = clusterCoordinator.getNodeIdentifier(nodeDTO.getNodeId()); - if (nodeId == null) { - throw new UnknownNodeException("No node exists with ID " + nodeDTO.getNodeId()); - } - - - if (NodeConnectionState.CONNECTING.name().equalsIgnoreCase(nodeDTO.getStatus())) { - clusterCoordinator.requestNodeConnect(nodeId, userDn); - } else if (NodeConnectionState.OFFLOADING.name().equalsIgnoreCase(nodeDTO.getStatus())) { - clusterCoordinator.requestNodeOffload(nodeId, OffloadCode.OFFLOADED, - "User " + userDn + " requested that node be offloaded"); - } else if (NodeConnectionState.DISCONNECTING.name().equalsIgnoreCase(nodeDTO.getStatus())) { - clusterCoordinator.requestNodeDisconnect(nodeId, DisconnectionCode.USER_DISCONNECTED, - "User " + userDn + " requested that node be disconnected from cluster"); - } - - return getNode(nodeId); - } - - @Override - public CounterDTO updateCounter(final String counterId) { - return dtoFactory.createCounterDto(controllerFacade.resetCounter(counterId)); - } - - @Override - public void verifyCanClearProcessorState(final String processorId) { - processorDAO.verifyClearState(processorId); - } - - @Override - public void clearProcessorState(final String processorId) { - processorDAO.clearState(processorId); - } - - @Override - public void verifyCanClearControllerServiceState(final String controllerServiceId) { - controllerServiceDAO.verifyClearState(controllerServiceId); - } - - @Override - public void clearControllerServiceState(final String controllerServiceId) { - controllerServiceDAO.clearState(controllerServiceId); - } - - @Override - public void verifyCanClearReportingTaskState(final String reportingTaskId) { - reportingTaskDAO.verifyClearState(reportingTaskId); - } - - @Override - public void clearReportingTaskState(final String reportingTaskId) { - reportingTaskDAO.clearState(reportingTaskId); - } - - @Override - public ConnectionEntity deleteConnection(final Revision revision, final String connectionId) { - final Connection connection = connectionDAO.getConnection(connectionId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); - final ConnectionDTO snapshot = deleteComponent( - revision, - connection.getResource(), - () -> connectionDAO.deleteConnection(connectionId), - false, // no policies to remove - dtoFactory.createConnectionDto(connection)); - - return entityFactory.createConnectionEntity(snapshot, null, permissions, null); - } - - @Override - public DropRequestDTO deleteFlowFileDropRequest(final String connectionId, final String dropRequestId) { - return dtoFactory.createDropRequestDTO(connectionDAO.deleteFlowFileDropRequest(connectionId, dropRequestId)); - } - - @Override - public ListingRequestDTO deleteFlowFileListingRequest(final String connectionId, final String listingRequestId) { - final Connection connection = connectionDAO.getConnection(connectionId); - final ListingRequestDTO listRequest = dtoFactory.createListingRequestDTO(connectionDAO.deleteFlowFileListingRequest(connectionId, listingRequestId)); - - // include whether the source and destination are running - if (connection.getSource() != null) { - listRequest.setSourceRunning(connection.getSource().isRunning()); - } - if (connection.getDestination() != null) { - listRequest.setDestinationRunning(connection.getDestination().isRunning()); - } - - return listRequest; - } - - @Override - public ProcessorEntity deleteProcessor(final Revision revision, final String processorId) { - final ProcessorNode processor = processorDAO.getProcessor(processorId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(processor)); - final ProcessorDTO snapshot = deleteComponent( - revision, - processor.getResource(), - () -> processorDAO.deleteProcessor(processorId), - true, - dtoFactory.createProcessorDto(processor)); - - return entityFactory.createProcessorEntity(snapshot, null, permissions, operatePermissions, null, null); - } - - @Override - public ProcessorEntity terminateProcessor(final String processorId) { - processorDAO.terminate(processorId); - return getProcessor(processorId); - } - - @Override - public void verifyTerminateProcessor(final String processorId) { - processorDAO.verifyTerminate(processorId); - } - - @Override - public LabelEntity deleteLabel(final Revision revision, final String labelId) { - final Label label = labelDAO.getLabel(labelId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label); - final LabelDTO snapshot = deleteComponent( - revision, - label.getResource(), - () -> labelDAO.deleteLabel(labelId), - true, - dtoFactory.createLabelDto(label)); - - return entityFactory.createLabelEntity(snapshot, null, permissions); - } - - @Override - public UserEntity deleteUser(final Revision revision, final String userId) { - final User user = userDAO.getUser(userId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); - final Set<TenantEntity> userGroups = user != null ? userGroupDAO.getUserGroupsForUser(userId).stream() - .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()) : null; - final Set<AccessPolicySummaryEntity> policyEntities = user != null ? userGroupDAO.getAccessPoliciesForUser(userId).stream() - .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()) : null; - - final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userId; - final UserDTO snapshot = deleteComponent( - revision, - new Resource() { - @Override - public String getIdentifier() { - return resourceIdentifier; - } - - @Override - public String getName() { - return resourceIdentifier; - } - - @Override - public String getSafeDescription() { - return "User " + userId; - } - }, - () -> userDAO.deleteUser(userId), - false, // no user specific policies to remove - dtoFactory.createUserDto(user, userGroups, policyEntities)); - - return entityFactory.createUserEntity(snapshot, null, permissions); - } - - @Override - public UserGroupEntity deleteUserGroup(final Revision revision, final String userGroupId) { - final Group userGroup = userGroupDAO.getUserGroup(userGroupId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); - final Set<TenantEntity> users = userGroup != null ? userGroup.getUsers().stream() - .map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()) : null; - final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream() - .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - - final String resourceIdentifier = ResourceFactory.getTenantResource().getIdentifier() + "/" + userGroupId; - final UserGroupDTO snapshot = deleteComponent( - revision, - new Resource() { - @Override - public String getIdentifier() { - return resourceIdentifier; - } - - @Override - public String getName() { - return resourceIdentifier; - } - - @Override - public String getSafeDescription() { - return "User Group " + userGroupId; - } - }, - () -> userGroupDAO.deleteUserGroup(userGroupId), - false, // no user group specific policies to remove - dtoFactory.createUserGroupDto(userGroup, users, policyEntities)); - - return entityFactory.createUserGroupEntity(snapshot, null, permissions); - } - - @Override - public AccessPolicyEntity deleteAccessPolicy(final Revision revision, final String accessPolicyId) { - final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId); - final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyId)); - final Set<TenantEntity> userGroups = accessPolicy != null ? accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()) : null; - final Set<TenantEntity> users = accessPolicy != null ? accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()) : null; - final AccessPolicyDTO snapshot = deleteComponent( - revision, - new Resource() { - @Override - public String getIdentifier() { - return accessPolicy.getResource(); - } - - @Override - public String getName() { - return accessPolicy.getResource(); - } - - @Override - public String getSafeDescription() { - return "Policy " + accessPolicyId; - } - }, - () -> accessPolicyDAO.deleteAccessPolicy(accessPolicyId), - false, // no need to clean up any policies as it's already been removed above - dtoFactory.createAccessPolicyDto(accessPolicy, userGroups, users, componentReference)); - - return entityFactory.createAccessPolicyEntity(snapshot, null, permissions); - } - - @Override - public FunnelEntity deleteFunnel(final Revision revision, final String funnelId) { - final Funnel funnel = funnelDAO.getFunnel(funnelId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel); - final FunnelDTO snapshot = deleteComponent( - revision, - funnel.getResource(), - () -> funnelDAO.deleteFunnel(funnelId), - true, - dtoFactory.createFunnelDto(funnel)); - - return entityFactory.createFunnelEntity(snapshot, null, permissions); - } - - /** - * Deletes a component using the Optimistic Locking Manager - * - * @param revision the current revision - * @param resource the resource being removed - * @param deleteAction the action that deletes the component via the appropriate DAO object - * @param cleanUpPolicies whether or not the policies for this resource should be removed as well - not necessary when there are - * no component specific policies or if the policies of the component are inherited - * @return a dto that represents the new configuration - */ - private <D, C> D deleteComponent(final Revision revision, final Resource resource, final Runnable deleteAction, final boolean cleanUpPolicies, final D dto) { - final RevisionClaim claim = new StandardRevisionClaim(revision); - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - return revisionManager.deleteRevision(claim, user, new DeleteRevisionTask<D>() { - @Override - public D performTask() { - logger.debug("Attempting to delete component {} with claim {}", resource.getIdentifier(), claim); - - // run the delete action - deleteAction.run(); - - // save the flow - controllerFacade.save(); - logger.debug("Deletion of component {} was successful", resource.getIdentifier()); - - if (cleanUpPolicies) { - cleanUpPolicies(resource); - } - - return dto; - } - }); - } - - /** - * Clean up the policies for the specified component resource. - * - * @param componentResource the resource for the component - */ - private void cleanUpPolicies(final Resource componentResource) { - // ensure the authorizer supports configuration - if (accessPolicyDAO.supportsConfigurableAuthorizer()) { - final List<Resource> resources = new ArrayList<>(); - resources.add(componentResource); - resources.add(ResourceFactory.getDataResource(componentResource)); - resources.add(ResourceFactory.getProvenanceDataResource(componentResource)); - resources.add(ResourceFactory.getDataTransferResource(componentResource)); - resources.add(ResourceFactory.getPolicyResource(componentResource)); - - for (final Resource resource : resources) { - for (final RequestAction action : RequestAction.values()) { - try { - // since the component is being deleted, also delete any relevant access policies - final AccessPolicy readPolicy = accessPolicyDAO.getAccessPolicy(action, resource.getIdentifier()); - if (readPolicy != null) { - accessPolicyDAO.deleteAccessPolicy(readPolicy.getIdentifier()); - } - } catch (final Exception e) { - logger.warn(String.format("Unable to remove access policy for %s %s after component removal.", action, resource.getIdentifier()), e); - } - } - } - } - } - - @Override - public void verifyDeleteSnippet(final String snippetId, final Set<String> affectedComponentIds) { - snippetDAO.verifyDeleteSnippetComponents(snippetId); - } - - @Override - public SnippetEntity deleteSnippet(final Set<Revision> revisions, final String snippetId) { - final Snippet snippet = snippetDAO.getSnippet(snippetId); - - // grab the resources in the snippet so we can delete the policies afterwards - final Set<Resource> snippetResources = new HashSet<>(); - snippet.getProcessors().keySet().forEach(id -> snippetResources.add(processorDAO.getProcessor(id).getResource())); - snippet.getInputPorts().keySet().forEach(id -> snippetResources.add(inputPortDAO.getPort(id).getResource())); - snippet.getOutputPorts().keySet().forEach(id -> snippetResources.add(outputPortDAO.getPort(id).getResource())); - snippet.getFunnels().keySet().forEach(id -> snippetResources.add(funnelDAO.getFunnel(id).getResource())); - snippet.getLabels().keySet().forEach(id -> snippetResources.add(labelDAO.getLabel(id).getResource())); - snippet.getRemoteProcessGroups().keySet().forEach(id -> snippetResources.add(remoteProcessGroupDAO.getRemoteProcessGroup(id).getResource())); - snippet.getProcessGroups().keySet().forEach(id -> { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(id); - - // add the process group - snippetResources.add(processGroup.getResource()); - - // add each encapsulated component - processGroup.findAllProcessors().forEach(processor -> snippetResources.add(processor.getResource())); - processGroup.findAllInputPorts().forEach(inputPort -> snippetResources.add(inputPort.getResource())); - processGroup.findAllOutputPorts().forEach(outputPort -> snippetResources.add(outputPort.getResource())); - processGroup.findAllFunnels().forEach(funnel -> snippetResources.add(funnel.getResource())); - processGroup.findAllLabels().forEach(label -> snippetResources.add(label.getResource())); - processGroup.findAllProcessGroups().forEach(childGroup -> snippetResources.add(childGroup.getResource())); - processGroup.findAllRemoteProcessGroups().forEach(remoteProcessGroup -> snippetResources.add(remoteProcessGroup.getResource())); - processGroup.findAllTemplates().forEach(template -> snippetResources.add(template.getResource())); - processGroup.findAllControllerServices().forEach(controllerService -> snippetResources.add(controllerService.getResource())); - }); - - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final RevisionClaim claim = new StandardRevisionClaim(revisions); - final SnippetDTO dto = revisionManager.deleteRevision(claim, user, new DeleteRevisionTask<SnippetDTO>() { - @Override - public SnippetDTO performTask() { - // delete the components in the snippet - snippetDAO.deleteSnippetComponents(snippetId); - - // drop the snippet - snippetDAO.dropSnippet(snippetId); - - // save - controllerFacade.save(); - - // create the dto for the snippet that was just removed - return dtoFactory.createSnippetDto(snippet); - } - }); - - // clean up component policies - snippetResources.forEach(resource -> cleanUpPolicies(resource)); - - return entityFactory.createSnippetEntity(dto); - } - - @Override - public PortEntity deleteInputPort(final Revision revision, final String inputPortId) { - final Port port = inputPortDAO.getPort(inputPortId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(port)); - final PortDTO snapshot = deleteComponent( - revision, - port.getResource(), - () -> inputPortDAO.deletePort(inputPortId), - true, - dtoFactory.createPortDto(port)); - - return entityFactory.createPortEntity(snapshot, null, permissions, operatePermissions, null, null); - } - - @Override - public PortEntity deleteOutputPort(final Revision revision, final String outputPortId) { - final Port port = outputPortDAO.getPort(outputPortId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(port)); - final PortDTO snapshot = deleteComponent( - revision, - port.getResource(), - () -> outputPortDAO.deletePort(outputPortId), - true, - dtoFactory.createPortDto(port)); - - return entityFactory.createPortEntity(snapshot, null, permissions, operatePermissions, null, null); - } - - @Override - public ProcessGroupEntity deleteProcessGroup(final Revision revision, final String groupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - - // grab the resources in the snippet so we can delete the policies afterwards - final Set<Resource> groupResources = new HashSet<>(); - processGroup.findAllProcessors().forEach(processor -> groupResources.add(processor.getResource())); - processGroup.findAllInputPorts().forEach(inputPort -> groupResources.add(inputPort.getResource())); - processGroup.findAllOutputPorts().forEach(outputPort -> groupResources.add(outputPort.getResource())); - processGroup.findAllFunnels().forEach(funnel -> groupResources.add(funnel.getResource())); - processGroup.findAllLabels().forEach(label -> groupResources.add(label.getResource())); - processGroup.findAllProcessGroups().forEach(childGroup -> groupResources.add(childGroup.getResource())); - processGroup.findAllRemoteProcessGroups().forEach(remoteProcessGroup -> groupResources.add(remoteProcessGroup.getResource())); - processGroup.findAllTemplates().forEach(template -> groupResources.add(template.getResource())); - processGroup.findAllControllerServices().forEach(controllerService -> groupResources.add(controllerService.getResource())); - - final ProcessGroupDTO snapshot = deleteComponent( - revision, - processGroup.getResource(), - () -> processGroupDAO.deleteProcessGroup(groupId), - true, - dtoFactory.createProcessGroupDto(processGroup)); - - // delete all applicable component policies - groupResources.forEach(groupResource -> cleanUpPolicies(groupResource)); - - return entityFactory.createProcessGroupEntity(snapshot, null, permissions, null, null); - } - - @Override - public RemoteProcessGroupEntity deleteRemoteProcessGroup(final Revision revision, final String remoteProcessGroupId) { - final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(remoteProcessGroup)); - final RemoteProcessGroupDTO snapshot = deleteComponent( - revision, - remoteProcessGroup.getResource(), - () -> remoteProcessGroupDAO.deleteRemoteProcessGroup(remoteProcessGroupId), - true, - dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup)); - - return entityFactory.createRemoteProcessGroupEntity(snapshot, null, permissions, operatePermissions, null, null); - } - - @Override - public void deleteTemplate(final String id) { - // delete the template and save the flow - templateDAO.deleteTemplate(id); - controllerFacade.save(); - } - - @Override - public ConnectionEntity createConnection(final Revision revision, final String groupId, final ConnectionDTO connectionDTO) { - final RevisionUpdate<ConnectionDTO> snapshot = createComponent( - revision, - connectionDTO, - () -> connectionDAO.createConnection(groupId, connectionDTO), - connection -> dtoFactory.createConnectionDto(connection)); - - final Connection connection = connectionDAO.getConnection(connectionDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); - final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionDTO.getId())); - return entityFactory.createConnectionEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status); - } - - @Override - public DropRequestDTO createFlowFileDropRequest(final String connectionId, final String dropRequestId) { - return dtoFactory.createDropRequestDTO(connectionDAO.createFlowFileDropRequest(connectionId, dropRequestId)); - } - - @Override - public ListingRequestDTO createFlowFileListingRequest(final String connectionId, final String listingRequestId) { - final Connection connection = connectionDAO.getConnection(connectionId); - final ListingRequestDTO listRequest = dtoFactory.createListingRequestDTO(connectionDAO.createFlowFileListingRequest(connectionId, listingRequestId)); - - // include whether the source and destination are running - if (connection.getSource() != null) { - listRequest.setSourceRunning(connection.getSource().isRunning()); - } - if (connection.getDestination() != null) { - listRequest.setDestinationRunning(connection.getDestination().isRunning()); - } - - return listRequest; - } - - @Override - public ProcessorEntity createProcessor(final Revision revision, final String groupId, final ProcessorDTO processorDTO) { - final RevisionUpdate<ProcessorDTO> snapshot = createComponent( - revision, - processorDTO, - () -> processorDAO.createProcessor(groupId, processorDTO), - processor -> { - awaitValidationCompletion(processor); - return dtoFactory.createProcessorDto(processor); - }); - - final ProcessorNode processor = processorDAO.getProcessor(processorDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(processor)); - final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processorDTO.getId())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processorDTO.getId())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createProcessorEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public LabelEntity createLabel(final Revision revision, final String groupId, final LabelDTO labelDTO) { - final RevisionUpdate<LabelDTO> snapshot = createComponent( - revision, - labelDTO, - () -> labelDAO.createLabel(groupId, labelDTO), - label -> dtoFactory.createLabelDto(label)); - - final Label label = labelDAO.getLabel(labelDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label); - return entityFactory.createLabelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - /** - * Creates a component using the optimistic locking manager. - * - * @param componentDto the DTO that will be used to create the component - * @param daoCreation A Supplier that will create the NiFi Component to use - * @param dtoCreation a Function that will convert the NiFi Component into a corresponding DTO - * @param <D> the DTO Type - * @param <C> the NiFi Component Type - * @return a RevisionUpdate that represents the updated configuration - */ - private <D, C> RevisionUpdate<D> createComponent(final Revision revision, final ComponentDTO componentDto, final Supplier<C> daoCreation, final Function<C, D> dtoCreation) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - // read lock on the containing group - // request claim for component to be created... revision already verified (version == 0) - final RevisionClaim claim = new StandardRevisionClaim(revision); - - // update revision through revision manager - return revisionManager.updateRevision(claim, user, () -> { - // add the component - final C component = daoCreation.get(); - - // save the flow - controllerFacade.save(); - - final D dto = dtoCreation.apply(component); - final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity()); - return new StandardRevisionUpdate<>(dto, lastMod); - }); - } - - @Override - public BulletinEntity createBulletin(final BulletinDTO bulletinDTO, final Boolean canRead){ - final Bulletin bulletin = BulletinFactory.createBulletin(bulletinDTO.getCategory(),bulletinDTO.getLevel(),bulletinDTO.getMessage()); - bulletinRepository.addBulletin(bulletin); - return entityFactory.createBulletinEntity(dtoFactory.createBulletinDto(bulletin),canRead); - } - - @Override - public FunnelEntity createFunnel(final Revision revision, final String groupId, final FunnelDTO funnelDTO) { - final RevisionUpdate<FunnelDTO> snapshot = createComponent( - revision, - funnelDTO, - () -> funnelDAO.createFunnel(groupId, funnelDTO), - funnel -> dtoFactory.createFunnelDto(funnel)); - - final Funnel funnel = funnelDAO.getFunnel(funnelDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel); - return entityFactory.createFunnelEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions); - } - - @Override - public AccessPolicyEntity createAccessPolicy(final Revision revision, final AccessPolicyDTO accessPolicyDTO) { - final Authorizable tenantAuthorizable = authorizableLookup.getTenant(); - final String creator = NiFiUserUtils.getNiFiUserIdentity(); - - final AccessPolicy newAccessPolicy = accessPolicyDAO.createAccessPolicy(accessPolicyDTO); - final ComponentReferenceEntity componentReference = createComponentReferenceEntity(newAccessPolicy.getResource()); - final AccessPolicyDTO newAccessPolicyDto = dtoFactory.createAccessPolicyDto(newAccessPolicy, - newAccessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()), - newAccessPolicy.getUsers().stream().map(userId -> { - final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId)); - return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(userDAO.getUser(userId)), userRevision, - dtoFactory.createPermissionsDto(tenantAuthorizable)); - }).collect(Collectors.toSet()), componentReference); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicyDTO.getId())); - return entityFactory.createAccessPolicyEntity(newAccessPolicyDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions); - } - - @Override - public UserEntity createUser(final Revision revision, final UserDTO userDTO) { - final String creator = NiFiUserUtils.getNiFiUserIdentity(); - final User newUser = userDAO.createUser(userDTO); - final Set<TenantEntity> tenantEntities = userGroupDAO.getUserGroupsForUser(newUser.getIdentifier()).stream() - .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()); - final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUser(newUser.getIdentifier()).stream() - .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - final UserDTO newUserDto = dtoFactory.createUserDto(newUser, tenantEntities, policyEntities); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); - return entityFactory.createUserEntity(newUserDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions); - } - - private ComponentReferenceEntity createComponentReferenceEntity(final String resource) { - ComponentReferenceEntity componentReferenceEntity = null; - try { - // get the component authorizable - Authorizable componentAuthorizable = authorizableLookup.getAuthorizableFromResource(resource); - - // if this represents an authorizable whose policy permissions are enforced through the base resource, - // get the underlying base authorizable for the component reference - if (componentAuthorizable instanceof EnforcePolicyPermissionsThroughBaseResource) { - componentAuthorizable = ((EnforcePolicyPermissionsThroughBaseResource) componentAuthorizable).getBaseAuthorizable(); - } - - final ComponentReferenceDTO componentReference = dtoFactory.createComponentReferenceDto(componentAuthorizable); - if (componentReference != null) { - final PermissionsDTO componentReferencePermissions = dtoFactory.createPermissionsDto(componentAuthorizable); - final RevisionDTO componentReferenceRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(componentReference.getId())); - componentReferenceEntity = entityFactory.createComponentReferenceEntity(componentReference, componentReferenceRevision, componentReferencePermissions); - } - } catch (final ResourceNotFoundException e) { - // component not found for the specified resource - } - - return componentReferenceEntity; - } - - private AccessPolicySummaryEntity createAccessPolicySummaryEntity(final AccessPolicy ap) { - final ComponentReferenceEntity componentReference = createComponentReferenceEntity(ap.getResource()); - final AccessPolicySummaryDTO apSummary = dtoFactory.createAccessPolicySummaryDto(ap, componentReference); - final PermissionsDTO apPermissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(ap.getIdentifier())); - final RevisionDTO apRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(ap.getIdentifier())); - return entityFactory.createAccessPolicySummaryEntity(apSummary, apRevision, apPermissions); - } - - @Override - public UserGroupEntity createUserGroup(final Revision revision, final UserGroupDTO userGroupDTO) { - final String creator = NiFiUserUtils.getNiFiUserIdentity(); - final Group newUserGroup = userGroupDAO.createUserGroup(userGroupDTO); - final Set<TenantEntity> tenantEntities = newUserGroup.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()); - final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(newUserGroup.getIdentifier()).stream() - .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - final UserGroupDTO newUserGroupDto = dtoFactory.createUserGroupDto(newUserGroup, tenantEntities, policyEntities); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); - return entityFactory.createUserGroupEntity(newUserGroupDto, dtoFactory.createRevisionDTO(new FlowModification(revision, creator)), permissions); - } - - private void validateSnippetContents(final FlowSnippetDTO flow) { - // validate any processors - if (flow.getProcessors() != null) { - for (final ProcessorDTO processorDTO : flow.getProcessors()) { - final ProcessorNode processorNode = processorDAO.getProcessor(processorDTO.getId()); - processorDTO.setValidationStatus(processorNode.getValidationStatus().name()); - - final Collection<ValidationResult> validationErrors = processorNode.getValidationErrors(); - if (validationErrors != null && !validationErrors.isEmpty()) { - final List<String> errors = new ArrayList<>(); - for (final ValidationResult validationResult : validationErrors) { - errors.add(validationResult.toString()); - } - processorDTO.setValidationErrors(errors); - } - } - } - - if (flow.getInputPorts() != null) { - for (final PortDTO portDTO : flow.getInputPorts()) { - final Port port = inputPortDAO.getPort(portDTO.getId()); - final Collection<ValidationResult> validationErrors = port.getValidationErrors(); - if (validationErrors != null && !validationErrors.isEmpty()) { - final List<String> errors = new ArrayList<>(); - for (final ValidationResult validationResult : validationErrors) { - errors.add(validationResult.toString()); - } - portDTO.setValidationErrors(errors); - } - } - } - - if (flow.getOutputPorts() != null) { - for (final PortDTO portDTO : flow.getOutputPorts()) { - final Port port = outputPortDAO.getPort(portDTO.getId()); - final Collection<ValidationResult> validationErrors = port.getValidationErrors(); - if (validationErrors != null && !validationErrors.isEmpty()) { - final List<String> errors = new ArrayList<>(); - for (final ValidationResult validationResult : validationErrors) { - errors.add(validationResult.toString()); - } - portDTO.setValidationErrors(errors); - } - } - } - - // get any remote process group issues - if (flow.getRemoteProcessGroups() != null) { - for (final RemoteProcessGroupDTO remoteProcessGroupDTO : flow.getRemoteProcessGroups()) { - final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupDTO.getId()); - - if (remoteProcessGroup.getAuthorizationIssue() != null) { - remoteProcessGroupDTO.setAuthorizationIssues(Arrays.asList(remoteProcessGroup.getAuthorizationIssue())); - } - } - } - } - - @Override - public FlowEntity copySnippet(final String groupId, final String snippetId, final Double originX, final Double originY, final String idGenerationSeed) { - // create the new snippet - final FlowSnippetDTO snippet = snippetDAO.copySnippet(groupId, snippetId, originX, originY, idGenerationSeed); - - // save the flow - controllerFacade.save(); - - // drop the snippet - snippetDAO.dropSnippet(snippetId); - - // post process new flow snippet - final FlowDTO flowDto = postProcessNewFlowSnippet(groupId, snippet); - - final FlowEntity flowEntity = new FlowEntity(); - flowEntity.setFlow(flowDto); - return flowEntity; - } - - @Override - public SnippetEntity createSnippet(final SnippetDTO snippetDTO) { - // add the component - final Snippet snippet = snippetDAO.createSnippet(snippetDTO); - - // save the flow - controllerFacade.save(); - - final SnippetDTO dto = dtoFactory.createSnippetDto(snippet); - final RevisionUpdate<SnippetDTO> snapshot = new StandardRevisionUpdate<>(dto, null); - - return entityFactory.createSnippetEntity(snapshot.getComponent()); - } - - @Override - public PortEntity createInputPort(final Revision revision, final String groupId, final PortDTO inputPortDTO) { - final RevisionUpdate<PortDTO> snapshot = createComponent( - revision, - inputPortDTO, - () -> inputPortDAO.createPort(groupId, inputPortDTO), - port -> dtoFactory.createPortDto(port)); - - final Port port = inputPortDAO.getPort(inputPortDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(port)); - final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(port.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public PortEntity createOutputPort(final Revision revision, final String groupId, final PortDTO outputPortDTO) { - final RevisionUpdate<PortDTO> snapshot = createComponent( - revision, - outputPortDTO, - () -> outputPortDAO.createPort(groupId, outputPortDTO), - port -> dtoFactory.createPortDto(port)); - - final Port port = outputPortDAO.getPort(outputPortDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(port)); - final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(port.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createPortEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public ProcessGroupEntity createProcessGroup(final Revision revision, final String parentGroupId, final ProcessGroupDTO processGroupDTO) { - final RevisionUpdate<ProcessGroupDTO> snapshot = createComponent( - revision, - processGroupDTO, - () -> processGroupDAO.createProcessGroup(parentGroupId, processGroupDTO), - processGroup -> dtoFactory.createProcessGroupDto(processGroup)); - - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(processGroupDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroup.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroup.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createProcessGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, status, bulletinEntities); - } - - @Override - public RemoteProcessGroupEntity createRemoteProcessGroup(final Revision revision, final String groupId, final RemoteProcessGroupDTO remoteProcessGroupDTO) { - final RevisionUpdate<RemoteProcessGroupDTO> snapshot = createComponent( - revision, - remoteProcessGroupDTO, - () -> remoteProcessGroupDAO.createRemoteProcessGroup(groupId, remoteProcessGroupDTO), - remoteProcessGroup -> dtoFactory.createRemoteProcessGroupDto(remoteProcessGroup)); - - final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(remoteProcessGroup)); - final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(remoteProcessGroup, controllerFacade.getRemoteProcessGroupStatus(remoteProcessGroup.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(remoteProcessGroup.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createRemoteProcessGroupEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), - permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public boolean isRemoteGroupPortConnected(final String remoteProcessGroupId, final String remotePortId) { - final RemoteProcessGroup rpg = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId); - RemoteGroupPort port = rpg.getInputPort(remotePortId); - if (port != null) { - return port.hasIncomingConnection(); - } - - port = rpg.getOutputPort(remotePortId); - if (port != null) { - return !port.getConnections().isEmpty(); - } - - throw new ResourceNotFoundException("Could not find Port with ID " + remotePortId + " as a child of RemoteProcessGroup with ID " + remoteProcessGroupId); - } - - @Override - public void verifyCanAddTemplate(String groupId, String name) { - templateDAO.verifyCanAddTemplate(name, groupId); - } - - @Override - public void verifyComponentTypes(FlowSnippetDTO snippet) { - templateDAO.verifyComponentTypes(snippet); - } - - @Override - public void verifyComponentTypes(final VersionedProcessGroup versionedGroup) { - controllerFacade.verifyComponentTypes(versionedGroup); - } - - @Override - public void verifyImportProcessGroup(final VersionControlInformationDTO versionControlInfo, final VersionedProcessGroup contents, final String groupId) { - final ProcessGroup group = processGroupDAO.getProcessGroup(groupId); - verifyImportProcessGroup(versionControlInfo, contents, group); - } - - private void verifyImportProcessGroup(final VersionControlInformationDTO vciDto, final VersionedProcessGroup contents, final ProcessGroup group) { - if (group == null) { - return; - } - - final VersionControlInformation vci = group.getVersionControlInformation(); - if (vci != null) { - // Note that we do not compare the Registry ID here because there could be two registry clients - // that point to the same server (one could point to localhost while another points to 127.0.0.1, for instance).. - if (Objects.equals(vciDto.getBucketId(), vci.getBucketIdentifier()) - && Objects.equals(vciDto.getFlowId(), vci.getFlowIdentifier())) { - - throw new IllegalStateException("Cannot import the specified Versioned Flow into the Process Group because doing so would cause a recursive dataflow. " - + "If Process Group A contains Process Group B, then Process Group B is not allowed to contain the flow identified by Process Group A."); - } - } - - final Set<VersionedProcessGroup> childGroups = contents.getProcessGroups(); - if (childGroups != null) { - for (final VersionedProcessGroup childGroup : childGroups) { - final VersionedFlowCoordinates childCoordinates = childGroup.getVersionedFlowCoordinates(); - if (childCoordinates != null) { - final VersionControlInformationDTO childVci = new VersionControlInformationDTO(); - childVci.setBucketId(childCoordinates.getBucketId()); - childVci.setFlowId(childCoordinates.getFlowId()); - verifyImportProcessGroup(childVci, childGroup, group); - } - } - } - - verifyImportProcessGroup(vciDto, contents, group.getParent()); - } - - @Override - public TemplateDTO createTemplate(final String name, final String description, final String snippetId, final String groupId, final Optional<String> idGenerationSeed) { - // get the specified snippet - final Snippet snippet = snippetDAO.getSnippet(snippetId); - - // create the template - final TemplateDTO templateDTO = new TemplateDTO(); - templateDTO.setName(name); - templateDTO.setDescription(description); - templateDTO.setTimestamp(new Date()); - templateDTO.setSnippet(snippetUtils.populateFlowSnippet(snippet, true, true, true)); - templateDTO.setEncodingVersion(TemplateDTO.MAX_ENCODING_VERSION); - - // set the id based on the specified seed - final String uuid = idGenerationSeed.isPresent() ? (UUID.nameUUIDFromBytes(idGenerationSeed.get().getBytes(StandardCharsets.UTF_8))).toString() : UUID.randomUUID().toString(); - templateDTO.setId(uuid); - - // create the template - final Template template = templateDAO.createTemplate(templateDTO, groupId); - - // drop the snippet - snippetDAO.dropSnippet(snippetId); - - // save the flow - controllerFacade.save(); - - return dtoFactory.createTemplateDTO(template); - } - - /** - * Ensures default values are populated for all components in this snippet. This is necessary to handle old templates without default values - * and when existing properties have default values introduced. - * - * @param snippet snippet - */ - private void ensureDefaultPropertyValuesArePopulated(final FlowSnippetDTO snippet) { - if (snippet != null) { - if (snippet.getControllerServices() != null) { - snippet.getControllerServices().forEach(dto -> { - if (dto.getProperties() == null) { - dto.setProperties(new LinkedHashMap<>()); - } - - try { - final ConfigurableComponent configurableComponent = controllerFacade.getTemporaryComponent(dto.getType(), dto.getBundle()); - configurableComponent.getPropertyDescriptors().forEach(descriptor -> { - if (dto.getProperties().get(descriptor.getName()) == null) { - dto.getProperties().put(descriptor.getName(), descriptor.getDefaultValue()); - } - }); - } catch (final Exception e) { - logger.warn(String.format("Unable to create ControllerService of type %s to populate default values.", dto.getType())); - } - }); - } - - if (snippet.getProcessors() != null) { - snippet.getProcessors().forEach(dto -> { - if (dto.getConfig() == null) { - dto.setConfig(new ProcessorConfigDTO()); - } - - final ProcessorConfigDTO config = dto.getConfig(); - if (config.getProperties() == null) { - config.setProperties(new LinkedHashMap<>()); - } - - try { - final ConfigurableComponent configurableComponent = controllerFacade.getTemporaryComponent(dto.getType(), dto.getBundle()); - configurableComponent.getPropertyDescriptors().forEach(descriptor -> { - if (config.getProperties().get(descriptor.getName()) == null) { - config.getProperties().put(descriptor.getName(), descriptor.getDefaultValue()); - } - }); - } catch (final Exception e) { - logger.warn(String.format("Unable to create Processor of type %s to populate default values.", dto.getType())); - } - }); - } - - if (snippet.getProcessGroups() != null) { - snippet.getProcessGroups().forEach(processGroup -> { - ensureDefaultPropertyValuesArePopulated(processGroup.getContents()); - }); - } - } - } - - @Override - public TemplateDTO importTemplate(final TemplateDTO templateDTO, final String groupId, final Optional<String> idGenerationSeed) { - // ensure id is set - final String uuid = idGenerationSeed.isPresent() ? (UUID.nameUUIDFromBytes(idGenerationSeed.get().getBytes(StandardCharsets.UTF_8))).toString() : UUID.randomUUID().toString(); - templateDTO.setId(uuid); - - // mark the timestamp - templateDTO.setTimestamp(new Date()); - - // ensure default values are populated - ensureDefaultPropertyValuesArePopulated(templateDTO.getSnippet()); - - // import the template - final Template template = templateDAO.importTemplate(templateDTO, groupId); - - // save the flow - controllerFacade.save(); - - // return the template dto - return dtoFactory.createTemplateDTO(template); - } - - /** - * Post processes a new flow snippet including validation, removing the snippet, and DTO conversion. - * - * @param groupId group id - * @param snippet snippet - * @return flow dto - */ - private FlowDTO postProcessNewFlowSnippet(final String groupId, final FlowSnippetDTO snippet) { - // validate the new snippet - validateSnippetContents(snippet); - - // identify all components added - final Set<String> identifiers = new HashSet<>(); - snippet.getProcessors().stream() - .map(proc -> proc.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getConnections().stream() - .map(conn -> conn.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getInputPorts().stream() - .map(port -> port.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getOutputPorts().stream() - .map(port -> port.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getProcessGroups().stream() - .map(group -> group.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getRemoteProcessGroups().stream() - .map(remoteGroup -> remoteGroup.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getRemoteProcessGroups().stream() - .filter(remoteGroup -> remoteGroup.getContents() != null && remoteGroup.getContents().getInputPorts() != null) - .flatMap(remoteGroup -> remoteGroup.getContents().getInputPorts().stream()) - .map(remoteInputPort -> remoteInputPort.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getRemoteProcessGroups().stream() - .filter(remoteGroup -> remoteGroup.getContents() != null && remoteGroup.getContents().getOutputPorts() != null) - .flatMap(remoteGroup -> remoteGroup.getContents().getOutputPorts().stream()) - .map(remoteOutputPort -> remoteOutputPort.getId()) - .forEach(id -> identifiers.add(id)); - snippet.getLabels().stream() - .map(label -> label.getId()) - .forEach(id -> identifiers.add(id)); - - final ProcessGroup group = processGroupDAO.getProcessGroup(groupId); - final ProcessGroupStatus groupStatus = controllerFacade.getProcessGroupStatus(groupId); - return dtoFactory.createFlowDto(group, groupStatus, snippet, revisionManager, this::getProcessGroupBulletins); - } - - @Override - public FlowEntity createTemplateInstance(final String groupId, final Double originX, final Double originY, final String templateEncodingVersion, - final FlowSnippetDTO requestSnippet, final String idGenerationSeed) { - - // instantiate the template - there is no need to make another copy of the flow snippet since the actual template - // was copied and this dto is only used to instantiate it's components (which as already completed) - final FlowSnippetDTO snippet = templateDAO.instantiateTemplate(groupId, originX, originY, templateEncodingVersion, requestSnippet, idGenerationSeed); - - // save the flow - controllerFacade.save(); - - // post process the new flow snippet - final FlowDTO flowDto = postProcessNewFlowSnippet(groupId, snippet); - - final FlowEntity flowEntity = new FlowEntity(); - flowEntity.setFlow(flowDto); - return flowEntity; - } - - @Override - public ControllerServiceEntity createControllerService(final Revision revision, final String groupId, final ControllerServiceDTO controllerServiceDTO) { - controllerServiceDTO.setParentGroupId(groupId); - - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - // request claim for component to be created... revision already verified (version == 0) - final RevisionClaim claim = new StandardRevisionClaim(revision); - - final RevisionUpdate<ControllerServiceDTO> snapshot; - if (groupId == null) { - // update revision through revision manager - snapshot = revisionManager.updateRevision(claim, user, () -> { - // Unfortunately, we can not use the createComponent() method here because createComponent() wants to obtain the read lock - // on the group. The Controller Service may or may not have a Process Group (it won't if it's controller-scoped). - final ControllerServiceNode controllerService = controllerServiceDAO.createControllerService(controllerServiceDTO); - controllerFacade.save(); - - awaitValidationCompletion(controllerService); - final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(controllerService); - - final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity()); - return new StandardRevisionUpdate<>(dto, lastMod); - }); - } else { - snapshot = revisionManager.updateRevision(claim, user, () -> { - final ControllerServiceNode controllerService = controllerServiceDAO.createControllerService(controllerServiceDTO); - controllerFacade.save(); - - awaitValidationCompletion(controllerService); - final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(controllerService); - - final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity()); - return new StandardRevisionUpdate<>(dto, lastMod); - }); - } - - final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(controllerService)); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, bulletinEntities); - } - - @Override - public ControllerServiceEntity updateControllerService(final Revision revision, final ControllerServiceDTO controllerServiceDTO) { - // get the component, ensure we have access to it, and perform the update request - final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceDTO.getId()); - final RevisionUpdate<ControllerServiceDTO> snapshot = updateComponent(revision, - controllerService, - () -> controllerServiceDAO.updateControllerService(controllerServiceDTO), - cs -> { - awaitValidationCompletion(cs); - final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(cs); - final ControllerServiceReference ref = controllerService.getReferences(); - final ControllerServiceReferencingComponentsEntity referencingComponentsEntity = - createControllerServiceReferencingComponentsEntity(ref, Sets.newHashSet(controllerService.getIdentifier())); - dto.setReferencingComponents(referencingComponentsEntity.getControllerServiceReferencingComponents()); - return dto; - }); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(controllerService)); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(controllerServiceDTO.getId())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createControllerServiceEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, bulletinEntities); - } - - - @Override - public ControllerServiceReferencingComponentsEntity updateControllerServiceReferencingComponents( - final Map<String, Revision> referenceRevisions, final String controllerServiceId, final ScheduledState scheduledState, final ControllerServiceState controllerServiceState) { - - final RevisionClaim claim = new StandardRevisionClaim(referenceRevisions.values()); - - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final RevisionUpdate<ControllerServiceReferencingComponentsEntity> update = revisionManager.updateRevision(claim, user, - new UpdateRevisionTask<ControllerServiceReferencingComponentsEntity>() { - @Override - public RevisionUpdate<ControllerServiceReferencingComponentsEntity> update() { - final Set<ComponentNode> updated = controllerServiceDAO.updateControllerServiceReferencingComponents(controllerServiceId, scheduledState, controllerServiceState); - final ControllerServiceReference updatedReference = controllerServiceDAO.getControllerService(controllerServiceId).getReferences(); - - // get the revisions of the updated components - final Map<String, Revision> updatedRevisions = new HashMap<>(); - for (final ComponentNode component : updated) { - final Revision currentRevision = revisionManager.getRevision(component.getIdentifier()); - final Revision requestRevision = referenceRevisions.get(component.getIdentifier()); - updatedRevisions.put(component.getIdentifier(), currentRevision.incrementRevision(requestRevision.getClientId())); - } - - // ensure the revision for all referencing components is included regardless of whether they were updated in this request - for (final ComponentNode component : updatedReference.findRecursiveReferences(ComponentNode.class)) { - updatedRevisions.putIfAbsent(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier())); - } - - final ControllerServiceReferencingComponentsEntity entity = createControllerServiceReferencingComponentsEntity(updatedReference, updatedRevisions); - return new StandardRevisionUpdate<>(entity, null, new HashSet<>(updatedRevisions.values())); - } - }); - - return update.getComponent(); - } - - /** - * Finds the identifiers for all components referencing a ControllerService. - * - * @param reference ControllerServiceReference - * @param visited ControllerServices we've already visited - */ - private void findControllerServiceReferencingComponentIdentifiers(final ControllerServiceReference reference, final Set<ControllerServiceNode> visited) { - for (final ComponentNode component : reference.getReferencingComponents()) { - - // if this is a ControllerService consider it's referencing components - if (component instanceof ControllerServiceNode) { - final ControllerServiceNode node = (ControllerServiceNode) component; - if (!visited.contains(node)) { - visited.add(node); - findControllerServiceReferencingComponentIdentifiers(node.getReferences(), visited); - } - } - } - } - - /** - * Creates entities for components referencing a ControllerService using their current revision. - * - * @param reference ControllerServiceReference - * @return The entity - */ - private ControllerServiceReferencingComponentsEntity createControllerServiceReferencingComponentsEntity(final ControllerServiceReference reference, final Set<String> lockedIds) { - final Set<ControllerServiceNode> visited = new HashSet<>(); - visited.add(reference.getReferencedComponent()); - findControllerServiceReferencingComponentIdentifiers(reference, visited); - - final Map<String, Revision> referencingRevisions = new HashMap<>(); - for (final ComponentNode component : reference.getReferencingComponents()) { - referencingRevisions.put(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier())); - } - - return createControllerServiceReferencingComponentsEntity(reference, referencingRevisions); - } - - /** - * Creates entities for components referencing a ControllerService using the specified revisions. - * - * @param reference ControllerServiceReference - * @param revisions The revisions - * @return The entity - */ - private ControllerServiceReferencingComponentsEntity createControllerServiceReferencingComponentsEntity( - final ControllerServiceReference reference, final Map<String, Revision> revisions) { - final Set<ControllerServiceNode> visited = new HashSet<>(); - visited.add(reference.getReferencedComponent()); - return createControllerServiceReferencingComponentsEntity(reference, revisions, visited); - } - - /** - * Creates entities for components referencing a ControllerServcie using the specified revisions. - * - * @param reference ControllerServiceReference - * @param revisions The revisions - * @param visited Which services we've already considered (in case of cycle) - * @return The entity - */ - private ControllerServiceReferencingComponentsEntity createControllerServiceReferencingComponentsEntity( - final ControllerServiceReference reference, final Map<String, Revision> revisions, final Set<ControllerServiceNode> visited) { - - final String modifier = NiFiUserUtils.getNiFiUserIdentity(); - final Set<ComponentNode> referencingComponents = reference.getReferencingComponents(); - - final Set<ControllerServiceReferencingComponentEntity> componentEntities = new HashSet<>(); - for (final ComponentNode refComponent : referencingComponents) { - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(refComponent); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(refComponent)); - - final Revision revision = revisions.get(refComponent.getIdentifier()); - final FlowModification flowMod = new FlowModification(revision, modifier); - final RevisionDTO revisionDto = dtoFactory.createRevisionDTO(flowMod); - final ControllerServiceReferencingComponentDTO dto = dtoFactory.createControllerServiceReferencingComponentDTO(refComponent); - - if (refComponent instanceof ControllerServiceNode) { - final ControllerServiceNode node = (ControllerServiceNode) refComponent; - - // indicate if we've hit a cycle - dto.setReferenceCycle(visited.contains(node)); - - // mark node as visited before building the reference cycle - visited.add(node); - - // if we haven't encountered this service before include it's referencing components - if (!dto.getReferenceCycle()) { - final ControllerServiceReference refReferences = node.getReferences(); - final Map<String, Revision> referencingRevisions = new HashMap<>(revisions); - for (final ComponentNode component : refReferences.getReferencingComponents()) { - referencingRevisions.putIfAbsent(component.getIdentifier(), revisionManager.getRevision(component.getIdentifier())); - } - final ControllerServiceReferencingComponentsEntity references = createControllerServiceReferencingComponentsEntity(refReferences, referencingRevisions, visited); - dto.setReferencingComponents(references.getControllerServiceReferencingComponents()); - } - } - - componentEntities.add(entityFactory.createControllerServiceReferencingComponentEntity(refComponent.getIdentifier(), dto, revisionDto, permissions, operatePermissions)); - } - - final ControllerServiceReferencingComponentsEntity entity = new ControllerServiceReferencingComponentsEntity(); - entity.setControllerServiceReferencingComponents(componentEntities); - return entity; - } - - @Override - public ControllerServiceEntity deleteControllerService(final Revision revision, final String controllerServiceId) { - final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerService); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(controllerService)); - final ControllerServiceDTO snapshot = deleteComponent( - revision, - controllerService.getResource(), - () -> controllerServiceDAO.deleteControllerService(controllerServiceId), - true, - dtoFactory.createControllerServiceDto(controllerService)); - - return entityFactory.createControllerServiceEntity(snapshot, null, permissions, operatePermissions, null); - } - - - @Override - public RegistryClientEntity createRegistryClient(Revision revision, RegistryDTO registryDTO) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - // request claim for component to be created... revision already verified (version == 0) - final RevisionClaim claim = new StandardRevisionClaim(revision); - - // update revision through revision manager - final RevisionUpdate<FlowRegistry> revisionUpdate = revisionManager.updateRevision(claim, user, () -> { - // add the component - final FlowRegistry registry = registryDAO.createFlowRegistry(registryDTO); - - // save the flow - controllerFacade.save(); - - final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity()); - return new StandardRevisionUpdate<>(registry, lastMod); - }); - - final FlowRegistry registry = revisionUpdate.getComponent(); - return createRegistryClientEntity(registry); - } - - @Override - public RegistryClientEntity getRegistryClient(final String registryId) { - final FlowRegistry registry = registryDAO.getFlowRegistry(registryId); - return createRegistryClientEntity(registry); - } - - private RegistryClientEntity createRegistryClientEntity(final FlowRegistry flowRegistry) { - if (flowRegistry == null) { - return null; - } - - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(flowRegistry.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getController()); - final RegistryDTO dto = dtoFactory.createRegistryDto(flowRegistry); - - return entityFactory.createRegistryClientEntity(dto, revision, permissions); - } - - private VersionedFlowEntity createVersionedFlowEntity(final String registryId, final VersionedFlow versionedFlow) { - if (versionedFlow == null) { - return null; - } - - final VersionedFlowDTO dto = new VersionedFlowDTO(); - dto.setRegistryId(registryId); - dto.setBucketId(versionedFlow.getBucketIdentifier()); - dto.setFlowId(versionedFlow.getIdentifier()); - dto.setFlowName(versionedFlow.getName()); - dto.setDescription(versionedFlow.getDescription()); - - final VersionedFlowEntity entity = new VersionedFlowEntity(); - entity.setVersionedFlow(dto); - - return entity; - } - - private VersionedFlowSnapshotMetadataEntity createVersionedFlowSnapshotMetadataEntity(final String registryId, final VersionedFlowSnapshotMetadata metadata) { - if (metadata == null) { - return null; - } - - final VersionedFlowSnapshotMetadataEntity entity = new VersionedFlowSnapshotMetadataEntity(); - entity.setRegistryId(registryId); - entity.setVersionedFlowMetadata(metadata); - - return entity; - } - - @Override - public Set<RegistryClientEntity> getRegistryClients() { - return registryDAO.getFlowRegistries().stream() - .map(this::createRegistryClientEntity) - .collect(Collectors.toSet()); - } - - @Override - public Set<RegistryEntity> getRegistriesForUser(final NiFiUser user) { - return registryDAO.getFlowRegistriesForUser(user).stream() - .map(flowRegistry -> entityFactory.createRegistryEntity(dtoFactory.createRegistryDto(flowRegistry))) - .collect(Collectors.toSet()); - } - - @Override - public Set<BucketEntity> getBucketsForUser(final String registryId, final NiFiUser user) { - return registryDAO.getBucketsForUser(registryId, user).stream() - .map(bucket -> { - if (bucket == null) { - return null; - } - - final BucketDTO dto = new BucketDTO(); - dto.setId(bucket.getIdentifier()); - dto.setName(bucket.getName()); - dto.setDescription(bucket.getDescription()); - dto.setCreated(bucket.getCreatedTimestamp()); - - final Permissions regPermissions = bucket.getPermissions(); - final PermissionsDTO permissions = new PermissionsDTO(); - permissions.setCanRead(regPermissions.getCanRead()); - permissions.setCanWrite(regPermissions.getCanWrite()); - - return entityFactory.createBucketEntity(dto, permissions); - }) - .collect(Collectors.toSet()); - } - - @Override - public Set<VersionedFlowEntity> getFlowsForUser(String registryId, String bucketId, NiFiUser user) { - return registryDAO.getFlowsForUser(registryId, bucketId, user).stream() - .map(vf -> createVersionedFlowEntity(registryId, vf)) - .collect(Collectors.toSet()); - } - - @Override - public Set<VersionedFlowSnapshotMetadataEntity> getFlowVersionsForUser(String registryId, String bucketId, String flowId, NiFiUser user) { - return registryDAO.getFlowVersionsForUser(registryId, bucketId, flowId, user).stream() - .map(md -> createVersionedFlowSnapshotMetadataEntity(registryId, md)) - .collect(Collectors.toSet()); - } - - @Override - public RegistryClientEntity updateRegistryClient(Revision revision, RegistryDTO registryDTO) { - final RevisionClaim revisionClaim = new StandardRevisionClaim(revision); - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - final FlowRegistry registry = registryDAO.getFlowRegistry(registryDTO.getId()); - final RevisionUpdate<FlowRegistry> revisionUpdate = revisionManager.updateRevision(revisionClaim, user, () -> { - final boolean duplicateName = registryDAO.getFlowRegistries().stream() - .anyMatch(reg -> reg.getName().equals(registryDTO.getName()) && !reg.getIdentifier().equals(registryDTO.getId())); - - if (duplicateName) { - throw new IllegalStateException("Cannot update Flow Registry because a Flow Registry already exists with the name " + registryDTO.getName()); - } - - registry.setDescription(registryDTO.getDescription()); - registry.setName(registryDTO.getName()); - registry.setURL(registryDTO.getUri()); - - controllerFacade.save(); - - final Revision updatedRevision = revisionManager.getRevision(revision.getComponentId()).incrementRevision(revision.getClientId()); - final FlowModification lastModification = new FlowModification(updatedRevision, user.getIdentity()); - - return new StandardRevisionUpdate<>(registry, lastModification); - }); - - final FlowRegistry updatedReg = revisionUpdate.getComponent(); - return createRegistryClientEntity(updatedReg); - } - - @Override - public void verifyDeleteRegistry(String registryId) { - processGroupDAO.verifyDeleteFlowRegistry(registryId); - } - - @Override - public RegistryClientEntity deleteRegistryClient(final Revision revision, final String registryId) { - final RevisionClaim claim = new StandardRevisionClaim(revision); - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - final FlowRegistry registry = revisionManager.deleteRevision(claim, user, () -> { - final FlowRegistry reg = registryDAO.removeFlowRegistry(registryId); - controllerFacade.save(); - return reg; - }); - - return createRegistryClientEntity(registry); - } - - @Override - public ReportingTaskEntity createReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - // request claim for component to be created... revision already verified (version == 0) - final RevisionClaim claim = new StandardRevisionClaim(revision); - - // update revision through revision manager - final RevisionUpdate<ReportingTaskDTO> snapshot = revisionManager.updateRevision(claim, user, () -> { - // create the reporting task - final ReportingTaskNode reportingTask = reportingTaskDAO.createReportingTask(reportingTaskDTO); - - // save the update - controllerFacade.save(); - awaitValidationCompletion(reportingTask); - - final ReportingTaskDTO dto = dtoFactory.createReportingTaskDto(reportingTask); - final FlowModification lastMod = new FlowModification(revision.incrementRevision(revision.getClientId()), user.getIdentity()); - return new StandardRevisionUpdate<>(dto, lastMod); - }); - - final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId()); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(reportingTask)); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, bulletinEntities); - } - - @Override - public ReportingTaskEntity updateReportingTask(final Revision revision, final ReportingTaskDTO reportingTaskDTO) { - // get the component, ensure we have access to it, and perform the update request - final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskDTO.getId()); - final RevisionUpdate<ReportingTaskDTO> snapshot = updateComponent(revision, - reportingTask, - () -> reportingTaskDAO.updateReportingTask(reportingTaskDTO), - rt -> { - awaitValidationCompletion(rt); - return dtoFactory.createReportingTaskDto(rt); - }); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(reportingTask)); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createReportingTaskEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification()), permissions, operatePermissions, bulletinEntities); - } - - @Override - public ReportingTaskEntity deleteReportingTask(final Revision revision, final String reportingTaskId) { - final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(reportingTask)); - final ReportingTaskDTO snapshot = deleteComponent( - revision, - reportingTask.getResource(), - () -> reportingTaskDAO.deleteReportingTask(reportingTaskId), - true, - dtoFactory.createReportingTaskDto(reportingTask)); - - return entityFactory.createReportingTaskEntity(snapshot, null, permissions, operatePermissions, null); - } - - @Override - public void deleteActions(final Date endDate) { - // get the user from the request - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - if (user == null) { - throw new WebApplicationException(new Throwable("Unable to access details for current user.")); - } - - // create the purge details - final FlowChangePurgeDetails details = new FlowChangePurgeDetails(); - details.setEndDate(endDate); - - // create a purge action to record that records are being removed - final FlowChangeAction purgeAction = new FlowChangeAction(); - purgeAction.setUserIdentity(user.getIdentity()); - purgeAction.setOperation(Operation.Purge); - purgeAction.setTimestamp(new Date()); - purgeAction.setSourceId("Flow Controller"); - purgeAction.setSourceName("History"); - purgeAction.setSourceType(Component.Controller); - purgeAction.setActionDetails(details); - - // purge corresponding actions - auditService.purgeActions(endDate, purgeAction); - } - - @Override - public ProvenanceDTO submitProvenance(final ProvenanceDTO query) { - return controllerFacade.submitProvenance(query); - } - - @Override - public void deleteProvenance(final String queryId) { - controllerFacade.deleteProvenanceQuery(queryId); - } - - @Override - public LineageDTO submitLineage(final LineageDTO lineage) { - return controllerFacade.submitLineage(lineage); - } - - @Override - public void deleteLineage(final String lineageId) { - controllerFacade.deleteLineage(lineageId); - } - - @Override - public ProvenanceEventDTO submitReplay(final Long eventId) { - return controllerFacade.submitReplay(eventId); - } - - // ----------------------------------------- - // Read Operations - // ----------------------------------------- - - @Override - public SearchResultsDTO searchController(final String query) { - return controllerFacade.search(query); - } - - @Override - public DownloadableContent getContent(final String connectionId, final String flowFileUuid, final String uri) { - return connectionDAO.getContent(connectionId, flowFileUuid, uri); - } - - @Override - public DownloadableContent getContent(final Long eventId, final String uri, final ContentDirection contentDirection) { - return controllerFacade.getContent(eventId, uri, contentDirection); - } - - @Override - public ProvenanceDTO getProvenance(final String queryId, final Boolean summarize, final Boolean incrementalResults) { - return controllerFacade.getProvenanceQuery(queryId, summarize, incrementalResults); - } - - @Override - public LineageDTO getLineage(final String lineageId) { - return controllerFacade.getLineage(lineageId); - } - - @Override - public ProvenanceOptionsDTO getProvenanceSearchOptions() { - return controllerFacade.getProvenanceSearchOptions(); - } - - @Override - public ProvenanceEventDTO getProvenanceEvent(final Long id) { - return controllerFacade.getProvenanceEvent(id); - } - - @Override - public ProcessGroupStatusEntity getProcessGroupStatus(final String groupId, final boolean recursive) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - final ProcessGroupStatusDTO dto = dtoFactory.createProcessGroupStatusDto(processGroup, controllerFacade.getProcessGroupStatus(groupId)); - - // prune the response as necessary - if (!recursive) { - pruneChildGroups(dto.getAggregateSnapshot()); - if (dto.getNodeSnapshots() != null) { - for (final NodeProcessGroupStatusSnapshotDTO nodeSnapshot : dto.getNodeSnapshots()) { - pruneChildGroups(nodeSnapshot.getStatusSnapshot()); - } - } - } - - return entityFactory.createProcessGroupStatusEntity(dto, permissions); - } - - private void pruneChildGroups(final ProcessGroupStatusSnapshotDTO snapshot) { - for (final ProcessGroupStatusSnapshotEntity childProcessGroupStatusEntity : snapshot.getProcessGroupStatusSnapshots()) { - final ProcessGroupStatusSnapshotDTO childProcessGroupStatus = childProcessGroupStatusEntity.getProcessGroupStatusSnapshot(); - childProcessGroupStatus.setConnectionStatusSnapshots(null); - childProcessGroupStatus.setProcessGroupStatusSnapshots(null); - childProcessGroupStatus.setInputPortStatusSnapshots(null); - childProcessGroupStatus.setOutputPortStatusSnapshots(null); - childProcessGroupStatus.setProcessorStatusSnapshots(null); - childProcessGroupStatus.setRemoteProcessGroupStatusSnapshots(null); - } - } - - @Override - public ControllerStatusDTO getControllerStatus() { - return controllerFacade.getControllerStatus(); - } - - @Override - public ComponentStateDTO getProcessorState(final String processorId) { - final StateMap clusterState = isClustered() ? processorDAO.getState(processorId, Scope.CLUSTER) : null; - final StateMap localState = processorDAO.getState(processorId, Scope.LOCAL); - - // processor will be non null as it was already found when getting the state - final ProcessorNode processor = processorDAO.getProcessor(processorId); - return dtoFactory.createComponentStateDTO(processorId, processor.getProcessor().getClass(), localState, clusterState); - } - - @Override - public ComponentStateDTO getControllerServiceState(final String controllerServiceId) { - final StateMap clusterState = isClustered() ? controllerServiceDAO.getState(controllerServiceId, Scope.CLUSTER) : null; - final StateMap localState = controllerServiceDAO.getState(controllerServiceId, Scope.LOCAL); - - // controller service will be non null as it was already found when getting the state - final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId); - return dtoFactory.createComponentStateDTO(controllerServiceId, controllerService.getControllerServiceImplementation().getClass(), localState, clusterState); - } - - @Override - public ComponentStateDTO getReportingTaskState(final String reportingTaskId) { - final StateMap clusterState = isClustered() ? reportingTaskDAO.getState(reportingTaskId, Scope.CLUSTER) : null; - final StateMap localState = reportingTaskDAO.getState(reportingTaskId, Scope.LOCAL); - - // reporting task will be non null as it was already found when getting the state - final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId); - return dtoFactory.createComponentStateDTO(reportingTaskId, reportingTask.getReportingTask().getClass(), localState, clusterState); - } - - @Override - public CountersDTO getCounters() { - final List<Counter> counters = controllerFacade.getCounters(); - final Set<CounterDTO> counterDTOs = new LinkedHashSet<>(counters.size()); - for (final Counter counter : counters) { - counterDTOs.add(dtoFactory.createCounterDto(counter)); - } - - final CountersSnapshotDTO snapshotDto = dtoFactory.createCountersDto(counterDTOs); - final CountersDTO countersDto = new CountersDTO(); - countersDto.setAggregateSnapshot(snapshotDto); - - return countersDto; - } - - private ConnectionEntity createConnectionEntity(final Connection connection) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(connection.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); - final ConnectionStatusDTO status = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connection.getIdentifier())); - return entityFactory.createConnectionEntity(dtoFactory.createConnectionDto(connection), revision, permissions, status); - } - - @Override - public Set<ConnectionEntity> getConnections(final String groupId) { - final Set<Connection> connections = connectionDAO.getConnections(groupId); - return connections.stream() - .map(connection -> createConnectionEntity(connection)) - .collect(Collectors.toSet()); - } - - @Override - public ConnectionEntity getConnection(final String connectionId) { - final Connection connection = connectionDAO.getConnection(connectionId); - return createConnectionEntity(connection); - } - - @Override - public DropRequestDTO getFlowFileDropRequest(final String connectionId, final String dropRequestId) { - return dtoFactory.createDropRequestDTO(connectionDAO.getFlowFileDropRequest(connectionId, dropRequestId)); - } - - @Override - public ListingRequestDTO getFlowFileListingRequest(final String connectionId, final String listingRequestId) { - final Connection connection = connectionDAO.getConnection(connectionId); - final ListingRequestDTO listRequest = dtoFactory.createListingRequestDTO(connectionDAO.getFlowFileListingRequest(connectionId, listingRequestId)); - - // include whether the source and destination are running - if (connection.getSource() != null) { - listRequest.setSourceRunning(connection.getSource().isRunning()); - } - if (connection.getDestination() != null) { - listRequest.setDestinationRunning(connection.getDestination().isRunning()); - } - - return listRequest; - } - - @Override - public FlowFileDTO getFlowFile(final String connectionId, final String flowFileUuid) { - return dtoFactory.createFlowFileDTO(connectionDAO.getFlowFile(connectionId, flowFileUuid)); - } - - @Override - public ConnectionStatusEntity getConnectionStatus(final String connectionId) { - final Connection connection = connectionDAO.getConnection(connectionId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); - final ConnectionStatusDTO dto = dtoFactory.createConnectionStatusDto(controllerFacade.getConnectionStatus(connectionId)); - return entityFactory.createConnectionStatusEntity(dto, permissions); - } - - @Override - public StatusHistoryEntity getConnectionStatusHistory(final String connectionId) { - final Connection connection = connectionDAO.getConnection(connectionId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(connection); - final StatusHistoryDTO dto = controllerFacade.getConnectionStatusHistory(connectionId); - return entityFactory.createStatusHistoryEntity(dto, permissions); - } - - private ProcessorEntity createProcessorEntity(final ProcessorNode processor, final NiFiUser user) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(processor.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor, user); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(processor)); - final ProcessorStatusDTO status = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processor.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processor.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createProcessorEntity(dtoFactory.createProcessorDto(processor), revision, permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public Set<ProcessorEntity> getProcessors(final String groupId, final boolean includeDescendants) { - final Set<ProcessorNode> processors = processorDAO.getProcessors(groupId, includeDescendants); - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - return processors.stream() - .map(processor -> createProcessorEntity(processor, user)) - .collect(Collectors.toSet()); - } - - @Override - public TemplateDTO exportTemplate(final String id) { - final Template template = templateDAO.getTemplate(id); - final TemplateDTO templateDetails = template.getDetails(); - - final TemplateDTO templateDTO = dtoFactory.createTemplateDTO(template); - templateDTO.setSnippet(dtoFactory.copySnippetContents(templateDetails.getSnippet())); - return templateDTO; - } - - @Override - public TemplateDTO getTemplate(final String id) { - return dtoFactory.createTemplateDTO(templateDAO.getTemplate(id)); - } - - @Override - public Set<TemplateEntity> getTemplates() { - return templateDAO.getTemplates().stream() - .map(template -> { - final TemplateDTO dto = dtoFactory.createTemplateDTO(template); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(template); - - final TemplateEntity entity = new TemplateEntity(); - entity.setId(dto.getId()); - entity.setPermissions(permissions); - entity.setTemplate(dto); - return entity; - }).collect(Collectors.toSet()); - } - - @Override - public Set<DocumentedTypeDTO> getWorkQueuePrioritizerTypes() { - return controllerFacade.getFlowFileComparatorTypes(); - } - - @Override - public Set<DocumentedTypeDTO> getProcessorTypes(final String bundleGroup, final String bundleArtifact, final String type) { - return controllerFacade.getFlowFileProcessorTypes(bundleGroup, bundleArtifact, type); - } - - @Override - public Set<DocumentedTypeDTO> getControllerServiceTypes(final String serviceType, final String serviceBundleGroup, final String serviceBundleArtifact, final String serviceBundleVersion, - final String bundleGroup, final String bundleArtifact, final String type) { - return controllerFacade.getControllerServiceTypes(serviceType, serviceBundleGroup, serviceBundleArtifact, serviceBundleVersion, bundleGroup, bundleArtifact, type); - } - - @Override - public Set<DocumentedTypeDTO> getReportingTaskTypes(final String bundleGroup, final String bundleArtifact, final String type) { - return controllerFacade.getReportingTaskTypes(bundleGroup, bundleArtifact, type); - } - - @Override - public ProcessorEntity getProcessor(final String id) { - final ProcessorNode processor = processorDAO.getProcessor(id); - return createProcessorEntity(processor, NiFiUserUtils.getNiFiUser()); - } - - @Override - public PropertyDescriptorDTO getProcessorPropertyDescriptor(final String id, final String property) { - final ProcessorNode processor = processorDAO.getProcessor(id); - PropertyDescriptor descriptor = processor.getPropertyDescriptor(property); - - // return an invalid descriptor if the processor doesn't support this property - if (descriptor == null) { - descriptor = new PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build(); - } - - return dtoFactory.createPropertyDescriptorDto(descriptor, processor.getProcessGroup().getIdentifier()); - } - - @Override - public ProcessorStatusEntity getProcessorStatus(final String id) { - final ProcessorNode processor = processorDAO.getProcessor(id); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); - final ProcessorStatusDTO dto = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(id)); - return entityFactory.createProcessorStatusEntity(dto, permissions); - } - - @Override - public StatusHistoryEntity getProcessorStatusHistory(final String id) { - final ProcessorNode processor = processorDAO.getProcessor(id); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processor); - final StatusHistoryDTO dto = controllerFacade.getProcessorStatusHistory(id); - return entityFactory.createStatusHistoryEntity(dto, permissions); - } - - private boolean authorizeBulletin(final Bulletin bulletin) { - final String sourceId = bulletin.getSourceId(); - final ComponentType type = bulletin.getSourceType(); - - final Authorizable authorizable; - try { - switch (type) { - case PROCESSOR: - authorizable = authorizableLookup.getProcessor(sourceId).getAuthorizable(); - break; - case REPORTING_TASK: - authorizable = authorizableLookup.getReportingTask(sourceId).getAuthorizable(); - break; - case CONTROLLER_SERVICE: - authorizable = authorizableLookup.getControllerService(sourceId).getAuthorizable(); - break; - case FLOW_CONTROLLER: - authorizable = controllerFacade; - break; - case INPUT_PORT: - authorizable = authorizableLookup.getInputPort(sourceId); - break; - case OUTPUT_PORT: - authorizable = authorizableLookup.getOutputPort(sourceId); - break; - case REMOTE_PROCESS_GROUP: - authorizable = authorizableLookup.getRemoteProcessGroup(sourceId); - break; - default: - throw new WebApplicationException(Response.serverError().entity("An unexpected type of component is the source of this bulletin.").build()); - } - } catch (final ResourceNotFoundException e) { - // if the underlying component is gone, disallow - return false; - } - - // perform the authorization - final AuthorizationResult result = authorizable.checkAuthorization(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); - return Result.Approved.equals(result.getResult()); - } - - @Override - public BulletinBoardDTO getBulletinBoard(final BulletinQueryDTO query) { - // build the query - final BulletinQuery.Builder queryBuilder = new BulletinQuery.Builder() - .groupIdMatches(query.getGroupId()) - .sourceIdMatches(query.getSourceId()) - .nameMatches(query.getName()) - .messageMatches(query.getMessage()) - .after(query.getAfter()) - .limit(query.getLimit()); - - // perform the query - final List<Bulletin> results = bulletinRepository.findBulletins(queryBuilder.build()); - - // perform the query and generate the results - iterating in reverse order since we are - // getting the most recent results by ordering by timestamp desc above. this gets the - // exact results we want but in reverse order - final List<BulletinEntity> bulletinEntities = new ArrayList<>(); - for (final ListIterator<Bulletin> bulletinIter = results.listIterator(results.size()); bulletinIter.hasPrevious(); ) { - final Bulletin bulletin = bulletinIter.previous(); - bulletinEntities.add(entityFactory.createBulletinEntity(dtoFactory.createBulletinDto(bulletin), authorizeBulletin(bulletin))); - } - - // create the bulletin board - final BulletinBoardDTO bulletinBoard = new BulletinBoardDTO(); - bulletinBoard.setBulletins(bulletinEntities); - bulletinBoard.setGenerated(new Date()); - return bulletinBoard; - } - - @Override - public SystemDiagnosticsDTO getSystemDiagnostics() { - final SystemDiagnostics sysDiagnostics = controllerFacade.getSystemDiagnostics(); - return dtoFactory.createSystemDiagnosticsDto(sysDiagnostics); - } - - @Override - public List<ResourceDTO> getResources() { - final List<Resource> resources = controllerFacade.getResources(); - final List<ResourceDTO> resourceDtos = new ArrayList<>(resources.size()); - for (final Resource resource : resources) { - resourceDtos.add(dtoFactory.createResourceDto(resource)); - } - return resourceDtos; - } - - @Override - public void discoverCompatibleBundles(VersionedProcessGroup versionedGroup) { - BundleUtils.discoverCompatibleBundles(controllerFacade.getExtensionManager(), versionedGroup); - } - - @Override - public BundleCoordinate getCompatibleBundle(String type, BundleDTO bundleDTO) { - return BundleUtils.getCompatibleBundle(controllerFacade.getExtensionManager(), type, bundleDTO); - } - - @Override - public ConfigurableComponent getTempComponent(String classType, BundleCoordinate bundleCoordinate) { - return controllerFacade.getExtensionManager().getTempComponent(classType, bundleCoordinate); - } - - /** - * Ensures the specified user has permission to access the specified port. This method does - * not utilize the DataTransferAuthorizable as that will enforce the entire chain is - * authorized for the transfer. This method is only invoked when obtaining the site to site - * details so the entire chain isn't necessary. - */ - private boolean isUserAuthorized(final NiFiUser user, final RootGroupPort port) { - final boolean isSiteToSiteSecure = Boolean.TRUE.equals(properties.isSiteToSiteSecure()); - - // if site to site is not secure, allow all users - if (!isSiteToSiteSecure) { - return true; - } - - final Map<String, String> userContext; - if (user.getClientAddress() != null && !user.getClientAddress().trim().isEmpty()) { - userContext = new HashMap<>(); - userContext.put(UserContextKeys.CLIENT_ADDRESS.name(), user.getClientAddress()); - } else { - userContext = null; - } - - final AuthorizationRequest request = new AuthorizationRequest.Builder() - .resource(ResourceFactory.getDataTransferResource(port.getResource())) - .identity(user.getIdentity()) - .groups(user.getGroups()) - .anonymous(user.isAnonymous()) - .accessAttempt(false) - .action(RequestAction.WRITE) - .userContext(userContext) - .explanationSupplier(() -> "Unable to retrieve port details.") - .build(); - - final AuthorizationResult result = authorizer.authorize(request); - return Result.Approved.equals(result.getResult()); - } - - @Override - public ControllerDTO getSiteToSiteDetails() { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - if (user == null) { - throw new WebApplicationException(new Throwable("Unable to access details for current user.")); - } - - // serialize the input ports this NiFi has access to - final Set<PortDTO> inputPortDtos = new LinkedHashSet<>(); - final Set<RootGroupPort> inputPorts = controllerFacade.getInputPorts(); - for (final RootGroupPort inputPort : inputPorts) { - if (isUserAuthorized(user, inputPort)) { - final PortDTO dto = new PortDTO(); - dto.setId(inputPort.getIdentifier()); - dto.setName(inputPort.getName()); - dto.setComments(inputPort.getComments()); - dto.setState(inputPort.getScheduledState().toString()); - inputPortDtos.add(dto); - } - } - - // serialize the output ports this NiFi has access to - final Set<PortDTO> outputPortDtos = new LinkedHashSet<>(); - for (final RootGroupPort outputPort : controllerFacade.getOutputPorts()) { - if (isUserAuthorized(user, outputPort)) { - final PortDTO dto = new PortDTO(); - dto.setId(outputPort.getIdentifier()); - dto.setName(outputPort.getName()); - dto.setComments(outputPort.getComments()); - dto.setState(outputPort.getScheduledState().toString()); - outputPortDtos.add(dto); - } - } - - // get the root group - final ProcessGroup rootGroup = processGroupDAO.getProcessGroup(controllerFacade.getRootGroupId()); - final ProcessGroupCounts counts = rootGroup.getCounts(); - - // create the controller dto - final ControllerDTO controllerDTO = new ControllerDTO(); - controllerDTO.setId(controllerFacade.getRootGroupId()); - controllerDTO.setInstanceId(controllerFacade.getInstanceId()); - controllerDTO.setName(controllerFacade.getName()); - controllerDTO.setComments(controllerFacade.getComments()); - controllerDTO.setInputPorts(inputPortDtos); - controllerDTO.setOutputPorts(outputPortDtos); - controllerDTO.setInputPortCount(inputPortDtos.size()); - controllerDTO.setOutputPortCount(outputPortDtos.size()); - controllerDTO.setRunningCount(counts.getRunningCount()); - controllerDTO.setStoppedCount(counts.getStoppedCount()); - controllerDTO.setInvalidCount(counts.getInvalidCount()); - controllerDTO.setDisabledCount(counts.getDisabledCount()); - - // determine the site to site configuration - controllerDTO.setRemoteSiteListeningPort(controllerFacade.getRemoteSiteListeningPort()); - controllerDTO.setRemoteSiteHttpListeningPort(controllerFacade.getRemoteSiteListeningHttpPort()); - controllerDTO.setSiteToSiteSecure(controllerFacade.isRemoteSiteCommsSecure()); - - return controllerDTO; - } - - @Override - public ControllerConfigurationEntity getControllerConfiguration() { - final Revision rev = revisionManager.getRevision(FlowController.class.getSimpleName()); - final ControllerConfigurationDTO dto = dtoFactory.createControllerConfigurationDto(controllerFacade); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(controllerFacade); - final RevisionDTO revision = dtoFactory.createRevisionDTO(rev); - return entityFactory.createControllerConfigurationEntity(dto, revision, permissions); - } - - @Override - public ControllerBulletinsEntity getControllerBulletins() { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final ControllerBulletinsEntity controllerBulletinsEntity = new ControllerBulletinsEntity(); - - final List<BulletinEntity> controllerBulletinEntities = new ArrayList<>(); - - final Authorizable controllerAuthorizable = authorizableLookup.getController(); - final boolean authorized = controllerAuthorizable.isAuthorized(authorizer, RequestAction.READ, user); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForController()); - controllerBulletinEntities.addAll(bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, authorized)).collect(Collectors.toList())); - - // get the controller service bulletins - final BulletinQuery controllerServiceQuery = new BulletinQuery.Builder().sourceType(ComponentType.CONTROLLER_SERVICE).build(); - final List<Bulletin> allControllerServiceBulletins = bulletinRepository.findBulletins(controllerServiceQuery); - final List<BulletinEntity> controllerServiceBulletinEntities = new ArrayList<>(); - for (final Bulletin bulletin : allControllerServiceBulletins) { - try { - final Authorizable controllerServiceAuthorizable = authorizableLookup.getControllerService(bulletin.getSourceId()).getAuthorizable(); - final boolean controllerServiceAuthorized = controllerServiceAuthorizable.isAuthorized(authorizer, RequestAction.READ, user); - - final BulletinEntity controllerServiceBulletin = entityFactory.createBulletinEntity(dtoFactory.createBulletinDto(bulletin), controllerServiceAuthorized); - controllerServiceBulletinEntities.add(controllerServiceBulletin); - controllerBulletinEntities.add(controllerServiceBulletin); - } catch (final ResourceNotFoundException e) { - // controller service missing.. skip - } - } - controllerBulletinsEntity.setControllerServiceBulletins(controllerServiceBulletinEntities); - - // get the reporting task bulletins - final BulletinQuery reportingTaskQuery = new BulletinQuery.Builder().sourceType(ComponentType.REPORTING_TASK).build(); - final List<Bulletin> allReportingTaskBulletins = bulletinRepository.findBulletins(reportingTaskQuery); - final List<BulletinEntity> reportingTaskBulletinEntities = new ArrayList<>(); - for (final Bulletin bulletin : allReportingTaskBulletins) { - try { - final Authorizable reportingTaskAuthorizable = authorizableLookup.getReportingTask(bulletin.getSourceId()).getAuthorizable(); - final boolean reportingTaskAuthorizableAuthorized = reportingTaskAuthorizable.isAuthorized(authorizer, RequestAction.READ, user); - - final BulletinEntity reportingTaskBulletin = entityFactory.createBulletinEntity(dtoFactory.createBulletinDto(bulletin), reportingTaskAuthorizableAuthorized); - reportingTaskBulletinEntities.add(reportingTaskBulletin); - controllerBulletinEntities.add(reportingTaskBulletin); - } catch (final ResourceNotFoundException e) { - // reporting task missing.. skip - } - } - controllerBulletinsEntity.setReportingTaskBulletins(reportingTaskBulletinEntities); - - controllerBulletinsEntity.setBulletins(pruneAndSortBulletins(controllerBulletinEntities, BulletinRepository.MAX_BULLETINS_FOR_CONTROLLER)); - return controllerBulletinsEntity; - } - - @Override - public FlowConfigurationEntity getFlowConfiguration() { - final FlowConfigurationDTO dto = dtoFactory.createFlowConfigurationDto(properties.getAutoRefreshInterval(), - properties.getDefaultBackPressureObjectThreshold(), properties.getDefaultBackPressureDataSizeThreshold(),properties.getDcaeDistributorApiHostname()); - final FlowConfigurationEntity entity = new FlowConfigurationEntity(); - entity.setFlowConfiguration(dto); - return entity; - } - - @Override - public AccessPolicyEntity getAccessPolicy(final String accessPolicyId) { - final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(accessPolicyId); - return createAccessPolicyEntity(accessPolicy); - } - - @Override - public AccessPolicyEntity getAccessPolicy(final RequestAction requestAction, final String resource) { - Authorizable authorizable; - try { - authorizable = authorizableLookup.getAuthorizableFromResource(resource); - } catch (final ResourceNotFoundException e) { - // unable to find the underlying authorizable... user authorized based on top level /policies... create - // an anonymous authorizable to attempt to locate an existing policy for this resource - authorizable = new Authorizable() { - @Override - public Authorizable getParentAuthorizable() { - return null; - } - - @Override - public Resource getResource() { - return new Resource() { - @Override - public String getIdentifier() { - return resource; - } - - @Override - public String getName() { - return resource; - } - - @Override - public String getSafeDescription() { - return "Policy " + resource; - } - }; - } - }; - } - - final AccessPolicy accessPolicy = accessPolicyDAO.getAccessPolicy(requestAction, authorizable); - return createAccessPolicyEntity(accessPolicy); - } - - private AccessPolicyEntity createAccessPolicyEntity(final AccessPolicy accessPolicy) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(accessPolicy.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getAccessPolicyById(accessPolicy.getIdentifier())); - final ComponentReferenceEntity componentReference = createComponentReferenceEntity(accessPolicy.getResource()); - return entityFactory.createAccessPolicyEntity( - dtoFactory.createAccessPolicyDto(accessPolicy, - accessPolicy.getGroups().stream().map(mapUserGroupIdToTenantEntity(false)).collect(Collectors.toSet()), - accessPolicy.getUsers().stream().map(mapUserIdToTenantEntity(false)).collect(Collectors.toSet()), componentReference), - revision, permissions); - } - - @Override - public UserEntity getUser(final String userId) { - final User user = userDAO.getUser(userId); - return createUserEntity(user, true); - } - - @Override - public Set<UserEntity> getUsers() { - final Set<User> users = userDAO.getUsers(); - return users.stream() - .map(user -> createUserEntity(user, false)) - .collect(Collectors.toSet()); - } - - private UserEntity createUserEntity(final User user, final boolean enforceUserExistence) { - final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(user.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); - final Set<TenantEntity> userGroups = userGroupDAO.getUserGroupsForUser(user.getIdentifier()).stream() - .map(g -> g.getIdentifier()).map(mapUserGroupIdToTenantEntity(enforceUserExistence)).collect(Collectors.toSet()); - final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUser(user.getIdentifier()).stream() - .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - return entityFactory.createUserEntity(dtoFactory.createUserDto(user, userGroups, policyEntities), userRevision, permissions); - } - - private UserGroupEntity createUserGroupEntity(final Group userGroup, final boolean enforceGroupExistence) { - final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroup.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(authorizableLookup.getTenant()); - final Set<TenantEntity> users = userGroup.getUsers().stream().map(mapUserIdToTenantEntity(enforceGroupExistence)).collect(Collectors.toSet()); - final Set<AccessPolicySummaryEntity> policyEntities = userGroupDAO.getAccessPoliciesForUserGroup(userGroup.getIdentifier()).stream() - .map(ap -> createAccessPolicySummaryEntity(ap)).collect(Collectors.toSet()); - return entityFactory.createUserGroupEntity(dtoFactory.createUserGroupDto(userGroup, users, policyEntities), userGroupRevision, permissions); - } - - @Override - public UserGroupEntity getUserGroup(final String userGroupId) { - final Group userGroup = userGroupDAO.getUserGroup(userGroupId); - return createUserGroupEntity(userGroup, true); - } - - @Override - public Set<UserGroupEntity> getUserGroups() { - final Set<Group> userGroups = userGroupDAO.getUserGroups(); - return userGroups.stream() - .map(userGroup -> createUserGroupEntity(userGroup, false)) - .collect(Collectors.toSet()); - } - - private LabelEntity createLabelEntity(final Label label) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(label.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(label); - return entityFactory.createLabelEntity(dtoFactory.createLabelDto(label), revision, permissions); - } - - @Override - public Set<LabelEntity> getLabels(final String groupId) { - final Set<Label> labels = labelDAO.getLabels(groupId); - return labels.stream() - .map(label -> createLabelEntity(label)) - .collect(Collectors.toSet()); - } - - @Override - public LabelEntity getLabel(final String labelId) { - final Label label = labelDAO.getLabel(labelId); - return createLabelEntity(label); - } - - private FunnelEntity createFunnelEntity(final Funnel funnel) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(funnel.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(funnel); - return entityFactory.createFunnelEntity(dtoFactory.createFunnelDto(funnel), revision, permissions); - } - - @Override - public Set<FunnelEntity> getFunnels(final String groupId) { - final Set<Funnel> funnels = funnelDAO.getFunnels(groupId); - return funnels.stream() - .map(funnel -> createFunnelEntity(funnel)) - .collect(Collectors.toSet()); - } - - @Override - public FunnelEntity getFunnel(final String funnelId) { - final Funnel funnel = funnelDAO.getFunnel(funnelId); - return createFunnelEntity(funnel); - } - - private PortEntity createInputPortEntity(final Port port) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(port.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port, NiFiUserUtils.getNiFiUser()); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(port), NiFiUserUtils.getNiFiUser()); - final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(port.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createPortEntity(dtoFactory.createPortDto(port), revision, permissions, operatePermissions, status, bulletinEntities); - } - - private PortEntity createOutputPortEntity(final Port port) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(port.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(port, NiFiUserUtils.getNiFiUser()); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(port), NiFiUserUtils.getNiFiUser()); - final PortStatusDTO status = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(port.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(port.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createPortEntity(dtoFactory.createPortDto(port), revision, permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public Set<PortEntity> getInputPorts(final String groupId) { - final Set<Port> inputPorts = inputPortDAO.getPorts(groupId); - return inputPorts.stream() - .map(port -> createInputPortEntity(port)) - .collect(Collectors.toSet()); - } - - @Override - public Set<PortEntity> getOutputPorts(final String groupId) { - final Set<Port> ports = outputPortDAO.getPorts(groupId); - return ports.stream() - .map(port -> createOutputPortEntity(port)) - .collect(Collectors.toSet()); - } - - private ProcessGroupEntity createProcessGroupEntity(final ProcessGroup group) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(group.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(group); - final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(group.getIdentifier())); - final List<BulletinEntity> bulletins = getProcessGroupBulletins(group); - return entityFactory.createProcessGroupEntity(dtoFactory.createProcessGroupDto(group), revision, permissions, status, bulletins); - } - - private List<BulletinEntity> getProcessGroupBulletins(final ProcessGroup group) { - final List<Bulletin> bulletins = new ArrayList<>(bulletinRepository.findBulletinsForGroupBySource(group.getIdentifier())); - - for (final ProcessGroup descendantGroup : group.findAllProcessGroups()) { - bulletins.addAll(bulletinRepository.findBulletinsForGroupBySource(descendantGroup.getIdentifier())); - } - - List<BulletinEntity> bulletinEntities = new ArrayList<>(); - for (final Bulletin bulletin : bulletins) { - bulletinEntities.add(entityFactory.createBulletinEntity(dtoFactory.createBulletinDto(bulletin), authorizeBulletin(bulletin))); - } - - return pruneAndSortBulletins(bulletinEntities, BulletinRepository.MAX_BULLETINS_PER_COMPONENT); - } - - private List<BulletinEntity> pruneAndSortBulletins(final List<BulletinEntity> bulletinEntities, final int maxBulletins) { - // sort the bulletins - Collections.sort(bulletinEntities, new Comparator<BulletinEntity>() { - @Override - public int compare(BulletinEntity o1, BulletinEntity o2) { - if (o1 == null && o2 == null) { - return 0; - } - if (o1 == null) { - return 1; - } - if (o2 == null) { - return -1; - } - - return -Long.compare(o1.getId(), o2.getId()); - } - }); - - // prune the response to only include the max number of bulletins - if (bulletinEntities.size() > maxBulletins) { - return bulletinEntities.subList(0, maxBulletins); - } else { - return bulletinEntities; - } - } - - @Override - public Set<ProcessGroupEntity> getProcessGroups(final String parentGroupId) { - final Set<ProcessGroup> groups = processGroupDAO.getProcessGroups(parentGroupId); - return groups.stream() - .map(group -> createProcessGroupEntity(group)) - .collect(Collectors.toSet()); - } - - private RemoteProcessGroupEntity createRemoteGroupEntity(final RemoteProcessGroup rpg, final NiFiUser user) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(rpg.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(rpg, user); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(rpg), user); - final RemoteProcessGroupStatusDTO status = dtoFactory.createRemoteProcessGroupStatusDto(rpg, controllerFacade.getRemoteProcessGroupStatus(rpg.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(rpg.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createRemoteProcessGroupEntity(dtoFactory.createRemoteProcessGroupDto(rpg), revision, permissions, operatePermissions, status, bulletinEntities); - } - - @Override - public Set<RemoteProcessGroupEntity> getRemoteProcessGroups(final String groupId) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final Set<RemoteProcessGroup> rpgs = remoteProcessGroupDAO.getRemoteProcessGroups(groupId); - return rpgs.stream() - .map(rpg -> createRemoteGroupEntity(rpg, user)) - .collect(Collectors.toSet()); - } - - @Override - public PortEntity getInputPort(final String inputPortId) { - final Port port = inputPortDAO.getPort(inputPortId); - return createInputPortEntity(port); - } - - @Override - public PortStatusEntity getInputPortStatus(final String inputPortId) { - final Port inputPort = inputPortDAO.getPort(inputPortId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(inputPort); - final PortStatusDTO dto = dtoFactory.createPortStatusDto(controllerFacade.getInputPortStatus(inputPortId)); - return entityFactory.createPortStatusEntity(dto, permissions); - } - - @Override - public PortEntity getOutputPort(final String outputPortId) { - final Port port = outputPortDAO.getPort(outputPortId); - return createOutputPortEntity(port); - } - - @Override - public PortStatusEntity getOutputPortStatus(final String outputPortId) { - final Port outputPort = outputPortDAO.getPort(outputPortId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(outputPort); - final PortStatusDTO dto = dtoFactory.createPortStatusDto(controllerFacade.getOutputPortStatus(outputPortId)); - return entityFactory.createPortStatusEntity(dto, permissions); - } - - @Override - public RemoteProcessGroupEntity getRemoteProcessGroup(final String remoteProcessGroupId) { - final RemoteProcessGroup rpg = remoteProcessGroupDAO.getRemoteProcessGroup(remoteProcessGroupId); - return createRemoteGroupEntity(rpg, NiFiUserUtils.getNiFiUser()); - } - - @Override - public RemoteProcessGroupStatusEntity getRemoteProcessGroupStatus(final String id) { - final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(id); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); - final RemoteProcessGroupStatusDTO dto = dtoFactory.createRemoteProcessGroupStatusDto(remoteProcessGroup, controllerFacade.getRemoteProcessGroupStatus(id)); - return entityFactory.createRemoteProcessGroupStatusEntity(dto, permissions); - } - - @Override - public StatusHistoryEntity getRemoteProcessGroupStatusHistory(final String id) { - final RemoteProcessGroup remoteProcessGroup = remoteProcessGroupDAO.getRemoteProcessGroup(id); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(remoteProcessGroup); - final StatusHistoryDTO dto = controllerFacade.getRemoteProcessGroupStatusHistory(id); - return entityFactory.createStatusHistoryEntity(dto, permissions); - } - - @Override - public CurrentUserEntity getCurrentUser() { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final CurrentUserEntity entity = new CurrentUserEntity(); - entity.setIdentity(user.getIdentity()); - entity.setAnonymous(user.isAnonymous()); - entity.setProvenancePermissions(dtoFactory.createPermissionsDto(authorizableLookup.getProvenance())); - entity.setCountersPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getCounters())); - entity.setTenantsPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getTenant())); - entity.setControllerPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getController())); - entity.setPoliciesPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getPolicies())); - entity.setSystemPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getSystem())); - entity.setCanVersionFlows(CollectionUtils.isNotEmpty(flowRegistryClient.getRegistryIdentifiers())); - - entity.setRestrictedComponentsPermissions(dtoFactory.createPermissionsDto(authorizableLookup.getRestrictedComponents())); - - final Set<ComponentRestrictionPermissionDTO> componentRestrictionPermissions = new HashSet<>(); - Arrays.stream(RequiredPermission.values()).forEach(requiredPermission -> { - final PermissionsDTO restrictionPermissions = dtoFactory.createPermissionsDto(authorizableLookup.getRestrictedComponents(requiredPermission)); - - final RequiredPermissionDTO requiredPermissionDto = new RequiredPermissionDTO(); - requiredPermissionDto.setId(requiredPermission.getPermissionIdentifier()); - requiredPermissionDto.setLabel(requiredPermission.getPermissionLabel()); - - final ComponentRestrictionPermissionDTO componentRestrictionPermissionDto = new ComponentRestrictionPermissionDTO(); - componentRestrictionPermissionDto.setRequiredPermission(requiredPermissionDto); - componentRestrictionPermissionDto.setPermissions(restrictionPermissions); - - componentRestrictionPermissions.add(componentRestrictionPermissionDto); - }); - entity.setComponentRestrictionPermissions(componentRestrictionPermissions); - - return entity; - } - - @Override - public ProcessGroupFlowEntity getProcessGroupFlow(final String groupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - - // Get the Process Group Status but we only need a status depth of one because for any child process group, - // we ignore the status of each individual components. I.e., if Process Group A has child Group B, and child Group B - // has a Processor, we don't care about the individual stats of that Processor because the ProcessGroupFlowEntity - // doesn't include that anyway. So we can avoid including the information in the status that is returned. - final ProcessGroupStatus groupStatus = controllerFacade.getProcessGroupStatus(groupId, 1); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - return entityFactory.createProcessGroupFlowEntity(dtoFactory.createProcessGroupFlowDto(processGroup, groupStatus, revisionManager, this::getProcessGroupBulletins), permissions); - } - - @Override - public ProcessGroupEntity getProcessGroup(final String groupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - return createProcessGroupEntity(processGroup); - } - - private ControllerServiceEntity createControllerServiceEntity(final ControllerServiceNode serviceNode, final Set<String> serviceIds) { - final ControllerServiceDTO dto = dtoFactory.createControllerServiceDto(serviceNode); - - final ControllerServiceReference ref = serviceNode.getReferences(); - final ControllerServiceReferencingComponentsEntity referencingComponentsEntity = createControllerServiceReferencingComponentsEntity(ref, serviceIds); - dto.setReferencingComponents(referencingComponentsEntity.getControllerServiceReferencingComponents()); - - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(serviceNode.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(serviceNode, NiFiUserUtils.getNiFiUser()); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(serviceNode), NiFiUserUtils.getNiFiUser()); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(serviceNode.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createControllerServiceEntity(dto, revision, permissions, operatePermissions, bulletinEntities); - } - - @Override - public VariableRegistryEntity getVariableRegistry(final String groupId, final boolean includeAncestorGroups) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - if (processGroup == null) { - throw new ResourceNotFoundException("Could not find group with ID " + groupId); - } - - return createVariableRegistryEntity(processGroup, includeAncestorGroups); - } - - private VariableRegistryEntity createVariableRegistryEntity(final ProcessGroup processGroup, final boolean includeAncestorGroups) { - final VariableRegistryDTO registryDto = dtoFactory.createVariableRegistryDto(processGroup, revisionManager); - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(processGroup.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - - if (includeAncestorGroups) { - ProcessGroup parent = processGroup.getParent(); - while (parent != null) { - final PermissionsDTO parentPerms = dtoFactory.createPermissionsDto(parent); - if (Boolean.TRUE.equals(parentPerms.getCanRead())) { - final VariableRegistryDTO parentRegistryDto = dtoFactory.createVariableRegistryDto(parent, revisionManager); - final Set<VariableEntity> parentVariables = parentRegistryDto.getVariables(); - registryDto.getVariables().addAll(parentVariables); - } - - parent = parent.getParent(); - } - } - - return entityFactory.createVariableRegistryEntity(registryDto, revision, permissions); - } - - @Override - public VariableRegistryEntity populateAffectedComponents(final VariableRegistryDTO variableRegistryDto) { - final String groupId = variableRegistryDto.getProcessGroupId(); - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - if (processGroup == null) { - throw new ResourceNotFoundException("Could not find group with ID " + groupId); - } - - final VariableRegistryDTO registryDto = dtoFactory.populateAffectedComponents(variableRegistryDto, processGroup, revisionManager); - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(processGroup.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - return entityFactory.createVariableRegistryEntity(registryDto, revision, permissions); - } - - @Override - public Set<ControllerServiceEntity> getControllerServices(final String groupId, final boolean includeAncestorGroups, final boolean includeDescendantGroups) { - final Set<ControllerServiceNode> serviceNodes = controllerServiceDAO.getControllerServices(groupId, includeAncestorGroups, includeDescendantGroups); - final Set<String> serviceIds = serviceNodes.stream().map(service -> service.getIdentifier()).collect(Collectors.toSet()); - - return serviceNodes.stream() - .map(serviceNode -> createControllerServiceEntity(serviceNode, serviceIds)) - .collect(Collectors.toSet()); - } - - @Override - public ControllerServiceEntity getControllerService(final String controllerServiceId) { - final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(controllerServiceId); - return createControllerServiceEntity(controllerService, Sets.newHashSet(controllerServiceId)); - } - - @Override - public PropertyDescriptorDTO getControllerServicePropertyDescriptor(final String id, final String property) { - final ControllerServiceNode controllerService = controllerServiceDAO.getControllerService(id); - PropertyDescriptor descriptor = controllerService.getControllerServiceImplementation().getPropertyDescriptor(property); - - // return an invalid descriptor if the controller service doesn't support this property - if (descriptor == null) { - descriptor = new PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build(); - } - - final String groupId = controllerService.getProcessGroup() == null ? null : controllerService.getProcessGroup().getIdentifier(); - return dtoFactory.createPropertyDescriptorDto(descriptor, groupId); - } - - @Override - public ControllerServiceReferencingComponentsEntity getControllerServiceReferencingComponents(final String controllerServiceId) { - final ControllerServiceNode service = controllerServiceDAO.getControllerService(controllerServiceId); - final ControllerServiceReference ref = service.getReferences(); - return createControllerServiceReferencingComponentsEntity(ref, Sets.newHashSet(controllerServiceId)); - } - - private ReportingTaskEntity createReportingTaskEntity(final ReportingTaskNode reportingTask) { - final RevisionDTO revision = dtoFactory.createRevisionDTO(revisionManager.getRevision(reportingTask.getIdentifier())); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(reportingTask); - final PermissionsDTO operatePermissions = dtoFactory.createPermissionsDto(new OperationAuthorizable(reportingTask)); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(reportingTask.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createReportingTaskEntity(dtoFactory.createReportingTaskDto(reportingTask), revision, permissions, operatePermissions, bulletinEntities); - } - - @Override - public Set<ReportingTaskEntity> getReportingTasks() { - final Set<ReportingTaskNode> reportingTasks = reportingTaskDAO.getReportingTasks(); - return reportingTasks.stream() - .map(reportingTask -> createReportingTaskEntity(reportingTask)) - .collect(Collectors.toSet()); - } - - @Override - public ReportingTaskEntity getReportingTask(final String reportingTaskId) { - final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(reportingTaskId); - return createReportingTaskEntity(reportingTask); - } - - @Override - public PropertyDescriptorDTO getReportingTaskPropertyDescriptor(final String id, final String property) { - final ReportingTaskNode reportingTask = reportingTaskDAO.getReportingTask(id); - PropertyDescriptor descriptor = reportingTask.getReportingTask().getPropertyDescriptor(property); - - // return an invalid descriptor if the reporting task doesn't support this property - if (descriptor == null) { - descriptor = new PropertyDescriptor.Builder().name(property).addValidator(Validator.INVALID).dynamic(true).build(); - } - - return dtoFactory.createPropertyDescriptorDto(descriptor, null); - } - - @Override - public StatusHistoryEntity getProcessGroupStatusHistory(final String groupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - final StatusHistoryDTO dto = controllerFacade.getProcessGroupStatusHistory(groupId); - return entityFactory.createStatusHistoryEntity(dto, permissions); - } - - @Override - public VersionControlComponentMappingEntity registerFlowWithFlowRegistry(final String groupId, final StartVersionControlRequestEntity requestEntity) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - - final VersionControlInformation currentVci = processGroup.getVersionControlInformation(); - final int expectedVersion = currentVci == null ? 1 : currentVci.getVersion() + 1; - - // Create a VersionedProcessGroup snapshot of the flow as it is currently. - final InstantiatedVersionedProcessGroup versionedProcessGroup = createFlowSnapshot(groupId); - - final VersionedFlowDTO versionedFlowDto = requestEntity.getVersionedFlow(); - final String flowId = versionedFlowDto.getFlowId() == null ? UUID.randomUUID().toString() : versionedFlowDto.getFlowId(); - - final VersionedFlow versionedFlow = new VersionedFlow(); - versionedFlow.setBucketIdentifier(versionedFlowDto.getBucketId()); - versionedFlow.setCreatedTimestamp(System.currentTimeMillis()); - versionedFlow.setDescription(versionedFlowDto.getDescription()); - versionedFlow.setModifiedTimestamp(versionedFlow.getCreatedTimestamp()); - versionedFlow.setName(versionedFlowDto.getFlowName()); - versionedFlow.setIdentifier(flowId); - - // Add the Versioned Flow and first snapshot to the Flow Registry - final String registryId = requestEntity.getVersionedFlow().getRegistryId(); - final VersionedFlowSnapshot registeredSnapshot; - final VersionedFlow registeredFlow; - - String action = "create the flow"; - try { - // first, create the flow in the registry, if necessary - if (versionedFlowDto.getFlowId() == null) { - registeredFlow = registerVersionedFlow(registryId, versionedFlow); - } else { - registeredFlow = getVersionedFlow(registryId, versionedFlowDto.getBucketId(), versionedFlowDto.getFlowId()); - } - - action = "add the local flow to the Flow Registry as the first Snapshot"; - - // add first snapshot to the flow in the registry - registeredSnapshot = registerVersionedFlowSnapshot(registryId, registeredFlow, versionedProcessGroup, versionedFlowDto.getComments(), expectedVersion); - } catch (final NiFiRegistryException e) { - throw new IllegalArgumentException(e.getLocalizedMessage()); - } catch (final IOException ioe) { - throw new IllegalStateException("Failed to communicate with Flow Registry when attempting to " + action); - } - - final Bucket bucket = registeredSnapshot.getBucket(); - final VersionedFlow flow = registeredSnapshot.getFlow(); - - // Update the Process Group with the new VersionControlInformation. (Send this to all nodes). - final VersionControlInformationDTO vci = new VersionControlInformationDTO(); - vci.setBucketId(bucket.getIdentifier()); - vci.setBucketName(bucket.getName()); - vci.setFlowId(flow.getIdentifier()); - vci.setFlowName(flow.getName()); - vci.setFlowDescription(flow.getDescription()); - vci.setGroupId(groupId); - vci.setRegistryId(registryId); - vci.setRegistryName(getFlowRegistryName(registryId)); - vci.setVersion(registeredSnapshot.getSnapshotMetadata().getVersion()); - vci.setState(VersionedFlowState.UP_TO_DATE.name()); - - final Map<String, String> mapping = dtoFactory.createVersionControlComponentMappingDto(versionedProcessGroup); - - final Revision groupRevision = revisionManager.getRevision(groupId); - final RevisionDTO groupRevisionDto = dtoFactory.createRevisionDTO(groupRevision); - - final VersionControlComponentMappingEntity entity = new VersionControlComponentMappingEntity(); - entity.setVersionControlInformation(vci); - entity.setProcessGroupRevision(groupRevisionDto); - entity.setVersionControlComponentMapping(mapping); - return entity; - } - - @Override - public VersionedFlow deleteVersionedFlow(final String registryId, final String bucketId, final String flowId) { - final FlowRegistry registry = flowRegistryClient.getFlowRegistry(registryId); - if (registry == null) { - throw new IllegalArgumentException("No Flow Registry exists with ID " + registryId); - } - - try { - return registry.deleteVersionedFlow(bucketId, flowId, NiFiUserUtils.getNiFiUser()); - } catch (final IOException | NiFiRegistryException e) { - throw new NiFiCoreException("Failed to remove flow from Flow Registry due to " + e.getMessage(), e); - } - } - - @Override - public VersionControlInformationEntity getVersionControlInformation(final String groupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - final VersionControlInformation versionControlInfo = processGroup.getVersionControlInformation(); - if (versionControlInfo == null) { - return null; - } - - final VersionControlInformationDTO versionControlDto = dtoFactory.createVersionControlInformationDto(processGroup); - final RevisionDTO groupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(groupId)); - return entityFactory.createVersionControlInformationEntity(versionControlDto, groupRevision); - } - - private InstantiatedVersionedProcessGroup createFlowSnapshot(final String processGroupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(processGroupId); - final NiFiRegistryFlowMapper mapper = new NiFiRegistryFlowMapper(controllerFacade.getExtensionManager()); - final InstantiatedVersionedProcessGroup versionedGroup = mapper.mapProcessGroup(processGroup, controllerFacade.getControllerServiceProvider(), flowRegistryClient, false); - return versionedGroup; - } - - @Override - public FlowComparisonEntity getLocalModifications(final String processGroupId) { - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(processGroupId); - final VersionControlInformation versionControlInfo = processGroup.getVersionControlInformation(); - if (versionControlInfo == null) { - throw new IllegalStateException("Process Group with ID " + processGroupId + " is not under Version Control"); - } - - final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(versionControlInfo.getRegistryIdentifier()); - if (flowRegistry == null) { - throw new IllegalStateException("Process Group with ID " + processGroupId + " is tracking to a flow in Flow Registry with ID " + versionControlInfo.getRegistryIdentifier() - + " but cannot find a Flow Registry with that identifier"); - } - - final VersionedFlowSnapshot versionedFlowSnapshot; - try { - versionedFlowSnapshot = flowRegistry.getFlowContents(versionControlInfo.getBucketIdentifier(), - versionControlInfo.getFlowIdentifier(), versionControlInfo.getVersion(), true, NiFiUserUtils.getNiFiUser()); - } catch (final IOException | NiFiRegistryException e) { - throw new NiFiCoreException("Failed to retrieve flow with Flow Registry in order to calculate local differences due to " + e.getMessage(), e); - } - - final NiFiRegistryFlowMapper mapper = new NiFiRegistryFlowMapper(controllerFacade.getExtensionManager()); - final VersionedProcessGroup localGroup = mapper.mapProcessGroup(processGroup, controllerFacade.getControllerServiceProvider(), flowRegistryClient, true); - final VersionedProcessGroup registryGroup = versionedFlowSnapshot.getFlowContents(); - - final ComparableDataFlow localFlow = new StandardComparableDataFlow("Local Flow", localGroup); - final ComparableDataFlow registryFlow = new StandardComparableDataFlow("Versioned Flow", registryGroup); - - final Set<String> ancestorServiceIds = getAncestorGroupServiceIds(processGroup); - final FlowComparator flowComparator = new StandardFlowComparator(registryFlow, localFlow, ancestorServiceIds, new ConciseEvolvingDifferenceDescriptor()); - final FlowComparison flowComparison = flowComparator.compare(); - - final Set<ComponentDifferenceDTO> differenceDtos = dtoFactory.createComponentDifferenceDtos(flowComparison); - - final FlowComparisonEntity entity = new FlowComparisonEntity(); - entity.setComponentDifferences(differenceDtos); - return entity; - } - - private Set<String> getAncestorGroupServiceIds(final ProcessGroup group) { - final Set<String> ancestorServiceIds; - ProcessGroup parentGroup = group.getParent(); - - if (parentGroup == null) { - ancestorServiceIds = Collections.emptySet(); - } else { - ancestorServiceIds = parentGroup.getControllerServices(true).stream() - .map(cs -> { - // We want to map the Controller Service to its Versioned Component ID, if it has one. - // If it does not have one, we want to generate it in the same way that our Flow Mapper does - // because this allows us to find the Controller Service when doing a Flow Diff. - final Optional<String> versionedId = cs.getVersionedComponentId(); - if (versionedId.isPresent()) { - return versionedId.get(); - } - - return UUID.nameUUIDFromBytes(cs.getIdentifier().getBytes(StandardCharsets.UTF_8)).toString(); - }) - .collect(Collectors.toSet()); - } - - return ancestorServiceIds; - } - - @Override - public VersionedFlow registerVersionedFlow(final String registryId, final VersionedFlow flow) { - final FlowRegistry registry = flowRegistryClient.getFlowRegistry(registryId); - if (registry == null) { - throw new ResourceNotFoundException("No Flow Registry exists with ID " + registryId); - } - - try { - return registry.registerVersionedFlow(flow, NiFiUserUtils.getNiFiUser()); - } catch (final IOException | NiFiRegistryException e) { - throw new NiFiCoreException("Failed to register flow with Flow Registry due to " + e.getMessage(), e); - } - } - - private VersionedFlow getVersionedFlow(final String registryId, final String bucketId, final String flowId) throws IOException, NiFiRegistryException { - final FlowRegistry registry = flowRegistryClient.getFlowRegistry(registryId); - if (registry == null) { - throw new ResourceNotFoundException("No Flow Registry exists with ID " + registryId); - } - - return registry.getVersionedFlow(bucketId, flowId, NiFiUserUtils.getNiFiUser()); - } - - @Override - public VersionedFlowSnapshot registerVersionedFlowSnapshot(final String registryId, final VersionedFlow flow, - final VersionedProcessGroup snapshot, final String comments, final int expectedVersion) { - final FlowRegistry registry = flowRegistryClient.getFlowRegistry(registryId); - if (registry == null) { - throw new ResourceNotFoundException("No Flow Registry exists with ID " + registryId); - } - - try { - return registry.registerVersionedFlowSnapshot(flow, snapshot, comments, expectedVersion, NiFiUserUtils.getNiFiUser()); - } catch (final IOException | NiFiRegistryException e) { - throw new NiFiCoreException("Failed to register flow with Flow Registry due to " + e.getMessage(), e); - } - } - - @Override - public VersionControlInformationEntity setVersionControlInformation(final Revision revision, final String processGroupId, - final VersionControlInformationDTO versionControlInfo, final Map<String, String> versionedComponentMapping) { - - final ProcessGroup group = processGroupDAO.getProcessGroup(processGroupId); - - final RevisionUpdate<VersionControlInformationDTO> snapshot = updateComponent(revision, - group, - () -> processGroupDAO.updateVersionControlInformation(versionControlInfo, versionedComponentMapping), - processGroup -> dtoFactory.createVersionControlInformationDto(processGroup)); - - return entityFactory.createVersionControlInformationEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification())); - } - - @Override - public VersionControlInformationEntity deleteVersionControl(final Revision revision, final String processGroupId) { - final ProcessGroup group = processGroupDAO.getProcessGroup(processGroupId); - - final RevisionUpdate<VersionControlInformationDTO> snapshot = updateComponent(revision, - group, - () -> processGroupDAO.disconnectVersionControl(processGroupId), - processGroup -> dtoFactory.createVersionControlInformationDto(group)); - - return entityFactory.createVersionControlInformationEntity(snapshot.getComponent(), dtoFactory.createRevisionDTO(snapshot.getLastModification())); - } - - @Override - public void verifyCanUpdate(final String groupId, final VersionedFlowSnapshot proposedFlow, final boolean verifyConnectionRemoval, final boolean verifyNotDirty) { - final ProcessGroup group = processGroupDAO.getProcessGroup(groupId); - group.verifyCanUpdate(proposedFlow, verifyConnectionRemoval, verifyNotDirty); - } - - @Override - public void verifyCanSaveToFlowRegistry(final String groupId, final String registryId, final String bucketId, final String flowId) { - final ProcessGroup group = processGroupDAO.getProcessGroup(groupId); - group.verifyCanSaveToFlowRegistry(registryId, bucketId, flowId); - } - - @Override - public void verifyCanRevertLocalModifications(final String groupId, final VersionedFlowSnapshot versionedFlowSnapshot) { - final ProcessGroup group = processGroupDAO.getProcessGroup(groupId); - group.verifyCanRevertLocalModifications(); - - // verify that the process group can be updated to the given snapshot. We do not verify that connections can - // be removed, because the flow may still be running, and it only matters that the connections can be removed once the components - // have been stopped. - group.verifyCanUpdate(versionedFlowSnapshot, false, false); - } - - @Override - public Set<AffectedComponentEntity> getComponentsAffectedByVersionChange(final String processGroupId, final VersionedFlowSnapshot updatedSnapshot) { - final ProcessGroup group = processGroupDAO.getProcessGroup(processGroupId); - - final NiFiRegistryFlowMapper mapper = new NiFiRegistryFlowMapper(controllerFacade.getExtensionManager()); - final VersionedProcessGroup localContents = mapper.mapProcessGroup(group, controllerFacade.getControllerServiceProvider(), flowRegistryClient, true); - - final ComparableDataFlow localFlow = new StandardComparableDataFlow("Local Flow", localContents); - final ComparableDataFlow proposedFlow = new StandardComparableDataFlow("Versioned Flow", updatedSnapshot.getFlowContents()); - - final Set<String> ancestorGroupServiceIds = getAncestorGroupServiceIds(group); - final FlowComparator flowComparator = new StandardFlowComparator(localFlow, proposedFlow, ancestorGroupServiceIds, new StaticDifferenceDescriptor()); - final FlowComparison comparison = flowComparator.compare(); - - final Set<AffectedComponentEntity> affectedComponents = comparison.getDifferences().stream() - .filter(difference -> difference.getDifferenceType() != DifferenceType.COMPONENT_ADDED) // components that are added are not components that will be affected in the local flow. - .filter(difference -> difference.getDifferenceType() != DifferenceType.BUNDLE_CHANGED) - .filter(FlowDifferenceFilters.FILTER_ADDED_REMOVED_REMOTE_PORTS) - .filter(FlowDifferenceFilters.FILTER_IGNORABLE_VERSIONED_FLOW_COORDINATE_CHANGES) - .map(difference -> { - final VersionedComponent localComponent = difference.getComponentA(); - - final String state; - switch (localComponent.getComponentType()) { - case CONTROLLER_SERVICE: - final String serviceId = ((InstantiatedVersionedControllerService) localComponent).getInstanceId(); - state = controllerServiceDAO.getControllerService(serviceId).getState().name(); - break; - case PROCESSOR: - final String processorId = ((InstantiatedVersionedProcessor) localComponent).getInstanceId(); - state = processorDAO.getProcessor(processorId).getPhysicalScheduledState().name(); - break; - case REMOTE_INPUT_PORT: - final InstantiatedVersionedRemoteGroupPort inputPort = (InstantiatedVersionedRemoteGroupPort) localComponent; - state = remoteProcessGroupDAO.getRemoteProcessGroup(inputPort.getInstanceGroupId()).getInputPort(inputPort.getInstanceId()).getScheduledState().name(); - break; - case REMOTE_OUTPUT_PORT: - final InstantiatedVersionedRemoteGroupPort outputPort = (InstantiatedVersionedRemoteGroupPort) localComponent; - state = remoteProcessGroupDAO.getRemoteProcessGroup(outputPort.getInstanceGroupId()).getOutputPort(outputPort.getInstanceId()).getScheduledState().name(); - break; - default: - state = null; - break; - } - - return createAffectedComponentEntity((InstantiatedVersionedComponent) localComponent, localComponent.getComponentType().name(), state); - }) - .collect(Collectors.toCollection(HashSet::new)); - - for (final FlowDifference difference : comparison.getDifferences()) { - // Ignore these as local differences for now because we can't do anything with it - if (difference.getDifferenceType() == DifferenceType.BUNDLE_CHANGED) { - continue; - } - - // Ignore differences for adding remote ports - if (FlowDifferenceFilters.isAddedOrRemovedRemotePort(difference)) { - continue; - } - - if (FlowDifferenceFilters.isIgnorableVersionedFlowCoordinateChange(difference)) { - continue; - } - - final VersionedComponent localComponent = difference.getComponentA(); - if (localComponent == null) { - continue; - } - - // If any Process Group is removed, consider all components below that Process Group as an affected component - if (difference.getDifferenceType() == DifferenceType.COMPONENT_REMOVED && localComponent.getComponentType() == org.apache.nifi.registry.flow.ComponentType.PROCESS_GROUP) { - final String localGroupId = ((InstantiatedVersionedProcessGroup) localComponent).getInstanceId(); - final ProcessGroup localGroup = processGroupDAO.getProcessGroup(localGroupId); - - localGroup.findAllProcessors().stream() - .map(comp -> createAffectedComponentEntity(comp)) - .forEach(affectedComponents::add); - localGroup.findAllFunnels().stream() - .map(comp -> createAffectedComponentEntity(comp)) - .forEach(affectedComponents::add); - localGroup.findAllInputPorts().stream() - .map(comp -> createAffectedComponentEntity(comp)) - .forEach(affectedComponents::add); - localGroup.findAllOutputPorts().stream() - .map(comp -> createAffectedComponentEntity(comp)) - .forEach(affectedComponents::add); - localGroup.findAllRemoteProcessGroups().stream() - .flatMap(rpg -> Stream.concat(rpg.getInputPorts().stream(), rpg.getOutputPorts().stream())) - .map(comp -> createAffectedComponentEntity(comp)) - .forEach(affectedComponents::add); - localGroup.findAllControllerServices().stream() - .map(comp -> createAffectedComponentEntity(comp)) - .forEach(affectedComponents::add); - } - - if (localComponent.getComponentType() == org.apache.nifi.registry.flow.ComponentType.CONTROLLER_SERVICE) { - final String serviceId = ((InstantiatedVersionedControllerService) localComponent).getInstanceId(); - final ControllerServiceNode serviceNode = controllerServiceDAO.getControllerService(serviceId); - - final List<ControllerServiceNode> referencingServices = serviceNode.getReferences().findRecursiveReferences(ControllerServiceNode.class); - for (final ControllerServiceNode referencingService : referencingServices) { - affectedComponents.add(createAffectedComponentEntity(referencingService)); - } - - final List<ProcessorNode> referencingProcessors = serviceNode.getReferences().findRecursiveReferences(ProcessorNode.class); - for (final ProcessorNode referencingProcessor : referencingProcessors) { - affectedComponents.add(createAffectedComponentEntity(referencingProcessor)); - } - } - } - - // Create a map of all connectable components by versioned component ID to the connectable component itself - final Map<String, List<Connectable>> connectablesByVersionId = new HashMap<>(); - mapToConnectableId(group.findAllFunnels(), connectablesByVersionId); - mapToConnectableId(group.findAllInputPorts(), connectablesByVersionId); - mapToConnectableId(group.findAllOutputPorts(), connectablesByVersionId); - mapToConnectableId(group.findAllProcessors(), connectablesByVersionId); - - final List<RemoteGroupPort> remotePorts = new ArrayList<>(); - for (final RemoteProcessGroup rpg : group.findAllRemoteProcessGroups()) { - remotePorts.addAll(rpg.getInputPorts()); - remotePorts.addAll(rpg.getOutputPorts()); - } - mapToConnectableId(remotePorts, connectablesByVersionId); - - // If any connection is added or modified, we need to stop both the source (if it exists in the flow currently) - // and the destination (if it exists in the flow currently). - for (final FlowDifference difference : comparison.getDifferences()) { - VersionedComponent component = difference.getComponentA(); - if (component == null) { - component = difference.getComponentB(); - } - - if (component.getComponentType() != org.apache.nifi.registry.flow.ComponentType.CONNECTION) { - continue; - } - - final VersionedConnection connection = (VersionedConnection) component; - - final String sourceVersionedId = connection.getSource().getId(); - final List<Connectable> sources = connectablesByVersionId.get(sourceVersionedId); - if (sources != null) { - for (final Connectable source : sources) { - affectedComponents.add(createAffectedComponentEntity(source)); - } - } - - final String destinationVersionId = connection.getDestination().getId(); - final List<Connectable> destinations = connectablesByVersionId.get(destinationVersionId); - if (destinations != null) { - for (final Connectable destination : destinations) { - affectedComponents.add(createAffectedComponentEntity(destination)); - } - } - } - - return affectedComponents; - } - - private void mapToConnectableId(final Collection<? extends Connectable> connectables, final Map<String, List<Connectable>> destination) { - for (final Connectable connectable : connectables) { - final Optional<String> versionedIdOption = connectable.getVersionedComponentId(); - - // Determine the Versioned ID by using the ID that is assigned, if one is. Otherwise, - // we will calculate the Versioned ID. This allows us to map connectables that currently are not under - // version control. We have to do this so that if we are changing flow versions and have a component that is running and it does not exist - // in the Versioned Flow, we still need to be able to create an AffectedComponentDTO for it. - final String versionedId; - if (versionedIdOption.isPresent()) { - versionedId = versionedIdOption.get(); - } else { - versionedId = UUID.nameUUIDFromBytes(connectable.getIdentifier().getBytes(StandardCharsets.UTF_8)).toString(); - } - - final List<Connectable> byVersionedId = destination.computeIfAbsent(versionedId, key -> new ArrayList<>()); - byVersionedId.add(connectable); - } - } - - - private AffectedComponentEntity createAffectedComponentEntity(final Connectable connectable) { - final AffectedComponentEntity entity = new AffectedComponentEntity(); - entity.setRevision(dtoFactory.createRevisionDTO(revisionManager.getRevision(connectable.getIdentifier()))); - entity.setId(connectable.getIdentifier()); - - final Authorizable authorizable = getAuthorizable(connectable); - final PermissionsDTO permissionsDto = dtoFactory.createPermissionsDto(authorizable); - entity.setPermissions(permissionsDto); - - final AffectedComponentDTO dto = new AffectedComponentDTO(); - dto.setId(connectable.getIdentifier()); - dto.setReferenceType(connectable.getConnectableType().name()); - dto.setState(connectable.getScheduledState().name()); - - final String groupId = connectable instanceof RemoteGroupPort ? ((RemoteGroupPort) connectable).getRemoteProcessGroup().getIdentifier() : connectable.getProcessGroupIdentifier(); - dto.setProcessGroupId(groupId); - - entity.setComponent(dto); - return entity; - } - - private AffectedComponentEntity createAffectedComponentEntity(final ControllerServiceNode serviceNode) { - final AffectedComponentEntity entity = new AffectedComponentEntity(); - entity.setRevision(dtoFactory.createRevisionDTO(revisionManager.getRevision(serviceNode.getIdentifier()))); - entity.setId(serviceNode.getIdentifier()); - - final Authorizable authorizable = authorizableLookup.getControllerService(serviceNode.getIdentifier()).getAuthorizable(); - final PermissionsDTO permissionsDto = dtoFactory.createPermissionsDto(authorizable); - entity.setPermissions(permissionsDto); - - final AffectedComponentDTO dto = new AffectedComponentDTO(); - dto.setId(serviceNode.getIdentifier()); - dto.setReferenceType(AffectedComponentDTO.COMPONENT_TYPE_CONTROLLER_SERVICE); - dto.setProcessGroupId(serviceNode.getProcessGroupIdentifier()); - dto.setState(serviceNode.getState().name()); - - entity.setComponent(dto); - return entity; - } - - private AffectedComponentEntity createAffectedComponentEntity(final InstantiatedVersionedComponent instance, final String componentTypeName, final String componentState) { - final AffectedComponentEntity entity = new AffectedComponentEntity(); - entity.setRevision(dtoFactory.createRevisionDTO(revisionManager.getRevision(instance.getInstanceId()))); - entity.setId(instance.getInstanceId()); - - final Authorizable authorizable = getAuthorizable(componentTypeName, instance); - final PermissionsDTO permissionsDto = dtoFactory.createPermissionsDto(authorizable); - entity.setPermissions(permissionsDto); - - final AffectedComponentDTO dto = new AffectedComponentDTO(); - dto.setId(instance.getInstanceId()); - dto.setReferenceType(componentTypeName); - dto.setProcessGroupId(instance.getInstanceGroupId()); - dto.setState(componentState); - - entity.setComponent(dto); - return entity; - } - - - private Authorizable getAuthorizable(final Connectable connectable) { - switch (connectable.getConnectableType()) { - case REMOTE_INPUT_PORT: - case REMOTE_OUTPUT_PORT: - final String rpgId = ((RemoteGroupPort) connectable).getRemoteProcessGroup().getIdentifier(); - return authorizableLookup.getRemoteProcessGroup(rpgId); - default: - return authorizableLookup.getLocalConnectable(connectable.getIdentifier()); - } - } - - private Authorizable getAuthorizable(final String componentTypeName, final InstantiatedVersionedComponent versionedComponent) { - final String componentId = versionedComponent.getInstanceId(); - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.CONTROLLER_SERVICE.name())) { - return authorizableLookup.getControllerService(componentId).getAuthorizable(); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.CONNECTION.name())) { - return authorizableLookup.getConnection(componentId).getAuthorizable(); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.FUNNEL.name())) { - return authorizableLookup.getFunnel(componentId); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.INPUT_PORT.name())) { - return authorizableLookup.getInputPort(componentId); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.OUTPUT_PORT.name())) { - return authorizableLookup.getOutputPort(componentId); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.LABEL.name())) { - return authorizableLookup.getLabel(componentId); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.PROCESS_GROUP.name())) { - return authorizableLookup.getProcessGroup(componentId).getAuthorizable(); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.PROCESSOR.name())) { - return authorizableLookup.getProcessor(componentId).getAuthorizable(); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.REMOTE_INPUT_PORT.name())) { - return authorizableLookup.getRemoteProcessGroup(versionedComponent.getInstanceGroupId()); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.REMOTE_OUTPUT_PORT.name())) { - return authorizableLookup.getRemoteProcessGroup(versionedComponent.getInstanceGroupId()); - } - - if (componentTypeName.equals(org.apache.nifi.registry.flow.ComponentType.REMOTE_PROCESS_GROUP.name())) { - return authorizableLookup.getRemoteProcessGroup(componentId); - } - - return null; - } - - @Override - public VersionedFlowSnapshot getVersionedFlowSnapshot(final VersionControlInformationDTO versionControlInfo, final boolean fetchRemoteFlows) { - final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(versionControlInfo.getRegistryId()); - if (flowRegistry == null) { - throw new ResourceNotFoundException("Could not find any Flow Registry registered with identifier " + versionControlInfo.getRegistryId()); - } - - final VersionedFlowSnapshot snapshot; - try { - snapshot = flowRegistry.getFlowContents(versionControlInfo.getBucketId(), versionControlInfo.getFlowId(), versionControlInfo.getVersion(), fetchRemoteFlows, NiFiUserUtils.getNiFiUser()); - } catch (final NiFiRegistryException | IOException e) { - logger.error(e.getMessage(), e); - throw new IllegalArgumentException("The Flow Registry with ID " + versionControlInfo.getRegistryId() + " reports that no Flow exists with Bucket " - + versionControlInfo.getBucketId() + ", Flow " + versionControlInfo.getFlowId() + ", Version " + versionControlInfo.getVersion()); - } - - return snapshot; - } - - @Override - public String getFlowRegistryName(final String flowRegistryId) { - final FlowRegistry flowRegistry = flowRegistryClient.getFlowRegistry(flowRegistryId); - return flowRegistry == null ? flowRegistryId : flowRegistry.getName(); - } - - private List<Revision> getComponentRevisions(final ProcessGroup processGroup, final boolean includeGroupRevision) { - final List<Revision> revisions = new ArrayList<>(); - if (includeGroupRevision) { - revisions.add(revisionManager.getRevision(processGroup.getIdentifier())); - } - - processGroup.findAllConnections().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllControllerServices().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllFunnels().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllInputPorts().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllOutputPorts().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllLabels().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllProcessGroups().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllProcessors().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllRemoteProcessGroups().stream() - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - processGroup.findAllRemoteProcessGroups().stream() - .flatMap(rpg -> Stream.concat(rpg.getInputPorts().stream(), rpg.getOutputPorts().stream())) - .map(component -> revisionManager.getRevision(component.getIdentifier())) - .forEach(revisions::add); - - return revisions; - } - - @Override - public ProcessGroupEntity updateProcessGroupContents(final Revision revision, final String groupId, final VersionControlInformationDTO versionControlInfo, - final VersionedFlowSnapshot proposedFlowSnapshot, final String componentIdSeed, final boolean verifyNotModified, final boolean updateSettings, final boolean updateDescendantVersionedFlows) { - - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - - final ProcessGroup processGroup = processGroupDAO.getProcessGroup(groupId); - final List<Revision> revisions = getComponentRevisions(processGroup, false); - revisions.add(revision); - - final RevisionClaim revisionClaim = new StandardRevisionClaim(revisions); - - final RevisionUpdate<ProcessGroupDTO> revisionUpdate = revisionManager.updateRevision(revisionClaim, user, new UpdateRevisionTask<ProcessGroupDTO>() { - @Override - public RevisionUpdate<ProcessGroupDTO> update() { - // update the Process Group - processGroupDAO.updateProcessGroupFlow(groupId, proposedFlowSnapshot, versionControlInfo, componentIdSeed, verifyNotModified, updateSettings, updateDescendantVersionedFlows); - - // update the revisions - final Set<Revision> updatedRevisions = revisions.stream() - .map(rev -> revisionManager.getRevision(rev.getComponentId()).incrementRevision(revision.getClientId())) - .collect(Collectors.toSet()); - - // save - controllerFacade.save(); - - // gather details for response - final ProcessGroupDTO dto = dtoFactory.createProcessGroupDto(processGroup); - - final Revision updatedRevision = revisionManager.getRevision(groupId).incrementRevision(revision.getClientId()); - final FlowModification lastModification = new FlowModification(updatedRevision, user.getIdentity()); - return new StandardRevisionUpdate<>(dto, lastModification, updatedRevisions); - } - }); - - final FlowModification lastModification = revisionUpdate.getLastModification(); - - final PermissionsDTO permissions = dtoFactory.createPermissionsDto(processGroup); - final RevisionDTO updatedRevision = dtoFactory.createRevisionDTO(lastModification); - final ProcessGroupStatusDTO status = dtoFactory.createConciseProcessGroupStatusDto(controllerFacade.getProcessGroupStatus(processGroup.getIdentifier())); - final List<BulletinDTO> bulletins = dtoFactory.createBulletinDtos(bulletinRepository.findBulletinsForSource(processGroup.getIdentifier())); - final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); - return entityFactory.createProcessGroupEntity(revisionUpdate.getComponent(), updatedRevision, permissions, status, bulletinEntities); - } - - private AuthorizationResult authorizeAction(final Action action) { - final String sourceId = action.getSourceId(); - final Component type = action.getSourceType(); - - Authorizable authorizable; - try { - switch (type) { - case Processor: - authorizable = authorizableLookup.getProcessor(sourceId).getAuthorizable(); - break; - case ReportingTask: - authorizable = authorizableLookup.getReportingTask(sourceId).getAuthorizable(); - break; - case ControllerService: - authorizable = authorizableLookup.getControllerService(sourceId).getAuthorizable(); - break; - case Controller: - authorizable = controllerFacade; - break; - case InputPort: - authorizable = authorizableLookup.getInputPort(sourceId); - break; - case OutputPort: - authorizable = authorizableLookup.getOutputPort(sourceId); - break; - case ProcessGroup: - authorizable = authorizableLookup.getProcessGroup(sourceId).getAuthorizable(); - break; - case RemoteProcessGroup: - authorizable = authorizableLookup.getRemoteProcessGroup(sourceId); - break; - case Funnel: - authorizable = authorizableLookup.getFunnel(sourceId); - break; - case Connection: - authorizable = authorizableLookup.getConnection(sourceId).getAuthorizable(); - break; - case AccessPolicy: - authorizable = authorizableLookup.getAccessPolicyById(sourceId); - break; - case User: - case UserGroup: - authorizable = authorizableLookup.getTenant(); - break; - default: - throw new WebApplicationException(Response.serverError().entity("An unexpected type of component is the source of this action.").build()); - } - } catch (final ResourceNotFoundException e) { - // if the underlying component is gone, use the controller to see if permissions should be allowed - authorizable = controllerFacade; - } - - // perform the authorization - return authorizable.checkAuthorization(authorizer, RequestAction.READ, NiFiUserUtils.getNiFiUser()); - } - - @Override - public HistoryDTO getActions(final HistoryQueryDTO historyQueryDto) { - // extract the query criteria - final HistoryQuery historyQuery = new HistoryQuery(); - historyQuery.setStartDate(historyQueryDto.getStartDate()); - historyQuery.setEndDate(historyQueryDto.getEndDate()); - historyQuery.setSourceId(historyQueryDto.getSourceId()); - historyQuery.setUserIdentity(historyQueryDto.getUserIdentity()); - historyQuery.setOffset(historyQueryDto.getOffset()); - historyQuery.setCount(historyQueryDto.getCount()); - historyQuery.setSortColumn(historyQueryDto.getSortColumn()); - historyQuery.setSortOrder(historyQueryDto.getSortOrder()); - - // perform the query - final History history = auditService.getActions(historyQuery); - - // only retain authorized actions - final HistoryDTO historyDto = dtoFactory.createHistoryDto(history); - if (history.getActions() != null) { - final List<ActionEntity> actionEntities = new ArrayList<>(); - for (final Action action : history.getActions()) { - final AuthorizationResult result = authorizeAction(action); - actionEntities.add(entityFactory.createActionEntity(dtoFactory.createActionDto(action), Result.Approved.equals(result.getResult()))); - } - historyDto.setActions(actionEntities); - } - - // create the response - return historyDto; - } - - @Override - public ActionEntity getAction(final Integer actionId) { - // get the action - final Action action = auditService.getAction(actionId); - - // ensure the action was found - if (action == null) { - throw new ResourceNotFoundException(String.format("Unable to find action with id '%s'.", actionId)); - } - - final AuthorizationResult result = authorizeAction(action); - final boolean authorized = Result.Approved.equals(result.getResult()); - if (!authorized) { - throw new AccessDeniedException(result.getExplanation()); - } - - // return the action - return entityFactory.createActionEntity(dtoFactory.createActionDto(action), authorized); - } - - @Override - public ComponentHistoryDTO getComponentHistory(final String componentId) { - final Map<String, PropertyHistoryDTO> propertyHistoryDtos = new LinkedHashMap<>(); - final Map<String, List<PreviousValue>> propertyHistory = auditService.getPreviousValues(componentId); - - for (final Map.Entry<String, List<PreviousValue>> entry : propertyHistory.entrySet()) { - final List<PreviousValueDTO> previousValueDtos = new ArrayList<>(); - - for (final PreviousValue previousValue : entry.getValue()) { - final PreviousValueDTO dto = new PreviousValueDTO(); - dto.setPreviousValue(previousValue.getPreviousValue()); - dto.setTimestamp(previousValue.getTimestamp()); - dto.setUserIdentity(previousValue.getUserIdentity()); - previousValueDtos.add(dto); - } - - if (!previousValueDtos.isEmpty()) { - final PropertyHistoryDTO propertyHistoryDto = new PropertyHistoryDTO(); - propertyHistoryDto.setPreviousValues(previousValueDtos); - propertyHistoryDtos.put(entry.getKey(), propertyHistoryDto); - } - } - - final ComponentHistoryDTO history = new ComponentHistoryDTO(); - history.setComponentId(componentId); - history.setPropertyHistory(propertyHistoryDtos); - - return history; - } - - @Override - public ProcessorDiagnosticsEntity getProcessorDiagnostics(final String id) { - final ProcessorNode processor = processorDAO.getProcessor(id); - final ProcessorStatus processorStatus = controllerFacade.getProcessorStatus(id); - - // Generate Processor Diagnostics - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - final ProcessorDiagnosticsDTO dto = controllerFacade.getProcessorDiagnostics(processor, processorStatus, bulletinRepository, serviceId -> { - final ControllerServiceNode serviceNode = controllerServiceDAO.getControllerService(serviceId); - return createControllerServiceEntity(serviceNode, Collections.emptySet()); - }); - - // Filter anything out of diagnostics that the user is not authorized to see. - final List<JVMDiagnosticsSnapshotDTO> jvmDiagnosticsSnaphots = new ArrayList<>(); - final JVMDiagnosticsDTO jvmDiagnostics = dto.getJvmDiagnostics(); - jvmDiagnosticsSnaphots.add(jvmDiagnostics.getAggregateSnapshot()); - - // filter controller-related information - final boolean canReadController = authorizableLookup.getController().isAuthorized(authorizer, RequestAction.READ, user); - if (!canReadController) { - for (final JVMDiagnosticsSnapshotDTO snapshot : jvmDiagnosticsSnaphots) { - snapshot.setControllerDiagnostics(null); - } - } - - // filter system diagnostics information - final boolean canReadSystem = authorizableLookup.getSystem().isAuthorized(authorizer, RequestAction.READ, user); - if (!canReadSystem) { - for (final JVMDiagnosticsSnapshotDTO snapshot : jvmDiagnosticsSnaphots) { - snapshot.setSystemDiagnosticsDto(null); - } - } - - final boolean canReadFlow = authorizableLookup.getFlow().isAuthorized(authorizer, RequestAction.READ, user); - if (!canReadFlow) { - for (final JVMDiagnosticsSnapshotDTO snapshot : jvmDiagnosticsSnaphots) { - snapshot.setFlowDiagnosticsDto(null); - } - } - - // filter connections - final Predicate<ConnectionDiagnosticsDTO> connectionAuthorized = connectionDiagnostics -> { - final String connectionId = connectionDiagnostics.getConnection().getId(); - return authorizableLookup.getConnection(connectionId).getAuthorizable().isAuthorized(authorizer, RequestAction.READ, user); - }; - - // Filter incoming connections by what user is authorized to READ - final Set<ConnectionDiagnosticsDTO> incoming = dto.getIncomingConnections(); - final Set<ConnectionDiagnosticsDTO> filteredIncoming = incoming.stream() - .filter(connectionAuthorized) - .collect(Collectors.toSet()); - - dto.setIncomingConnections(filteredIncoming); - - // Filter outgoing connections by what user is authorized to READ - final Set<ConnectionDiagnosticsDTO> outgoing = dto.getOutgoingConnections(); - final Set<ConnectionDiagnosticsDTO> filteredOutgoing = outgoing.stream() - .filter(connectionAuthorized) - .collect(Collectors.toSet()); - dto.setOutgoingConnections(filteredOutgoing); - - // Filter out any controller services that are referenced by the Processor - final Set<ControllerServiceDiagnosticsDTO> referencedServices = dto.getReferencedControllerServices(); - final Set<ControllerServiceDiagnosticsDTO> filteredReferencedServices = referencedServices.stream() - .filter(csDiagnostics -> { - final String csId = csDiagnostics.getControllerService().getId(); - return authorizableLookup.getControllerService(csId).getAuthorizable().isAuthorized(authorizer, RequestAction.READ, user); - }) - .map(csDiagnostics -> { - // Filter out any referencing components because those are generally not relevant from this context. - final ControllerServiceDTO serviceDto = csDiagnostics.getControllerService().getComponent(); - if (serviceDto != null) { - serviceDto.setReferencingComponents(null); - } - return csDiagnostics; - }) - .collect(Collectors.toSet()); - dto.setReferencedControllerServices(filteredReferencedServices); - - final Revision revision = revisionManager.getRevision(id); - final RevisionDTO revisionDto = dtoFactory.createRevisionDTO(revision); - final PermissionsDTO permissionsDto = dtoFactory.createPermissionsDto(processor); - final List<BulletinEntity> bulletins = bulletinRepository.findBulletinsForSource(id).stream() - .map(bulletin -> dtoFactory.createBulletinDto(bulletin)) - .map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissionsDto.getCanRead())) - .collect(Collectors.toList()); - - final ProcessorStatusDTO processorStatusDto = dtoFactory.createProcessorStatusDto(controllerFacade.getProcessorStatus(processor.getIdentifier())); - return entityFactory.createProcessorDiagnosticsEntity(dto, revisionDto, permissionsDto, processorStatusDto, bulletins); - } - - @Override - public boolean isClustered() { - return controllerFacade.isClustered(); - } - - @Override - public String getNodeId() { - final NodeIdentifier nodeId = controllerFacade.getNodeId(); - if (nodeId != null) { - return nodeId.getId(); - } else { - return null; - } - } - - @Override - public ClusterDTO getCluster() { - // create cluster summary dto - final ClusterDTO clusterDto = new ClusterDTO(); - - // set current time - clusterDto.setGenerated(new Date()); - - // create node dtos - final List<NodeDTO> nodeDtos = clusterCoordinator.getNodeIdentifiers().stream() - .map(nodeId -> getNode(nodeId)) - .collect(Collectors.toList()); - clusterDto.setNodes(nodeDtos); - - return clusterDto; - } - - @Override - public NodeDTO getNode(final String nodeId) { - final NodeIdentifier nodeIdentifier = clusterCoordinator.getNodeIdentifier(nodeId); - return getNode(nodeIdentifier); - } - - private NodeDTO getNode(final NodeIdentifier nodeId) { - final NodeConnectionStatus nodeStatus = clusterCoordinator.getConnectionStatus(nodeId); - final List<NodeEvent> events = clusterCoordinator.getNodeEvents(nodeId); - final Set<String> roles = getRoles(nodeId); - final NodeHeartbeat heartbeat = heartbeatMonitor.getLatestHeartbeat(nodeId); - return dtoFactory.createNodeDTO(nodeId, nodeStatus, heartbeat, events, roles); - } - - private Set<String> getRoles(final NodeIdentifier nodeId) { - final Set<String> roles = new HashSet<>(); - final String nodeAddress = nodeId.getSocketAddress() + ":" + nodeId.getSocketPort(); - - for (final String roleName : ClusterRoles.getAllRoles()) { - final String leader = leaderElectionManager.getLeader(roleName); - if (leader == null) { - continue; - } - - if (leader.equals(nodeAddress)) { - roles.add(roleName); - } - } - - return roles; - } - - @Override - public void deleteNode(final String nodeId) { - final NiFiUser user = NiFiUserUtils.getNiFiUser(); - if (user == null) { - throw new WebApplicationException(new Throwable("Unable to access details for current user.")); - } - - final String userDn = user.getIdentity(); - final NodeIdentifier nodeIdentifier = clusterCoordinator.getNodeIdentifier(nodeId); - if (nodeIdentifier == null) { - throw new UnknownNodeException("Cannot remove Node with ID " + nodeId + " because it is not part of the cluster"); - } - - final NodeConnectionStatus nodeConnectionStatus = clusterCoordinator.getConnectionStatus(nodeIdentifier); - if (!nodeConnectionStatus.getState().equals(NodeConnectionState.OFFLOADED) && !nodeConnectionStatus.getState().equals(NodeConnectionState.DISCONNECTED)) { - throw new IllegalNodeDeletionException("Cannot remove Node with ID " + nodeId + - " because it is not disconnected or offloaded, current state = " + nodeConnectionStatus.getState()); - } - - clusterCoordinator.removeNode(nodeIdentifier, userDn); - heartbeatMonitor.removeHeartbeat(nodeIdentifier); - } - - /* reusable function declarations for converting ids to tenant entities */ - private Function<String, TenantEntity> mapUserGroupIdToTenantEntity(final boolean enforceGroupExistence) { - return userGroupId -> { - final RevisionDTO userGroupRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userGroupId)); - - final Group group; - if (enforceGroupExistence || userGroupDAO.hasUserGroup(userGroupId)) { - group = userGroupDAO.getUserGroup(userGroupId); - } else { - group = new Group.Builder().identifier(userGroupId).name("Group ID - " + userGroupId + " (removed externally)").build(); - } - - return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(group), userGroupRevision, - dtoFactory.createPermissionsDto(authorizableLookup.getTenant())); - }; - } - - private Function<String, TenantEntity> mapUserIdToTenantEntity(final boolean enforceUserExistence) { - return userId -> { - final RevisionDTO userRevision = dtoFactory.createRevisionDTO(revisionManager.getRevision(userId)); - - final User user; - if (enforceUserExistence || userDAO.hasUser(userId)) { - user = userDAO.getUser(userId); - } else { - user = new User.Builder().identifier(userId).identity("User ID - " + userId + " (removed externally)").build(); - } - - return entityFactory.createTenantEntity(dtoFactory.createTenantDTO(user), userRevision, - dtoFactory.createPermissionsDto(authorizableLookup.getTenant())); - }; - } - - - /* setters */ - public void setProperties(final NiFiProperties properties) { - this.properties = properties; - } - - public void setControllerFacade(final ControllerFacade controllerFacade) { - this.controllerFacade = controllerFacade; - } - - public void setRemoteProcessGroupDAO(final RemoteProcessGroupDAO remoteProcessGroupDAO) { - this.remoteProcessGroupDAO = remoteProcessGroupDAO; - } - - public void setLabelDAO(final LabelDAO labelDAO) { - this.labelDAO = labelDAO; - } - - public void setFunnelDAO(final FunnelDAO funnelDAO) { - this.funnelDAO = funnelDAO; - } - - public void setSnippetDAO(final SnippetDAO snippetDAO) { - this.snippetDAO = snippetDAO; - } - - public void setProcessorDAO(final ProcessorDAO processorDAO) { - this.processorDAO = processorDAO; - } - - public void setConnectionDAO(final ConnectionDAO connectionDAO) { - this.connectionDAO = connectionDAO; - } - - public void setAuditService(final AuditService auditService) { - this.auditService = auditService; - } - - public void setRevisionManager(final RevisionManager revisionManager) { - this.revisionManager = revisionManager; - } - - public void setDtoFactory(final DtoFactory dtoFactory) { - this.dtoFactory = dtoFactory; - } - - public void setEntityFactory(final EntityFactory entityFactory) { - this.entityFactory = entityFactory; - } - - public void setInputPortDAO(final PortDAO inputPortDAO) { - this.inputPortDAO = inputPortDAO; - } - - public void setOutputPortDAO(final PortDAO outputPortDAO) { - this.outputPortDAO = outputPortDAO; - } - - public void setProcessGroupDAO(final ProcessGroupDAO processGroupDAO) { - this.processGroupDAO = processGroupDAO; - } - - public void setControllerServiceDAO(final ControllerServiceDAO controllerServiceDAO) { - this.controllerServiceDAO = controllerServiceDAO; - } - - public void setReportingTaskDAO(final ReportingTaskDAO reportingTaskDAO) { - this.reportingTaskDAO = reportingTaskDAO; - } - - public void setTemplateDAO(final TemplateDAO templateDAO) { - this.templateDAO = templateDAO; - } - - public void setSnippetUtils(final SnippetUtils snippetUtils) { - this.snippetUtils = snippetUtils; - } - - public void setAuthorizableLookup(final AuthorizableLookup authorizableLookup) { - this.authorizableLookup = authorizableLookup; - } - - public void setAuthorizer(final Authorizer authorizer) { - this.authorizer = authorizer; - } - - public void setUserDAO(final UserDAO userDAO) { - this.userDAO = userDAO; - } - - public void setUserGroupDAO(final UserGroupDAO userGroupDAO) { - this.userGroupDAO = userGroupDAO; - } - - public void setAccessPolicyDAO(final AccessPolicyDAO accessPolicyDAO) { - this.accessPolicyDAO = accessPolicyDAO; - } - - public void setClusterCoordinator(final ClusterCoordinator coordinator) { - this.clusterCoordinator = coordinator; - } - - public void setHeartbeatMonitor(final HeartbeatMonitor heartbeatMonitor) { - this.heartbeatMonitor = heartbeatMonitor; - } - - public void setBulletinRepository(final BulletinRepository bulletinRepository) { - this.bulletinRepository = bulletinRepository; - } - - public void setLeaderElectionManager(final LeaderElectionManager leaderElectionManager) { - this.leaderElectionManager = leaderElectionManager; - } - - public void setRegistryDAO(RegistryDAO registryDao) { - this.registryDAO = registryDao; - } - - public void setFlowRegistryClient(FlowRegistryClient flowRegistryClient) { - this.flowRegistryClient = flowRegistryClient; - } -} diff --git a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java index 2943e10..ad45f30 100644 --- a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java +++ b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/DtoFactory.java @@ -282,8 +282,7 @@ public final class DtoFactory { public FlowConfigurationDTO createFlowConfigurationDto(final String autoRefreshInterval, final Long defaultBackPressureObjectThreshold, - final String defaultBackPressureDataSizeThreshold, - final String dcaeDistributorApiHostname) { + final String defaultBackPressureDataSizeThreshold) { final FlowConfigurationDTO dto = new FlowConfigurationDTO(); // get the refresh interval @@ -293,9 +292,6 @@ public final class DtoFactory { dto.setSupportsConfigurableUsersAndGroups(AuthorizerCapabilityDetection.isConfigurableUserGroupProvider(authorizer)); dto.setSupportsConfigurableAuthorizer(AuthorizerCapabilityDetection.isConfigurableAccessPolicyProvider(authorizer)); - /* Renu - getting host IP */ - dto.setDcaeDistributorApiHostname(dcaeDistributorApiHostname); - final Date now = new Date(); dto.setTimeOffset(TimeZone.getDefault().getOffset(now.getTime())); dto.setCurrentTime(now); @@ -2042,8 +2038,8 @@ public final class DtoFactory { final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(connection.getIdentifier())); final PermissionsDTO accessPolicy = createPermissionsDto(connection); final ConnectionStatusDTO status = getComponentStatus( - () -> groupStatus.getConnectionStatus().stream().filter(connectionStatus -> connection.getIdentifier().equals(connectionStatus.getId())).findFirst().orElse(null), - connectionStatus -> createConnectionStatusDto(connectionStatus) + () -> groupStatus.getConnectionStatus().stream().filter(connectionStatus -> connection.getIdentifier().equals(connectionStatus.getId())).findFirst().orElse(null), + connectionStatus -> createConnectionStatusDto(connectionStatus) ); flow.getConnections().add(entityFactory.createConnectionEntity(dto, revision, accessPolicy, status)); } @@ -2067,8 +2063,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(inputPort); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(inputPort)); final PortStatusDTO status = getComponentStatus( - () -> groupStatus.getInputPortStatus().stream().filter(inputPortStatus -> inputPort.getIdentifier().equals(inputPortStatus.getId())).findFirst().orElse(null), - inputPortStatus -> createPortStatusDto(inputPortStatus) + () -> groupStatus.getInputPortStatus().stream().filter(inputPortStatus -> inputPort.getIdentifier().equals(inputPortStatus.getId())).findFirst().orElse(null), + inputPortStatus -> createPortStatusDto(inputPortStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(inputPort.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2084,8 +2080,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(outputPort); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(outputPort)); final PortStatusDTO status = getComponentStatus( - () -> groupStatus.getOutputPortStatus().stream().filter(outputPortStatus -> outputPort.getIdentifier().equals(outputPortStatus.getId())).findFirst().orElse(null), - outputPortStatus -> createPortStatusDto(outputPortStatus) + () -> groupStatus.getOutputPortStatus().stream().filter(outputPortStatus -> outputPort.getIdentifier().equals(outputPortStatus.getId())).findFirst().orElse(null), + outputPortStatus -> createPortStatusDto(outputPortStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(outputPort.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2110,8 +2106,8 @@ public final class DtoFactory { final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(processGroup.getIdentifier())); final PermissionsDTO permissions = createPermissionsDto(processGroup); final ProcessGroupStatusDTO status = getComponentStatus( - () -> groupStatus.getProcessGroupStatus().stream().filter(processGroupStatus -> processGroup.getIdentifier().equals(processGroupStatus.getId())).findFirst().orElse(null), - processGroupStatus -> createConciseProcessGroupStatusDto(processGroupStatus) + () -> groupStatus.getProcessGroupStatus().stream().filter(processGroupStatus -> processGroup.getIdentifier().equals(processGroupStatus.getId())).findFirst().orElse(null), + processGroupStatus -> createConciseProcessGroupStatusDto(processGroupStatus) ); final List<BulletinEntity> bulletins = getProcessGroupBulletins.apply(processGroup); flow.getProcessGroups().add(entityFactory.createProcessGroupEntity(dto, revision, permissions, status, bulletins)); @@ -2126,8 +2122,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(processor); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(processor)); final ProcessorStatusDTO status = getComponentStatus( - () -> groupStatus.getProcessorStatus().stream().filter(processorStatus -> processor.getIdentifier().equals(processorStatus.getId())).findFirst().orElse(null), - processorStatus -> createProcessorStatusDto(processorStatus) + () -> groupStatus.getProcessorStatus().stream().filter(processorStatus -> processor.getIdentifier().equals(processorStatus.getId())).findFirst().orElse(null), + processorStatus -> createProcessorStatusDto(processorStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(processor.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2143,8 +2139,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(remoteProcessGroup); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(remoteProcessGroup)); final RemoteProcessGroupStatusDTO status = getComponentStatus( - () -> groupStatus.getRemoteProcessGroupStatus().stream().filter(rpgStatus -> remoteProcessGroup.getIdentifier().equals(rpgStatus.getId())).findFirst().orElse(null), - remoteProcessGroupStatus -> createRemoteProcessGroupStatusDto(remoteProcessGroup, remoteProcessGroupStatus) + () -> groupStatus.getRemoteProcessGroupStatus().stream().filter(rpgStatus -> remoteProcessGroup.getIdentifier().equals(rpgStatus.getId())).findFirst().orElse(null), + remoteProcessGroupStatus -> createRemoteProcessGroupStatusDto(remoteProcessGroup, remoteProcessGroupStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(remoteProcessGroup.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2174,8 +2170,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(procNode); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(procNode)); final ProcessorStatusDTO status = getComponentStatus( - () -> groupStatus.getProcessorStatus().stream().filter(processorStatus -> procNode.getIdentifier().equals(processorStatus.getId())).findFirst().orElse(null), - processorStatus -> createProcessorStatusDto(processorStatus) + () -> groupStatus.getProcessorStatus().stream().filter(processorStatus -> procNode.getIdentifier().equals(processorStatus.getId())).findFirst().orElse(null), + processorStatus -> createProcessorStatusDto(processorStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(procNode.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2186,8 +2182,8 @@ public final class DtoFactory { final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(connNode.getIdentifier())); final PermissionsDTO permissions = createPermissionsDto(connNode); final ConnectionStatusDTO status = getComponentStatus( - () -> groupStatus.getConnectionStatus().stream().filter(connectionStatus -> connNode.getIdentifier().equals(connectionStatus.getId())).findFirst().orElse(null), - connectionStatus -> createConnectionStatusDto(connectionStatus) + () -> groupStatus.getConnectionStatus().stream().filter(connectionStatus -> connNode.getIdentifier().equals(connectionStatus.getId())).findFirst().orElse(null), + connectionStatus -> createConnectionStatusDto(connectionStatus) ); dto.getConnections().add(entityFactory.createConnectionEntity(createConnectionDto(connNode), revision, permissions, status)); } @@ -2208,8 +2204,8 @@ public final class DtoFactory { final RevisionDTO revision = createRevisionDTO(revisionManager.getRevision(childGroup.getIdentifier())); final PermissionsDTO permissions = createPermissionsDto(childGroup); final ProcessGroupStatusDTO status = getComponentStatus( - () -> groupStatus.getProcessGroupStatus().stream().filter(processGroupStatus -> childGroup.getIdentifier().equals(processGroupStatus.getId())).findFirst().orElse(null), - processGroupStatus -> createConciseProcessGroupStatusDto(processGroupStatus) + () -> groupStatus.getProcessGroupStatus().stream().filter(processGroupStatus -> childGroup.getIdentifier().equals(processGroupStatus.getId())).findFirst().orElse(null), + processGroupStatus -> createConciseProcessGroupStatusDto(processGroupStatus) ); final List<BulletinEntity> bulletins = getProcessGroupBulletins.apply(childGroup); dto.getProcessGroups().add(entityFactory.createProcessGroupEntity(createProcessGroupDto(childGroup), revision, permissions, status, bulletins)); @@ -2220,8 +2216,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(rpg); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(rpg)); final RemoteProcessGroupStatusDTO status = getComponentStatus( - () -> groupStatus.getRemoteProcessGroupStatus().stream().filter(remoteProcessGroupStatus -> rpg.getIdentifier().equals(remoteProcessGroupStatus.getId())).findFirst().orElse(null), - remoteProcessGroupStatus -> createRemoteProcessGroupStatusDto(rpg, remoteProcessGroupStatus) + () -> groupStatus.getRemoteProcessGroupStatus().stream().filter(remoteProcessGroupStatus -> rpg.getIdentifier().equals(remoteProcessGroupStatus.getId())).findFirst().orElse(null), + remoteProcessGroupStatus -> createRemoteProcessGroupStatusDto(rpg, remoteProcessGroupStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(rpg.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2233,8 +2229,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(inputPort); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(inputPort)); final PortStatusDTO status = getComponentStatus( - () -> groupStatus.getInputPortStatus().stream().filter(inputPortStatus -> inputPort.getIdentifier().equals(inputPortStatus.getId())).findFirst().orElse(null), - inputPortStatus -> createPortStatusDto(inputPortStatus) + () -> groupStatus.getInputPortStatus().stream().filter(inputPortStatus -> inputPort.getIdentifier().equals(inputPortStatus.getId())).findFirst().orElse(null), + inputPortStatus -> createPortStatusDto(inputPortStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(inputPort.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2246,8 +2242,8 @@ public final class DtoFactory { final PermissionsDTO permissions = createPermissionsDto(outputPort); final PermissionsDTO operatePermissions = createPermissionsDto(new OperationAuthorizable(outputPort)); final PortStatusDTO status = getComponentStatus( - () -> groupStatus.getOutputPortStatus().stream().filter(outputPortStatus -> outputPort.getIdentifier().equals(outputPortStatus.getId())).findFirst().orElse(null), - outputPortStatus -> createPortStatusDto(outputPortStatus) + () -> groupStatus.getOutputPortStatus().stream().filter(outputPortStatus -> outputPort.getIdentifier().equals(outputPortStatus.getId())).findFirst().orElse(null), + outputPortStatus -> createPortStatusDto(outputPortStatus) ); final List<BulletinDTO> bulletins = createBulletinDtos(bulletinRepository.findBulletinsForSource(outputPort.getIdentifier())); final List<BulletinEntity> bulletinEntities = bulletins.stream().map(bulletin -> entityFactory.createBulletinEntity(bulletin, permissions.getCanRead())).collect(Collectors.toList()); @@ -2290,7 +2286,7 @@ public final class DtoFactory { dto.setVersionControlInformation(createVersionControlInformationDto(group)); final Map<String, String> variables = group.getVariableRegistry().getVariableMap().entrySet().stream() - .collect(Collectors.toMap(entry -> entry.getKey().getName(), entry -> entry.getValue())); + .collect(Collectors.toMap(entry -> entry.getKey().getName(), entry -> entry.getValue())); dto.setVariables(variables); final ProcessGroup parentGroup = group.getParent(); @@ -2409,50 +2405,50 @@ public final class DtoFactory { mapping.put(group.getInstanceId(), group.getIdentifier()); group.getProcessors().stream() - .map(proc -> (InstantiatedVersionedProcessor) proc) - .forEach(proc -> mapping.put(proc.getInstanceId(), proc.getIdentifier())); + .map(proc -> (InstantiatedVersionedProcessor) proc) + .forEach(proc -> mapping.put(proc.getInstanceId(), proc.getIdentifier())); group.getFunnels().stream() - .map(funnel -> (InstantiatedVersionedFunnel) funnel) - .forEach(funnel -> mapping.put(funnel.getInstanceId(), funnel.getIdentifier())); + .map(funnel -> (InstantiatedVersionedFunnel) funnel) + .forEach(funnel -> mapping.put(funnel.getInstanceId(), funnel.getIdentifier())); group.getInputPorts().stream() - .map(port -> (InstantiatedVersionedPort) port) - .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); + .map(port -> (InstantiatedVersionedPort) port) + .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); group.getOutputPorts().stream() - .map(port -> (InstantiatedVersionedPort) port) - .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); + .map(port -> (InstantiatedVersionedPort) port) + .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); group.getControllerServices().stream() - .map(service -> (InstantiatedVersionedControllerService) service) - .forEach(service -> mapping.put(service.getInstanceId(), service.getIdentifier())); + .map(service -> (InstantiatedVersionedControllerService) service) + .forEach(service -> mapping.put(service.getInstanceId(), service.getIdentifier())); group.getLabels().stream() - .map(label -> (InstantiatedVersionedLabel) label) - .forEach(label -> mapping.put(label.getInstanceId(), label.getIdentifier())); + .map(label -> (InstantiatedVersionedLabel) label) + .forEach(label -> mapping.put(label.getInstanceId(), label.getIdentifier())); group.getConnections().stream() - .map(conn -> (InstantiatedVersionedConnection) conn) - .forEach(conn -> mapping.put(conn.getInstanceId(), conn.getIdentifier())); + .map(conn -> (InstantiatedVersionedConnection) conn) + .forEach(conn -> mapping.put(conn.getInstanceId(), conn.getIdentifier())); group.getRemoteProcessGroups().stream() - .map(rpg -> (InstantiatedVersionedRemoteProcessGroup) rpg) - .forEach(rpg -> { - mapping.put(rpg.getInstanceId(), rpg.getIdentifier()); - - if (rpg.getInputPorts() != null) { - rpg.getInputPorts().stream() - .map(port -> (InstantiatedVersionedRemoteGroupPort) port) - .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); - } + .map(rpg -> (InstantiatedVersionedRemoteProcessGroup) rpg) + .forEach(rpg -> { + mapping.put(rpg.getInstanceId(), rpg.getIdentifier()); + + if (rpg.getInputPorts() != null) { + rpg.getInputPorts().stream() + .map(port -> (InstantiatedVersionedRemoteGroupPort) port) + .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); + } - if (rpg.getOutputPorts() != null) { - rpg.getOutputPorts().stream() - .map(port -> (InstantiatedVersionedRemoteGroupPort) port) - .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); - } - }); + if (rpg.getOutputPorts() != null) { + rpg.getOutputPorts().stream() + .map(port -> (InstantiatedVersionedRemoteGroupPort) port) + .forEach(port -> mapping.put(port.getInstanceId(), port.getIdentifier())); + } + }); group.getProcessGroups().stream() - .map(child -> (InstantiatedVersionedProcessGroup) child) - .forEach(child -> { - final Map<String, String> childMapping = createVersionControlComponentMappingDto(child); - mapping.putAll(childMapping); - }); + .map(child -> (InstantiatedVersionedProcessGroup) child) + .forEach(child -> { + final Map<String, String> childMapping = createVersionControlComponentMappingDto(child); + mapping.putAll(childMapping); + }); return mapping; } @@ -2574,8 +2570,8 @@ public final class DtoFactory { final ComponentVariableRegistry variableRegistry = processGroup.getVariableRegistry(); final List<String> variableNames = variableRegistry.getVariableMap().keySet().stream() - .map(descriptor -> descriptor.getName()) - .collect(Collectors.toList()); + .map(descriptor -> descriptor.getName()) + .collect(Collectors.toList()); final Set<VariableEntity> variableEntities = new LinkedHashSet<>(); @@ -3278,31 +3274,31 @@ public final class DtoFactory { * @return ProcessorDiagnosticsDTO for the given Processor */ public ProcessorDiagnosticsDTO createProcessorDiagnosticsDto(final ProcessorNode procNode, final ProcessorStatus procStatus, final BulletinRepository bulletinRepo, - final FlowController flowController, final Function<String, ControllerServiceEntity> serviceEntityFactory) { + final FlowController flowController, final Function<String, ControllerServiceEntity> serviceEntityFactory) { final ProcessorDiagnosticsDTO procDiagnostics = new ProcessorDiagnosticsDTO(); procDiagnostics.setClassLoaderDiagnostics(createClassLoaderDiagnosticsDto(procNode)); procDiagnostics.setIncomingConnections(procNode.getIncomingConnections().stream() - .map(this::createConnectionDiagnosticsDto) - .collect(Collectors.toSet())); + .map(this::createConnectionDiagnosticsDto) + .collect(Collectors.toSet())); procDiagnostics.setOutgoingConnections(procNode.getConnections().stream() - .map(this::createConnectionDiagnosticsDto) - .collect(Collectors.toSet())); + .map(this::createConnectionDiagnosticsDto) + .collect(Collectors.toSet())); procDiagnostics.setJvmDiagnostics(createJvmDiagnosticsDto(flowController)); procDiagnostics.setProcessor(createProcessorDto(procNode)); procDiagnostics.setProcessorStatus(createProcessorStatusDto(procStatus)); procDiagnostics.setThreadDumps(createThreadDumpDtos(procNode)); final Set<ControllerServiceDiagnosticsDTO> referencedServiceDiagnostics = createReferencedServiceDiagnostics(procNode.getProperties(), - flowController.getControllerServiceProvider(), serviceEntityFactory); + flowController.getControllerServiceProvider(), serviceEntityFactory); procDiagnostics.setReferencedControllerServices(referencedServiceDiagnostics); return procDiagnostics; } private Set<ControllerServiceDiagnosticsDTO> createReferencedServiceDiagnostics(final Map<PropertyDescriptor, String> properties, final ControllerServiceProvider serviceProvider, - final Function<String, ControllerServiceEntity> serviceEntityFactory) { + final Function<String, ControllerServiceEntity> serviceEntityFactory) { final Set<ControllerServiceDiagnosticsDTO> referencedServiceDiagnostics = new HashSet<>(); for (final Map.Entry<PropertyDescriptor, String> entry : properties.entrySet()) { @@ -3339,7 +3335,7 @@ public final class DtoFactory { * @return ControllerServiceDiagnosticsDTO for the given Controller Service */ public ControllerServiceDiagnosticsDTO createControllerServiceDiagnosticsDto(final ControllerServiceNode serviceNode, final Function<String, ControllerServiceEntity> serviceEntityFactory, - final ControllerServiceProvider serviceProvider) { + final ControllerServiceProvider serviceProvider) { final ControllerServiceDiagnosticsDTO serviceDiagnostics = new ControllerServiceDiagnosticsDTO(); final ControllerServiceEntity serviceEntity = serviceEntityFactory.apply(serviceNode.getIdentifier()); @@ -3409,8 +3405,8 @@ public final class DtoFactory { final List<RemoteQueuePartitionDiagnostics> remoteDiagnostics = queueDiagnostics.getRemoteQueuePartitionDiagnostics(); if (remoteDiagnostics != null) { final List<RemoteQueuePartitionDTO> remoteDiagnosticsDtos = remoteDiagnostics.stream() - .map(this::createRemoteQueuePartitionDto) - .collect(Collectors.toList()); + .map(this::createRemoteQueuePartitionDto) + .collect(Collectors.toList()); dto.setRemoteQueuePartitions(remoteDiagnosticsDtos); } @@ -3490,10 +3486,10 @@ public final class DtoFactory { // flow-related information final Set<BundleDTO> bundlesLoaded = extensionManager.getAllBundles().stream() - .map(bundle -> bundle.getBundleDetails().getCoordinate()) - .sorted((a, b) -> a.getCoordinate().compareTo(b.getCoordinate())) - .map(this::createBundleDto) - .collect(Collectors.toCollection(LinkedHashSet::new)); + .map(bundle -> bundle.getBundleDetails().getCoordinate()) + .sorted((a, b) -> a.getCoordinate().compareTo(b.getCoordinate())) + .map(this::createBundleDto) + .collect(Collectors.toCollection(LinkedHashSet::new)); flowDiagnosticsDto.setActiveEventDrivenThreads(flowController.getActiveEventDrivenThreadCount()); flowDiagnosticsDto.setActiveTimerDrivenThreads(flowController.getActiveTimerDrivenThreadCount()); diff --git a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java b/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java deleted file mode 100644 index 2dd91ad..0000000 --- a/mod/designtool/designtool-web/src/main/java/org/apache/nifi/web/api/dto/FlowConfigurationDTO.java +++ /dev/null @@ -1,182 +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. - * - * Modifications to the original nifi code for the ONAP project are made - * available under the Apache License, Version 2.0 - */ -package org.apache.nifi.web.api.dto; - -import io.swagger.annotations.ApiModelProperty; -import org.apache.nifi.web.api.dto.util.TimeAdapter; - -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import java.util.Date; - -/** - * Details for the controller configuration. - */ -@XmlType(name = "flowConfiguration") -public class FlowConfigurationDTO { - - private Boolean supportsManagedAuthorizer; - private Boolean supportsConfigurableAuthorizer; - private Boolean supportsConfigurableUsersAndGroups; - private Long autoRefreshIntervalSeconds; - - private Date currentTime; - private Integer timeOffset; - - private Long defaultBackPressureObjectThreshold; - private String defaultBackPressureDataSizeThreshold; - - private String dcaeDistributorApiHostname; - - /** - * @author Renu - * @return getter and setter for dcae distributor api hostname. This value is read only - */ - @ApiModelProperty( - value = "Whether it picks up configurable host address.", - readOnly = true - ) - public String getDcaeDistributorApiHostname() { - return dcaeDistributorApiHostname; - } - - public void setDcaeDistributorApiHostname(String dcaeDistributorApiHostname) { - this.dcaeDistributorApiHostname = dcaeDistributorApiHostname; - } - - /** - * @return interval in seconds between the automatic NiFi refresh requests. This value is read only - */ - @ApiModelProperty( - value = "The interval in seconds between the automatic NiFi refresh requests.", - readOnly = true - ) - public Long getAutoRefreshIntervalSeconds() { - return autoRefreshIntervalSeconds; - } - - public void setAutoRefreshIntervalSeconds(Long autoRefreshIntervalSeconds) { - this.autoRefreshIntervalSeconds = autoRefreshIntervalSeconds; - } - - /** - * @return whether this NiFi supports a managed authorizer. Managed authorizers can visualize users, groups, - * and policies in the UI. This value is read only - */ - @ApiModelProperty( - value = "Whether this NiFi supports a managed authorizer. Managed authorizers can visualize users, groups, and policies in the UI.", - readOnly = true - ) - public Boolean getSupportsManagedAuthorizer() { - return supportsManagedAuthorizer; - } - - public void setSupportsManagedAuthorizer(Boolean supportsManagedAuthorizer) { - this.supportsManagedAuthorizer = supportsManagedAuthorizer; - } - - /** - * @return whether this NiFi supports configurable users and groups. This value is read only - */ - @ApiModelProperty( - value = "Whether this NiFi supports configurable users and groups.", - readOnly = true - ) - public Boolean getSupportsConfigurableUsersAndGroups() { - return supportsConfigurableUsersAndGroups; - } - - public void setSupportsConfigurableUsersAndGroups(Boolean supportsConfigurableUsersAndGroups) { - this.supportsConfigurableUsersAndGroups = supportsConfigurableUsersAndGroups; - } - - /** - * @return whether this NiFi supports a configurable authorizer. This value is read only - */ - @ApiModelProperty( - value = "Whether this NiFi supports a configurable authorizer.", - readOnly = true - ) - public Boolean getSupportsConfigurableAuthorizer() { - return supportsConfigurableAuthorizer; - } - - public void setSupportsConfigurableAuthorizer(Boolean supportsConfigurableAuthorizer) { - this.supportsConfigurableAuthorizer = supportsConfigurableAuthorizer; - } - - /** - * @return current time on the server - */ - @XmlJavaTypeAdapter(TimeAdapter.class) - @ApiModelProperty( - value = "The current time on the system.", - dataType = "string" - ) - public Date getCurrentTime() { - return currentTime; - } - - public void setCurrentTime(Date currentTime) { - this.currentTime = currentTime; - } - - /** - * @return time offset of the server - */ - @ApiModelProperty( - value = "The time offset of the system." - ) - public Integer getTimeOffset() { - return timeOffset; - } - - public void setTimeOffset(Integer timeOffset) { - this.timeOffset = timeOffset; - } - - /** - * @return the default back pressure object threshold - */ - @ApiModelProperty( - value = "The default back pressure object threshold." - ) - public Long getDefaultBackPressureObjectThreshold() { - return defaultBackPressureObjectThreshold; - } - - public void setDefaultBackPressureObjectThreshold(Long backPressureObjectThreshold) { - this.defaultBackPressureObjectThreshold = backPressureObjectThreshold; - } - - /** - * @return the default back pressure data size threshold - */ - @ApiModelProperty( - value = "The default back pressure data size threshold." - ) - public String getDefaultBackPressureDataSizeThreshold() { - return defaultBackPressureDataSizeThreshold; - } - - public void setDefaultBackPressureDataSizeThreshold(String backPressureDataSizeThreshold) { - this.defaultBackPressureDataSizeThreshold = backPressureDataSizeThreshold; - } -} diff --git a/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp b/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp index 3afbe66..e0a4a44 100644 --- a/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp +++ b/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/canvas-header.jsp @@ -50,34 +50,34 @@ nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.groupComponent);"> <span class="component-button-grip"></span> </button> - <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.remoteProcessGroup}}" - id="group-remote-component" - class="component-button icon icon-group-remote" - ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" - nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.remoteGroupComponent);"> - <span class="component-button-grip"></span> - </button> - <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.funnel}}" - id="funnel-component" - class="component-button icon icon-funnel" - ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" - nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.funnelComponent);"> - <span class="component-button-grip"></span> - </button> - <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.template}}" - id="template-component" - class="component-button icon icon-template" - ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" - nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.templateComponent);"> - <span class="component-button-grip"></span> - </button> - <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.label}}" - id="label-component" - class="component-button icon icon-label" - ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" - nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.labelComponent);"> - <span class="component-button-grip"></span> - </button> + <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.remoteProcessGroup}}" + id="group-remote-component" + class="component-button icon icon-group-remote" + ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" + nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.remoteGroupComponent);"> + <span class="component-button-grip"></span> + </button> + <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.funnel}}" + id="funnel-component" + class="component-button icon icon-funnel" + ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" + nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.funnelComponent);"> + <span class="component-button-grip"></span> + </button> + <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.template}}" + id="template-component" + class="component-button icon icon-template" + ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" + nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.templateComponent);"> + <span class="component-button-grip"></span> + </button> + <button title="{{appCtrl.serviceProvider.headerCtrl.toolboxCtrl.config.type.label}}" + id="label-component" + class="component-button icon icon-label" + ng-disabled="!appCtrl.nf.CanvasUtils.canWriteCurrentGroup();" + nf-draggable="appCtrl.serviceProvider.headerCtrl.toolboxCtrl.draggableComponentConfig(appCtrl.serviceProvider.headerCtrl.toolboxCtrl.labelComponent);"> + <span class="component-button-grip"></span> + </button> </div> <div layout="row" layout-align="space-between center"> <div layout-align="space-between end" layout="column"> @@ -128,6 +128,22 @@ <i class="icon icon-provenance"></i>Data Provenance </a> </md-menu-item> + <md-menu-item layout-align="space-around center"> + <md-menu class="onap-unpadded"> + <a id="import-link" ng-click="$mdMenu.open()"><i class="icon icon-import"></i>Import</a> + <md-menu-content id="import-menu-content"> + <md-menu-item layout-align="space-around center"> + <a id="adapter-acumos-link" ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.importModel.shell.launch();">Import Models ...</a> + </md-menu-item> + <md-menu-item layout-align="space-around center"> + <a id="import-component-link" ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.importComponent.shell.launch();">Import Component Spec. ...</a> + </md-menu-item> + <md-menu-item layout-align="space-around center"> + <a id="import-format-link" ng-click="appCtrl.serviceProvider.headerCtrl.globalMenuCtrl.importDataFormat.shell.launch();">Import Data Format ...</a> + </md-menu-item> + </md-menu-content> + </md-menu> + </md-menu-item> <md-menu-divider></md-menu-divider> <md-menu-item layout-align="space-around center"> <a id="flow-settings-link" diff --git a/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp b/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp index caf7278..30eb004 100644 --- a/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp +++ b/mod/designtool/designtool-web/src/main/webapp/WEB-INF/partials/canvas/navigation.jsp @@ -127,3 +127,53 @@ </div> </div> </div> +<div id="import-model" class="hidden medium-dialog import-group"> + <div id="import-model-header-text" class="import-header-text">Import Model</div> + <div class="import-container"> + <select id="model-type" onchange="setModelType()"> + <option value="-" selected="true">-- Choose Model Type --</option> + <option value="mtAcumos">Acumos</option> + </select> + <div id="mt-acumos" class="hidden"> + <hr/> + <label for="furl"><b>Acumos Federation URL</b></label> <input id="furl" type="text" name="furl" placeholder="https://server:9084" required/> + <button type="button" class="onap-action" onclick="lookupCatalogs()">Lookup</button> + </div> + <div id="c-acumos" class="hidden"> + <hr/> + <label for="cat-menu"><b>Select Catalog</b></label> <select id="cat-menu" onchange="chooseCatalog()"> + <option value="*">All Catalogs</option> + </select> + </div> + <div id="ac-sols" class="hidden"> + <hr/> + <label for="sol-menu"><b>Select Solution</b></label> <select id="sol-menu" onchange="chooseSolution()"> + <option value="*">All Solutions</option> + </select> + </div> + <div id="ac-revs" class="hidden"> + <hr/> + <label for="rev-menu"><b>Select Revision</b></label> <select id="rev-menu"> + <option value="*">All Revisions</option> + </select> + </div> + <hr/> + <button id="onboard" class="hidden onap-action" type="button" onclick="onBoard()">Onboard</button><br> + <b id="onboarding-in-progress" class="hidden">Onboarding - Please Wait ...</b> + </div> +</div> + +<div id="import-component" class="hidden medium-dialog import-group"> + <div id="import-component-header-text" class="import-header-text">Import Component Specification</div> + <div class="import-container"> + <label for="cspec"><b>Component Specification File</b></label> <input id="cspec" type="file" name="file" placeholder="Component-Spec.json" accept=".json,application/json" required> + <br><button id="uploadComponent" type="button" class="onap-action" onclick="onBoardComponent()">Upload</button> + </div> +</div> +<div id="import-data-format" class="hidden medium-dialog import-group"> + <div id="import-data-format-header-text" class="import-header-text">Import Data Format</div> + <div class="import-container"> + <label for="dfspec"><b>Data Format File</b></label> <input id="dfspec" type="file" name="file" placeholder="Data-Format.json" accept=".json,application/json" required> + <br><button id="uploadDataFormat" type="button" class="onap-action" onclick="onBoardDataFormat()">Upload</button> + </div> +</div> diff --git a/mod/designtool/designtool-web/src/main/webapp/css/navigation.css b/mod/designtool/designtool-web/src/main/webapp/css/navigation.css index 05adc45..0f2705f 100644 --- a/mod/designtool/designtool-web/src/main/webapp/css/navigation.css +++ b/mod/designtool/designtool-web/src/main/webapp/css/navigation.css @@ -336,3 +336,69 @@ span.breadcrumb-version-control-gray { white-space: nowrap; line-height: normal; } + +.icon-import:before { + content: '\e850'; +} + +div.import-group { + position: absolute; + top: 0px; + bottom: 0px; + left: 20px; + right: 20px; + overflow: auto; +} + +div.import-header-text { + height: 28px; + font-size: 18px; + font-weight: bold; + color: #728E9B; + margin-bottom: 30px; +} + +div.import-container { + position: absolute; + top: 58px; + bottom: 52px; + left: 20px; + right: 0px; + font-size: 15px; +} + +.onap-action { + width: 250px; +} + +.onap-unpadded { + margin: 0px; + padding: 0px; +} + +#import-menu-content { + font-size: 13px; + padding: 3px 0; + background-color: rgba(249, 250, 251, 0.97); + border: 1px solid #004849; + box-shadow: 0 3px 6px rgba(0, 0, 0, 0.3); + width: 215px; + max-height: inherit; +} + +#import-menu-content md-menu-item { + min-height: 28px; + height: 28px; +} + +#import-menu-content a { + height: 28px; + padding: 6px 16px; + cursor: pointer; + padding-left: 10px; + padding-right: 10px; +} + +#import-menu-content a:hover { + background-color:#C7D2D7; +} diff --git a/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.eot b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.eot Binary files differnew file mode 100644 index 0000000..0104560 --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.eot diff --git a/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.svg b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.svg new file mode 100644 index 0000000..9493a8c --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.svg @@ -0,0 +1,70 @@ +<?xml version="1.0" standalone="no"?> +<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> +<svg xmlns="http://www.w3.org/2000/svg"> +<metadata>Copyright (C) 2016 by original authors @ fontello.com</metadata> +<defs> +<font id="flowfont" horiz-adv-x="1000" > +<font-face font-family="flowfont" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="860" descent="-140" /> +<missing-glyph horiz-adv-x="1000" /> +<glyph glyph-name="funnel-add" unicode="" d="M948 796h-114a52 52 0 0 1-53-52v-147l-183-77a305 305 0 0 1-35 11l78 110h51a52 52 0 0 1 52 52v115a52 52 0 0 1-52 52h-114a52 52 0 0 1-52-52v-114a52 52 0 0 1 52-53h29l-74-108c-9 0-18-2-28-2s-19 4-28 3l-73 107h18a52 52 0 0 1 52 52v115a52 52 0 0 1-52 52h-114a52 52 0 0 1-51-52v-114a52 52 0 0 1 51-53h61l75-111a379 379 0 0 1-38-8l-187 75v147a52 52 0 0 1-53 52h-114a52 52 0 0 1-52-52v-114a52 52 0 0 1 52-51h156l159-68a39 39 0 0 1-28-29c0-28 74-51 166-51s167 22 167 50a40 40 0 0 1-29 31l159 67h146a52 52 0 0 1 52 51v114a52 52 0 0 1-52 52z m-365-128a31 31 0 0 0-32 31v104a31 31 0 0 0 32 31h105a31 31 0 0 0 31-31v-104a31 31 0 0 0-31-31h-105z m-270 0a31 31 0 0 0-32 31v104a31 31 0 0 0 32 31h104a31 31 0 0 0 31-31v-104a31 31 0 0 0-31-31h-104z m-121-33a31 31 0 0 0-31-32h-104a31 31 0 0 0-31 32v104a31 31 0 0 0 31 31h104a31 31 0 0 0 31-31v-104z m781 0a31 31 0 0 0-31-32h-103a31 31 0 0 0-31 32v104a31 31 0 0 0 31 31h104a31 31 0 0 0 31-31v-104z m-689-257a234 234 0 1 1 234-234 234 234 0 0 1-234 234z m140-268a9 9 0 0 0-9-9h-81a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-66a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-80a9 9 0 0 0-9 9v66a9 9 0 0 0 9 9h81a9 9 0 0 1 10 9v82a9 9 0 0 0 7 8h65a9 9 0 0 0 9-9v-81a9 9 0 0 1 9-9h81a9 9 0 0 0 9-9v-66z m153 252v-164a18 18 0 0 1 19-19h60c12 0 14-7 7-15l-115-122a281 281 0 0 1-164 366 514 514 0 0 1 121-14c20 0 194 2 202 80h12v-2a31 31 0 0 0 0-5c0-69-78-95-142-104z m51-301v-150a52 52 0 0 0-52-51h-138a52 52 0 0 0-43 22 281 281 0 0 1 43 23 31 31 0 0 1 18-6h104a31 31 0 0 1 31 31v96z" horiz-adv-x="1000" /> + +<glyph glyph-name="counter" unicode="" d="M878-7h-756c-67 0-122 54-122 121v492c0 67 55 121 122 121h756c68 0 122-54 122-121v-492c0-67-54-121-122-121z m-756 670c-32 0-58-26-58-57v-492c0-31 26-57 58-57h756c32 0 58 26 58 57v492c0 31-26 57-58 57h-756z m358-535h-314v62l148 158c20 22 35 42 45 58 10 17 15 33 15 47 0 21-5 37-15 48-11 12-25 18-45 18-20 0-36-7-48-21-12-15-18-33-18-56h-91c0 28 7 53 20 76 13 23 32 41 56 54 25 13 52 20 83 20 47 0 84-11 110-34s39-55 39-96c0-22-6-45-18-69-11-23-31-51-60-82l-104-110h197v-73z m344 457c8-17 12-36 12-57 0-21-7-41-19-58-13-18-30-31-51-41 26-9 45-23 58-41 13-19 19-40 19-66 0-40-15-73-44-97s-69-37-118-37c-46 0-83 12-112 36-29 24-44 56-44 96h91c0-18 7-32 20-42 12-11 28-17 47-17 22 0 39 6 51 17 12 12 18 27 18 46 0 45-25 68-75 68h-48v71h48c23 0 40 6 51 17 12 12 17 27 17 46 0 19-5 33-16 43-11 11-26 16-45 16l140 0z m-141 0c-18 0-32-5-44-15-11-9-17-21-17-37h-91c0 19 4 36 12 52h140z m0-457l25 39h92v-39h-117z" horiz-adv-x="1000" /> + +<glyph glyph-name="enable-false" unicode="" d="M912-113l-297 296-144-308c-5-9-14-15-25-15-3 0-6 1-9 1-13 4-21 17-18 30l96 392-71 70-150-37c-3-1-5-1-7-1-7 0-14 2-19 7-7 5-10 14-8 23l38 154-251 250 41 42 865-862-41-42z m-117 683c5 9 3 20-4 27-5 5-12 9-20 9-3 0-5-1-7-1l-238-59 102 278c2 4 3 7 3 11 0 14-12 25-27 25h-197c-12 0-23-8-26-19l-42-172 343-342 113 243z" horiz-adv-x="1000" /> + +<glyph glyph-name="funnel" unicode="" d="M782 744v-147l-183-77c-11 2-21 9-35 11l77 111h51c28 0 52 23 52 52v114c0 29-24 52-52 52h-114c-29 0-52-23-52-52v-114c0-29 23-52 52-52h29l-74-108c-9 0-18-2-28-2-9 0-19 3-28 3l-73 107h18c29 0 52 23 52 52v114c0 29-23 52-52 52h-113c-29 0-53-23-53-52v-114c0-29 24-52 53-52h60l75-111c-13-2-27-6-38-9l-188 75v147c0 29-23 52-52 52h-114c-29 0-52-23-52-52v-114c0-29 23-52 52-52h157l158-68c-18-8-28-19-28-29 0-27 74-50 166-50 92 0 166 22 166 49 0 10-10 22-28 30l159 68h146c29 0 52 23 52 52v114c0 29-23 52-52 52h-114c-29 0-52-23-52-52z m-231-45v104c0 17 14 31 32 31h104c17 0 31-14 31-31v-104c0-17-14-31-31-31h-104c-18 0-32 14-32 31z m-269 0v104c0 17 14 31 31 31h105c17 0 31-14 31-31v-104c0-17-14-31-31-31h-105c-17 0-31 14-31 31z m-121-95h-104c-17 0-31 14-31 31v104c0 17 14 31 31 31h104c17 0 31-14 31-31v-104c0-17-14-31-31-31z m782 0h-104c-17 0-31 14-31 31v104c0 17 14 31 31 31h104c17 0 31-14 31-31v-104c0-17-14-31-31-31z m-452-592c8-9 20-9 28 0l144 153c8 8 5 16-6 16h-61c-11 0-19 7-19 18v164c64 9 142 35 142 104 0 2-1 3-1 5l-1 2-10 0c-8-78-182-80-202-80-20 0-194 2-202 80l-10 0 0-2c0-2 0-3 0-5 0-69 79-95 143-104v-164c0-11-11-18-22-18h-60c-11 0-14-8-7-16l144-153z m137 50v-150c0-29-23-52-52-52h-139c-29 0-52 23-52 52v150l38-36v-96c0-18 14-32 31-32h105c17 0 31 14 31 32v96l38 36z" horiz-adv-x="1000" /> + +<glyph glyph-name="group" unicode="" d="M82 852c-45 0-82-36-82-82v-110h192v192h-110z m53-134h-77v36c0 22 18 41 41 41h36v-77z m783 134h-110v-192h192v110c0 46-37 82-82 82z m24-134h-77v77h36c23 0 41-19 41-41v-36z m-942-658v-110c0-46 37-82 82-82h110v192h-192z m135-135h-36c-23 0-41 19-41 41v36h77v-77z m673 135v-192h110c45 0 82 36 82 82v110h-192z m134-94c0-22-18-41-41-41h-36v77h77v-36z m-883 126v536h75v-536h-75z m807 0v536h75v-536h-75z m-634 627v75h536v-75h-536z m0-793v75h536v-75h-536z m454 530h-92v71c0 46-37 82-82 82h-179c-45 0-82-36-82-82v-178c0-46 37-82 82-82h92v-72c0-45 37-82 82-82h179c45 0 82 37 82 82v179c0 45-37 82-82 82z m-261-82v-67h-84c-27 0-49 22-49 49v164c0 27 22 49 49 49h163c27 0 49-22 49-49v-64h-46c-45 0-82-37-82-82z m302-172c0-27-22-49-49-49h-164c-27 0-49 22-49 49v164c0 27 22 49 49 49h164c27 0 49-22 49-49v-163z" horiz-adv-x="1000" /> + +<glyph glyph-name="group-remote" unicode="" d="M82 852c-45 0-82-36-82-82v-110h192v192h-110z m53-134h-77v36c0 22 18 41 41 41h36v-77z m783 134h-110v-192h192v110c0 46-37 82-82 82z m24-134h-77v77h36c23 0 41-19 41-41v-36z m-942-658v-110c0-46 37-82 82-82h110v192h-192z m135-135h-36c-23 0-41 19-41 41v36h77v-77z m673 135v-192h110c45 0 82 36 82 82v110h-192z m134-94c0-22-18-41-41-41h-36v77h77v-36z m-211 433c-5 78-69 138-147 138-42 0-82-18-110-49-16 17-38 26-61 26-48 0-87-39-87-86l0-2c-4 1-7 1-11 1-67 0-122-55-122-122 0-67 55-122 122-122h384c60 0 110 50 110 111 0 49-32 91-78 105z m-32-158h-384c-86 0-75 143 11 127l68-13-10 68c-4 28 34 43 51 22l39-50 40 50c49 62 157 27 159-54l1-38 37-9c57-13 46-103-12-103z m-640-149v536h75v-536h-75z m882 0h-75v536h75v-536z m-709 627v75h536v-75h-536z m0-793v75h536v-75h-536z" horiz-adv-x="1000" /> + +<glyph glyph-name="label" unicode="" d="M670 167c2 4 5 7 8 11l322 321v-43l-303-303c-3-3-7-6-11-8l-36-18 20 40z m-225-271l315 93c7 2 13 6 18 11l222 222v83l-207-207c-3-3-5-5-6-8l-40-65c-5-8-12-14-21-17l-167-61-5 10c-15 33-41 59-74 75l-10 5 60 166c3 9 10 17 18 21l62 38c3 2 6 4 8 6l382 382v83l-475-473c-5-5-8-11-10-18l-96-320c-5-16 10-31 26-26z m160 712c40 0 70 18 70 41s-30 40-70 40h-535c-40 0-70-17-70-40s30-41 70-41h535z m-59-136c40 0 70 18 70 41s-30 41-70 41h-476c-40 0-70-18-70-41s30-41 70-41h476z m-228-135c40 0 70 17 70 40 0 24-30 41-70 41h-248c-40 0-70-17-70-40 0-24 30-41 70-41h248z m178 407c40 0 70 17 70 40s-30 41-70 41h-426c-40 0-70-17-70-41s30-40 70-40h426z" horiz-adv-x="1000" /> + +<glyph glyph-name="processor" unicode="" d="M101 842l-50-50-39-88 39 39v-120l-39-88 39 39v-120l-39-87 39 39v-121l-39-87 39 39v-121l-39-87 39 39v-121l-39-87 63 63h121l-15-63 63 63h121l-15-63 63 63h120l-14-63 63 63h120l-14-63 63 63h120l-15-63 114 113c11 12 18 28 18 44v760c0 46-37 83-83 83h-760c-16 0-32-7-44-18z m798-850h-738c-23 0-41 18-41 41v738c0 23 18 42 41 42h738c23 0 42-19 42-42v-738c0-23-19-41-42-41z m-119 564c-2 9-4 19-11 27-57 75-144 119-239 119-65 0-128-21-180-60-127-96-156-278-66-409 1-3 2-6 4-8 57-76 144-120 239-120 66 0 128 21 180 61 68 51 111 123 122 202 9 66-8 133-49 188z m-54-322c-39-30-87-45-137-45-80 0-157 40-208 106-11 15-28 24-46 24-13 0-25-4-36-12-12-10-20-23-23-39 0-4 1-7 1-11-60 110-39 246 55 317 39 29 86 45 136 45 80 0 158-40 208-107 11-15 28-23 47-23 13 0 25 4 35 11 16 13 23 32 22 51 63-110 42-245-54-317z" horiz-adv-x="1000" /> + +<glyph glyph-name="provenance" unicode="" d="M827 170v-258c0-29-23-52-51-52h-724c-29 0-52 23-52 52v724c0 28 23 51 52 51h258v-465c0-29 23-52 52-52h465z m-193 293c-17 0-31 14-31 31v271h-150c-17 0-31-13-31-30v-422c0-17 14-30 31-30h422c17 0 30 13 30 30v150h-271z m366 145v193c0 33-26 59-59 59h-193c-32 0-58-26-58-59v-193c0-32 26-58 58-58h193c33 0 59 26 59 58z m-241 183h172v-172h-172v172z" horiz-adv-x="1000" /> + +<glyph glyph-name="template" unicode="" d="M995 423v-157a31 31 0 0 0-31-31h-231l-195-156h153a31 31 0 0 0 32-31v-157a31 31 0 0 0-32-31h-434a31 31 0 0 0-31 31v157a31 31 0 0 0 31 31h231l196 156h-153a31 31 0 0 0-31 31v157a31 31 0 0 0 31 31h122l-373 187h-244a31 31 0 0 0-31 32v156a31 31 0 0 0 31 31h433a31 31 0 0 0 31-31v-156a31 31 0 0 0-31-32h-122l373-187h244a31 31 0 0 0 31-31z" horiz-adv-x="1000" /> + +<glyph glyph-name="transmit-false" unicode="" d="M44 845l-44-44 163-163c-52-74-83-165-83-262 0-255 206-461 460-461 98 0 189 32 264 85l125-125 44 44-929 926z m287-374l60-60c-2-11-4-23-4-36 0-84 68-153 153-153 12 0 24 2 36 5l60-60c-29-14-62-22-96-22-127 0-230 103-230 230 0 35 8 67 21 96z m209-479c-212 0-383 172-383 383 0 77 23 148 62 208l55-55c-26-45-41-97-41-153 0-169 138-306 307-306 56 0 108 15 153 41l56-55c-60-40-132-63-209-63z m0 767c212 0 383-172 383-383 0-75-21-145-58-204l55-55v0c50 73 80 163 80 258 0 255-206 460-460 460-96 0-186-29-260-80l56-55c59 37 129 59 204 59z m269-531c24 44 38 94 38 148 0 169-138 306-307 306-54 0-104-14-148-38l57-57c28 12 59 18 91 18 127 0 230-102 230-230 0-32-7-62-18-90l57-57z m-299 298l180-180c2 10 3 19 3 30 0 84-68 153-153 153-10 0-20-1-30-3z" horiz-adv-x="1000" /> + +<glyph glyph-name="zoom-actual" unicode="" d="M42-140c-23 0-42 19-42 42v916c0 23 19 42 42 42h83c23 0 42-19 42-42v-916c0-23-19-42-42-42h-83z m416 233c-22 0-41 19-41 42v108c0 23 19 42 41 42h84c23 0 41-19 41-42v-108c0-23-18-42-41-42h-84z m0 343c-22 0-41 18-41 41v108c0 23 19 42 41 42h84c23 0 41-19 41-42v-108c0-23-18-41-41-41h-84z m417-576c-23 0-42 19-42 42v916c0 23 19 42 42 42h83c23 0 42-19 42-42v-916c0-23-19-42-42-42h-83z" horiz-adv-x="1000" /> + +<glyph glyph-name="zoom-fit" unicode="" d="M637 789c-12 12-15 30-9 45 7 16 22 26 39 26h291c23 0 42-19 42-42v-291c0-17-10-32-25-39-6-2-11-3-17-3-11 0-21 5-29 12l-292 292z m-566-292c-8-7-18-12-29-12-6 0-11 1-16 3-16 7-26 22-26 39v291c0 23 19 42 42 42h291c17 0 32-10 39-26 6-15 3-33-9-45l-292-292z m292-566c12-12 15-30 9-45-7-16-22-26-39-26h-291c-23 0-42 19-42 42v291c0 17 10 32 26 39 15 6 33 3 45-9l292-292z m566 292c12 12 30 15 46 9 15-7 25-22 25-39v-291c0-23-19-42-42-42h-291c-17 0-32 10-39 26-6 15-3 33 9 45l292 292z" horiz-adv-x="1000" /> + +<glyph glyph-name="label-add" unicode="" d="M670 167a42 42 0 0 0 8 11l322 321v-43l-303-303a42 42 0 0 0-11-8l-36-17z m-65 441c40 0 70 18 70 41s-31 40-70 40h-535c-39 0-70-16-70-40s31-41 70-41h535z m-58-135c40 0 70 17 70 40s-32 41-70 41h-477c-39 0-70-18-70-41s31-40 70-40h477z m-51 271c40 0 70 17 70 40s-31 41-70 41h-426c-39 0-70-17-70-41s31-40 70-40h426z m-426-406h6a283 283 0 0 0 137 81h-143c-39-1-70-18-70-41s31-41 70-41z m214 40a234 234 0 1 1 234-234 234 234 0 0 1-234 234z m140-268a9 9 0 0 0-9-9h-81a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-66a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-80a9 9 0 0 0-9 9v66a9 9 0 0 0 9 9h81a9 9 0 0 1 10 9v82a9 9 0 0 0 7 8h65a9 9 0 0 0 9-9v-81a9 9 0 0 1 9-9h81a9 9 0 0 0 9-9v-66z m363-22l-40-64a42 42 0 0 0-21-18l-167-60-4 10a156 156 0 0 1-28 40 285 285 0 0 0-100-99 20 20 0 0 1 18-3l315 94a42 42 0 0 1 18 11l222 223v82l-207-206a42 42 0 0 1-6-8z m-250 182a281 281 0 0 0 17-43l56 34a42 42 0 0 1 8 6l382 383v83z" horiz-adv-x="1000" /> + +<glyph glyph-name="template-add" unicode="" d="M723 48v-157a31 31 0 0 0-32-31h-406a283 283 0 0 1 276 219h132a31 31 0 0 0 30-31z m241 406h-244l-372 187h121a31 31 0 0 1 31 32v156a31 31 0 0 1-31 31h-433a31 31 0 0 1-31-31v-156a31 31 0 0 1 31-32h244l372-187h-121a31 31 0 0 1-31-31v-94a283 283 0 0 0 53-94h132l-117-94a284 284 0 0 0-5-43l170 137h231a31 31 0 0 1 31 31v157a31 31 0 0 1-31 31z m-446-310a234 234 0 1 0-234 234 234 234 0 0 0 234-234z m-94 32a9 9 0 0 1-9 9h-81a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-66a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-80a9 9 0 0 1-9-9v-66a9 9 0 0 1 9-9h81a9 9 0 0 0 10-9v-81a9 9 0 0 1 9-9h65a9 9 0 0 1 9 9v81a9 9 0 0 0 9 9h81a9 9 0 0 1 8 9v66z" horiz-adv-x="1000" /> + +<glyph glyph-name="group-add" unicode="" d="M82 852a82 82 0 0 1-82-82v-110h192v192h-110z m53-134h-77v35a41 41 0 0 0 41 41h36v-76z m783 134h-110v-192h192v110a82 82 0 0 1-82 82z m24-134h-77v76h36a41 41 0 0 0 41-41v-35z m-134-657v-192h110a82 82 0 0 1 82 81v110h-192z m134-94a41 41 0 0 0-41-40h-36v76h77v-36z m-76 126v535h75v-536h-75z m-634 626v74h536v-75h-536z m536-719v-75h-302a285 285 0 0 1 62 75h240z m-485 375a234 234 0 1 1 235-234 234 234 0 0 1-234 237z m141-265a9 9 0 0 0-9-9h-81a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-66a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-80a9 9 0 0 0-9 9v66a9 9 0 0 0 9 9h81a9 9 0 0 1 10 9v82a9 9 0 0 0 7 8h65a9 9 0 0 0 9-9v-81a9 9 0 0 1 9-9h81a9 9 0 0 0 9-9v-66z m-365 206v312h75v-243a285 285 0 0 1-75-69z m709 58v-179a82 82 0 0 0-82-82h-120a286 286 0 0 1 1 31v10h111a49 49 0 0 1 49 50v162a49 49 0 0 1-49 49h-164a49 49 0 0 1-49-49v-6a284 284 0 0 1-38 27 82 82 0 0 0 80 67h46v66a49 49 0 0 1-49 49h-163a49 49 0 0 1-49-49v-94h-8a286 286 0 0 1-31-2v103a82 82 0 0 0 80 83h179a82 82 0 0 0 82-83v-72h92a82 82 0 0 0 82-81z" horiz-adv-x="1000" /> + +<glyph glyph-name="template-import" unicode="" d="M990 442v-153a31 31 0 0 0-31-31h-430a31 31 0 0 0-31 31v153a31 31 0 0 0 31 31h116l-361 172h-243a31 31 0 0 0-31 31v153a31 31 0 0 0 31 31h430a31 31 0 0 0 31-31v-153a31 31 0 0 0-31-32h-115l360-171h243a31 31 0 0 0 31-31z m-656-558h-113a63 63 0 0 0-57 38h-154v-31a31 31 0 0 1 31-31h474a31 31 0 0 1 31 31v31h-154a63 63 0 0 0-57-39z m-115 31h115a31 31 0 0 1 31 31v151a13 13 0 0 0 14 13h159c8 0 10 4 5 9l-256 259a13 13 0 0 1-19 0l-255-258c-5-5-3-10 4-10h159a13 13 0 0 0 14-13v-152a31 31 0 0 1 31-31z" horiz-adv-x="1000" /> + +<glyph glyph-name="template-save" unicode="" d="M990 442v-153a31 31 0 0 0-31-31h-430a31 31 0 0 0-31 31v153a31 31 0 0 0 31 31h116l-361 172h-243a31 31 0 0 0-31 31v153a31 31 0 0 0 31 31h430a31 31 0 0 0 31-31v-153a31 31 0 0 0-31-32h-115l360-171h243a31 31 0 0 0 31-31z m-508-560a22 22 0 0 0-22-22h-438a22 22 0 0 0-22 22v437a22 22 0 0 0 22 22h312a47 47 0 0 0 29-12l106-106a47 47 0 0 0 12-28v-313z m-40 18v286a25 25 0 0 1-7 15l-91 92a44 44 0 0 1-23 9v-139a22 22 0 0 0-22-22h-197a22 22 0 0 0-22 22v139h-40v-402h40v139a22 22 0 0 0 22 22h278a22 22 0 0 0 22-22v-139h40z m-81 0v121h-240v-121h241z m-80 402h-93v-121h71a22 22 0 0 1 22 23v98z" horiz-adv-x="1000" /> + +<glyph glyph-name="group-remote-add" unicode="" d="M82 852a82 82 0 0 1-82-82v-110h192v192h-110z m53-134h-77v35a41 41 0 0 0 41 41h36v-76z m783 134h-110v-192h192v110a82 82 0 0 1-82 82z m24-134h-77v76h36a41 41 0 0 0 41-41v-35z m-134-657v-192h110a82 82 0 0 1 82 81v110h-192z m134-94a41 41 0 0 0-41-40h-36v76h77v-36z m0 126h-75v535h75v-536z m-710 626v74h536v-75h-536z m536-719v-75h-302a285 285 0 0 1 62 75h240z m-485 375a234 234 0 1 1 235-234 234 234 0 0 1-234 237z m141-265a9 9 0 0 0-9-9h-81a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-66a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-80a9 9 0 0 0-9 9v66a9 9 0 0 0 9 9h81a9 9 0 0 1 10 9v82a9 9 0 0 0 7 8h65a9 9 0 0 0 9-9v-81a9 9 0 0 1 9-9h81a9 9 0 0 0 9-9v-66z m-365 206v312h75v-243a285 285 0 0 1-75-69z m750-22a111 111 0 0 0-111-111h-134a281 281 0 0 1-14 59h148a53 53 0 0 1 13 103l-37 9v38a91 91 0 0 1-160 53l-39-50-39 50a29 29 0 0 1-52-22l3-16a281 281 0 0 1-61 16v3a87 87 0 0 0 148 61 148 148 0 0 0 257-89 110 110 0 0 0 78-104z" horiz-adv-x="1000" /> + +<glyph glyph-name="port-out-add" unicode="" d="M284 378a234 234 0 1 1 234-234 234 234 0 0 1-234 234z m140-268a9 9 0 0 0-9-9h-81a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-66a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-80a9 9 0 0 0-9 9v66a9 9 0 0 0 9 9h81a9 9 0 0 1 10 9v82a9 9 0 0 0 7 8h65a9 9 0 0 0 9-9v-81a9 9 0 0 1 9-9h81a9 9 0 0 0 9-9v-66z m365 594v-102l-39 39v63a38 38 0 0 1-39 37h-615a38 38 0 0 1-38-37v-390a281 281 0 0 1-58-170v579l41 41a58 58 0 0 0 41 17h630a77 77 0 0 0 77-77z m205-421l-341-339c-9-8-16-6-16 7v192a22 22 0 0 1-22 22h-49a281 281 0 0 1-11 63h133a11 11 0 0 0 10-11v-132c0-6 4-7 8-3l212 209a11 11 0 0 1 0 15l-212 210c-4 5-8 3-8-3v-130a11 11 0 0 0-10-11h-208a11 11 0 0 1-11-12 283 283 0 0 1-63 40v10a22 22 0 0 0 22 22h188a22 22 0 0 1 22 21v194c0 11 6 15 15 6l341-339a22 22 0 0 0 0-31z" horiz-adv-x="1000" /> + +<glyph glyph-name="port-in-add" unicode="" d="M786 158h-54v276h54v-276z m-179 154l-353 351c-9 10-16 6-16-6v-200a23 23 0 0 0-22-23h-193a23 23 0 0 1-23-22v-231a22 22 0 0 1 2-8 281 281 0 0 0 62 149v38a11 11 0 0 0 11 11h39a281 281 0 0 0 170 57h18v88c0 7 3 8 8 4l218-217a11 11 0 0 0 0-15 281 281 0 0 0 27-60l53 52a23 23 0 0 1-1 32z m-323 66a234 234 0 1 1 234-234 234 234 0 0 1-234 234z m140-268a9 9 0 0 0-9-9h-81a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-66a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-80a9 9 0 0 0-9 9v66a9 9 0 0 0 9 9h81a9 9 0 0 1 10 9v82a9 9 0 0 0 7 8h65a9 9 0 0 0 9-9v-81a9 9 0 0 1 9-9h81a9 9 0 0 0 9-9v-66z m534 668a60 60 0 0 1-42 18h-671a63 63 0 0 1-62-63l41-40v22a40 40 0 0 0 40 40h637a40 40 0 0 0 39-40v-636a40 40 0 0 0-39-40h-354a281 281 0 0 0-31-60h463l21 21v735z" horiz-adv-x="1000" /> + +<glyph glyph-name="processor-add" unicode="" d="M988 777v-761a63 63 0 0 0-19-43l-113-113 15 62h-121l-62-62 14 62h-120l-63-62 15 62h-73a285 285 0 0 1 62 69h375a42 42 0 0 1 42 42v738a42 42 0 0 1-42 42h-737a42 42 0 0 1-42-42v-396a285 285 0 0 1-68-69v99l-39-38 39 87v120l-39-39 39 88v120l-39-39 39 88 50 50a63 63 0 0 0 44 18h760a83 83 0 0 0 83-83z m-469-634a234 234 0 1 0-234 235 234 234 0 0 0 233-234z m-94 32a9 9 0 0 1-9 9h-81a9 9 0 0 0-9 9v81a9 9 0 0 1-9 9h-67a9 9 0 0 1-9-9v-81a9 9 0 0 0-9-9h-80a9 9 0 0 1-9-9v-65a9 9 0 0 1 9-9h81a9 9 0 0 0 10-9v-81a9 9 0 0 1 9-9h65a9 9 0 0 1 9 9v81a9 9 0 0 0 9 9h81a9 9 0 0 1 8 9v66z m356 381a57 57 0 0 1-10 27 299 299 0 0 1-539-160l14 2a221 221 0 0 0 223 194 263 263 0 0 0 208-107 58 58 0 0 1 104 39 242 242 0 0 0-55-316 225 225 0 0 0-137-45 242 242 0 0 0-26 0 256 256 0 0 0 0-82 297 297 0 0 1 142 58 304 304 0 0 1 122 202 256 256 0 0 1-46 188z" horiz-adv-x="1000" /> + +<glyph glyph-name="lineage" unicode="" d="M785 415a214 214 0 0 1-83-17l-58 87a215 215 0 1 1-266-18l-82-184a215 215 0 1 1 72-31l82 185a210 210 0 0 1 127 8l59-90a215 215 0 1 1 149 60z m-539-438a98 98 0 1 0 98 98 98 98 0 0 0-98-98z m157 668a98 98 0 1 0 97-97 98 98 0 0 0-97 97z m382-543a98 98 0 1 0 98 98 98 98 0 0 0-98-98z" horiz-adv-x="1000" /> + +<glyph glyph-name="port-in" unicode="" d="M1000 0v735l-42 43a60 60 0 0 1-42 18h-671a63 63 0 0 1-62-63l41-40v22a40 40 0 0 0 40 40h637a40 40 0 0 0 39-40v-636a40 40 0 0 0-39-40h-449l-60-60h587z m-1000 412v-231a23 23 0 0 1 23-23h192a23 23 0 0 0 23-22v-200c0-13 7-15 16-7l353 351a23 23 0 0 1 0 32l-353 351c-9 10-16 6-16-6v-200a23 23 0 0 0-22-23h-193a23 23 0 0 1-23-22z m63-52a11 11 0 0 0 11 11h216a11 11 0 0 1 12 12v133c0 7 3 8 8 4l218-217a11 11 0 0 0 0-15l-218-217c-5-4-8-3-8 4v135a11 11 0 0 1-12 12h-215a11 11 0 0 0-12 11v127z m722-201h-53v275h54v-276z" horiz-adv-x="1000" /> + +<glyph glyph-name="port-out" unicode="" d="M0 13v710l41 41a58 58 0 0 0 41 17h630a77 77 0 0 0 77-77v-102l-39 39v63a38 38 0 0 1-39 37h-615a38 38 0 0 1-38-37v-616a38 38 0 0 1 38-38h482v-58h-558z m653-69l341 339a22 22 0 0 1 0 31l-341 339c-9 9-16 6-16-6v-193a22 22 0 0 0-22-22h-187a22 22 0 0 1-22-22v-222a22 22 0 0 1 22-22h187a22 22 0 0 0 22-22v-193c0-13 7-16 16-7z m45 141v131a11 11 0 0 1-10 11h-208a11 11 0 0 0-11 11v122a11 11 0 0 0 11 11h208a11 11 0 0 1 10 11v130c0 6 4 7 8 3l212-209a11 11 0 0 0 0-15l-212-209c-4-3-8-3-8 3z m-467 347a127 127 0 0 1-118-134 127 127 0 0 1 118-133 127 127 0 0 1 119 133 127 127 0 0 1-119 134z m0-223a84 84 0 0 0-79 89 84 84 0 0 0 79 89 84 84 0 0 0 79-89 84 84 0 0 0-79-89z" horiz-adv-x="1000" /> + +<glyph glyph-name="connect" unicode="" d="M853 713a500 500 0 1 0-753-53 31 31 0 0 0 46 2l279-279a16 16 0 0 0 0-22l-93-94a8 8 0 0 1 3-13l332-74a8 8 0 0 1 9 9l-72 334a8 8 0 0 1-13 3l-94-93a16 16 0 0 0-22 0l-278 280a31 31 0 0 0 4 47 500 500 0 0 0 652-47z" horiz-adv-x="1000" /> + +<glyph glyph-name="connect-add" unicode="" d="M853 713a500 500 0 1 0-752-53 31 31 0 0 0 46 2l154-154a16 16 0 0 0 0-22l-94-94a8 8 0 0 1 4-13l333-73a8 8 0 0 1 9 10l-74 331a8 8 0 0 1-13 4l-94-94a16 16 0 0 0-22 0l-152 156a31 31 0 0 0 3 47 500 500 0 0 0 652-47z m-55-523a8 8 0 0 1 8 8v70a8 8 0 0 0 7 8h70a8 8 0 0 1 8 8v56a8 8 0 0 1-8 8h-70a8 8 0 0 0-8 8v70a8 8 0 0 1-8 8h-56a8 8 0 0 1-8-8v-70a8 8 0 0 0-8-8h-69a8 8 0 0 1-8-8v-56a8 8 0 0 1 8-8h71a8 8 0 0 0 7-8v-70a8 8 0 0 1 8-8h56z" horiz-adv-x="1000" /> + +<glyph glyph-name="threads" unicode="" d="M308 360a149 149 0 1 0-149 149 149 149 0 0 0 149-149z m10 341a159 159 0 1 1-159-158 159 159 0 0 1 159 158z m-66 0a94 94 0 1 0-94 94 94 94 0 0 0 94-94z m248 149a149 149 0 1 1 149-149 149 149 0 0 1-149 149z m-182-831a159 159 0 1 1-159-159 159 159 0 0 1 159 159z m-66 0a94 94 0 1 0-94 94 94 94 0 0 0 94-94z m248 149a149 149 0 1 1 149-149 149 149 0 0 1-149 149z m341 0a149 149 0 1 1 149-149 149 149 0 0 1-149 149z m159 192a159 159 0 1 1-159-159 159 159 0 0 1 159 159z m-66 0a94 94 0 1 0-94 94 94 94 0 0 0 94-94z m66 341a159 159 0 1 1-159-158 159 159 0 0 1 159 158z m-66 0a94 94 0 1 0-94 94 94 94 0 0 0 94-94z m-434-192a149 149 0 1 1 149-149 149 149 0 0 1-149 149z" horiz-adv-x="1000" /> + +<glyph glyph-name="drop" unicode="" d="M507-28v104a8 8 0 0 0 8 8h104v-112h-112z m0-111a333 333 0 0 1 112 21v56h-104a8 8 0 0 1-8-8v-70z m237 236v112h-103a8 8 0 0 1-8-8v-103h111z m14-139a23 23 0 0 1 6 17v89h-111v-112h88a23 23 0 0 1 17 7z m-98-98a334 334 0 0 1 83 51h-83v-51z m174 238a332 332 0 0 1 22 111h-78v-111h56z m-28-126a333 333 0 0 1 50 83h-50v-83z m0 0a333 333 0 0 1 50 83h-50v-83z m21 258h-209a8 8 0 0 1-8-8v-117h-117a8 8 0 0 1-8-8v-209a342 342 0 0 0-341 343c0 162 127 318 214 432a1279 1279 0 0 1 125 195 4 4 0 0 0 7 0 1279 1279 0 0 1 125-195c85-114 212-270 212-432z m-489 326l-28 5a1143 1143 0 0 1-80-123 406 406 0 0 1-59-255 320 320 0 0 1 107-192 314 314 0 0 1 39-29 4 4 0 0 1 5 7 344 344 0 0 0-94 156 435 435 0 0 0 31 279 1210 1210 0 0 0 68 136z m72 138l-19-26c-20-28-41-55-62-82l24-3c18 29 36 58 53 86l14 25c3 7-6 6-10 0z" horiz-adv-x="1000" /> + +<glyph glyph-name="import" unicode="" d="M12 142c0-22 20-42 42-42h892c22 0 42 20 42 42v116c0 10-20 10-20 0v-96c0-22-22-42-42-42h-852c-22 0-42 20-42 42v96c0 10-20 10-20 0zM500 150l-100 100h80v400h40v-400h80z" fill="#728e9b" horiz-adv-x="1000"/> +</font> +</defs> +</svg> diff --git a/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.ttf b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.ttf Binary files differnew file mode 100644 index 0000000..d90261f --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.ttf diff --git a/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.woff b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.woff Binary files differnew file mode 100644 index 0000000..de3da3e --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.woff diff --git a/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.woff2 b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.woff2 Binary files differnew file mode 100644 index 0000000..84a9ae5 --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/fonts/flowfont/flowfont.woff2 diff --git a/mod/designtool/designtool-web/src/main/webapp/js/jquery/dcae-mod.js b/mod/designtool/designtool-web/src/main/webapp/js/jquery/dcae-mod.js index 879739c..48c5d8e 100644 --- a/mod/designtool/designtool-web/src/main/webapp/js/jquery/dcae-mod.js +++ b/mod/designtool/designtool-web/src/main/webapp/js/jquery/dcae-mod.js @@ -19,7 +19,6 @@ limitations under the License. console.log("loading dcae-mod"); var dt_id; - var hostname; /** * @desc: on load of page, makes submit button disabled. Also makes an api call to get the host IP of the current instance @@ -27,19 +26,7 @@ console.log("loading dcae-mod"); $(document).ready(function (){ if(dt_id == null){ $('#operate-submit-btn').prop('disabled', true); } - //get hostname - $.ajax({ - type: 'GET', - url: '../nifi-api/flow/config', - dataType: 'json', - contentType: 'application/json', - success: function(data){ - hostname= data.flowConfiguration.dcaeDistributorApiHostname; - - //function call: invokes api to refresh the list of Envs - if(hostname){ getDistributionTargets(); } - } - }); + getDistributionTargets(); }); /** @@ -61,7 +48,7 @@ console.log("loading dcae-mod"); $.ajax({ type: 'GET', - url: hostname+'/distribution-targets', + url: '/distributor/distribution-targets', dataType: 'json', contentType: 'application/json', success: function(data){ @@ -97,7 +84,7 @@ console.log("loading dcae-mod"); $.ajax({ type: 'POST', data: JSON.stringify(request), - url: hostname+'/distribution-targets/'+dt_id+'/process-groups', + url: '/distributor/distribution-targets/'+dt_id+'/process-groups', dataType: 'json', contentType: 'application/json', success: function(data){ @@ -133,3 +120,151 @@ console.log("loading dcae-mod"); * @desc: event handler for Close icon of Setting/ Distribution Env CRUD dialog : invokes api to refresh the list of Envs */ var onCloseSettings= function(){ getDistributionTargets(); }; + + +function uecvalue(n) { + return encodeURIComponent("" + $(n).val()); +} + +function esc(s) { + return s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>'); +} + +function onBoard() { + $("#onboarding-in-progress").show(); + var url = "/acumos-adapter/onboard.js?acumos=" + uecvalue("#furl"); + if ($("#cat-menu").val() != "*") { + url += "&catalogId=" + uecvalue("#cat-menu"); + if ($("#sol-menu").val() != "*") { + url += "&solutionId=" + uecvalue("#sol-menu"); + if ($("#rev-menu").val() != "*") { + url += "&revisionId=" + uecvalue("#rev-menu"); + } + } + } + var xhr = new XMLHttpRequest(); + xhr.onerror = function() { + $("#onboarding-in-progress").hide(); + alert("Onboarding failed"); + } + xhr.onload = function() { + if (this.status < 400) { + $("#onboarding-in-progress").hide(); + alert("Onboarding successful"); + } else { + alert("Onboarding error: " + this.statusText); + } + } + xhr.open("POST", url); + xhr.send(); +} + +function chooseSolution() { + if ($("#sol-menu").val() == "*") { + _updatevis(); + } else { + lookupItem("#ac-revs", "#rev-menu", "/acumos-adapter/listRevisions.js?acumos=" + uecvalue("#furl") + "&solutionId=" + uecvalue("#sol-menu")); + } +} + +function chooseCatalog() { + if ($("#cat-menu").val() == "*") { + _updatevis(); + } else { + lookupItem("#ac-sols", "#sol-menu", "/acumos-adapter/listSolutions.js?acumos=" + uecvalue("#furl") + "&catalogId=" + uecvalue("#cat-menu")); + } +} + +function lookupCatalogs() { + $("#onboard").show(); + lookupItem("#c-acumos", "#cat-menu", "/acumos-adapter/listCatalogs.js?acumos=" + uecvalue("#furl")); +} + +function lookupItem(dblock, smenu, url) { + var xhr = new XMLHttpRequest(); + var xmenu = $(smenu); + xmenu[0].options.length = 1; + xmenu.val("*"); + xhr.onerror = function() { + alert("Error querying remote Acumos system"); + $(dblock).hide(); + } + xhr.onload = function() { + var xresp = JSON.parse(this.response); + var i; + for (i = 0; i < xresp.length; i++) { + var option = document.createElement("option"); + option.text = esc(xresp[i].name); + option.value = xresp[i].id; + xmenu[0].add(option); + } + if (xresp.length == 0) { + $(dblock).hide(); + } else { + $(dblock).show(); + } + _updatevis(); + }; + xhr.open("GET", url); + xhr.send(); +} + +function setModelType() { + if ($("#model-type").val() == "mtAcumos") { + $("#furl").val(""); + $("#mt-acumos").show(); + } + _updatevis(); +} + +function _updatevis() { + if ($("#model-type").val() != "mtAcumos") { + $("#mt-acumos").hide(); + $("#furl").val(""); + } + if ($("#furl").val() == "") { + $("#c-acumos").hide(); + $("#onboard").hide(); + $("#cat-menu").val("*"); + } + if ($("#cat-menu").val() == "*") { + $("#ac-sols").hide(); + $("#sol-menu").val(""); + } + if ($("#sol-menu").val() == "*") { + $("#ac-revs").hide(); + $("#rev-menu").val(""); + } +} + +function onBoardComponent() { + _onBoardFile("#cspec", "/onboarding/components"); +} + +function onBoardDataFormat() { + _onBoardFile("#dfspec", "/onboarding/dataformats"); +} + +function _onBoardFile(source, url) { + reader = new FileReader(); + reader.onerror = function() { + alert("Error reading file"); + } + reader.onload = function(evt) { + xhr = new XMLHttpRequest(); + xhr.onload = function() { + if (this.status >= 400) { + alert("File upload failed " + this.statusText); + } else { + alert("File upload complete"); + } + } + xhr.onerror = function() { + alert("File upload failed"); + } + xhr.open("POST", url); + xhr.overrideMimeType("application/json"); + xhr.send(evt.target.result); + }; + reader.readAsBinaryString($(source)[0].files[0]); +} diff --git a/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js b/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js new file mode 100644 index 0000000..b22f40a --- /dev/null +++ b/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/controllers/nf-ng-canvas-global-menu-controller.js @@ -0,0 +1,501 @@ +/* + * 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. + * + * Modifications to the original nifi code for the ONAP project are made + * available under the Apache License, Version 2.0 + */ + +/* global define, module, require, exports */ + +(function (root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', + 'nf.Common', + 'nf.QueueListing', + 'nf.Shell', + 'nf.PolicyManagement', + 'nf.ClusterSummary', + 'nf.ErrorHandler', + 'nf.Settings', + 'nf.CanvasUtils'], + function ($, nfCommon, nfQueueListing, nfShell, nfPolicyManagement, nfClusterSummary, nfErrorHandler, nfSettings, nfCanvasUtils) { + return (nf.ng.Canvas.GlobalMenuCtrl = factory($, nfCommon, nfQueueListing, nfShell, nfPolicyManagement, nfClusterSummary, nfErrorHandler, nfSettings, nfCanvasUtils)); + }); + } else if (typeof exports === 'object' && typeof module === 'object') { + module.exports = (nf.ng.Canvas.GlobalMenuCtrl = + factory(require('jquery'), + require('nf.Common'), + require('nf.QueueListing'), + require('nf.Shell'), + require('nf.PolicyManagement'), + require('nf.ClusterSummary'), + require('nf.ErrorHandler'), + require('nf.Settings'), + require('nf.CanvasUtils'))); + } else { + nf.ng.Canvas.GlobalMenuCtrl = factory(root.$, + root.nf.Common, + root.nf.QueueListing, + root.nf.Shell, + root.nf.PolicyManagement, + root.nf.ClusterSummary, + root.nf.ErrorHandler, + root.nf.Settings, + root.nf.CanvasUtils); + } +}(this, function ($, nfCommon, nfQueueListing, nfShell, nfPolicyManagement, nfClusterSummary, nfErrorHandler, nfSettings, nfCanvasUtils) { + 'use strict'; + + return function (serviceProvider) { + 'use strict'; + + var config = { + urls: { + helpDocument: '../nifi-docs/documentation', + controllerAbout: '../nifi-api/flow/about' + } + }; + + function GlobalMenuCtrl(serviceProvider) { + + /** + * The summary menu item controller. + */ + this.summary = { + + /** + * The summary menu item's shell controller. + */ + shell: { + + /** + * Launch the summary shell. + */ + launch: function () { + nfShell.showPage('summary'); + } + } + }; + + /** + * The counters menu item controller. + */ + this.counters = { + + /** + * The counters menu item's shell controller. + */ + shell: { + + /** + * Launch the counters shell. + */ + launch: function () { + if (nfCommon.canAccessCounters()) { + nfShell.showPage('counters'); + } + } + } + }; + + /** + * The bulletin board menu item controller. + */ + this.bulletinBoard = { + + /** + * The bulletin board menu item's shell controller. + */ + shell: { + + /** + * Launch the bulletin board shell. + */ + launch: function () { + nfShell.showPage('bulletin-board'); + } + } + }; + + /** + * The data provenance menu item controller. + */ + this.dataProvenance = { + + /** + * The data provenance menu item's shell controller. + */ + shell: { + + /** + * Launch the data provenance shell. + */ + launch: function () { + if (nfCommon.canAccessProvenance()) { + nfShell.showPage('provenance'); + } + } + } + }; + + /** + * The controller settings menu item controller. + */ + this.controllerSettings = { + + /** + * The controller settings menu item's shell controller. + */ + shell: { + + /** + * Launch the settings shell. + */ + launch: function () { + nfSettings.showSettings(); + } + } + }; + + /** + * The cluster menu item controller. + */ + this.cluster = { + + /** + * Determines if the cluster menu item is enabled. + * + * @returns {*|boolean} + */ + visible: function () { + return nfClusterSummary.isConnectedToCluster(); + }, + + /** + * The cluster menu item's shell controller. + */ + shell: { + + /** + * Launch the cluster shell. + */ + launch: function () { + if (nfCommon.canAccessController()) { + nfShell.showPage('cluster'); + } + } + } + }; + + /** + * The flow config history menu item controller. + */ + this.flowConfigHistory = { + + /** + * The flow config history menu item's shell controller. + */ + shell: { + + /** + * Launch the history shell. + */ + launch: function () { + nfShell.showPage('history'); + } + } + }; + + /** + * The users menu item controller. + */ + this.users = { + + /** + * The users menu item's shell controller. + */ + shell: { + + /** + * Launch the users shell. + */ + launch: function () { + if (nfCommon.canAccessTenants()) { + nfShell.showPage('users'); + } + } + } + }; + + /** + * The policies menu item controller. + */ + this.policies = { + + /** + * The policies menu item's shell controller. + */ + shell: { + + /** + * Launch the policies shell. + */ + launch: function () { + if (nfCommon.canModifyPolicies() && nfCommon.canAccessTenants()) { + nfPolicyManagement.showGlobalPolicies(); + } + } + } + }; + + /** + * The templates menu item controller. + */ + this.templates = { + + /** + * The templates menu item's shell controller. + */ + shell: { + + /** + * Launch the templates shell. + */ + launch: function () { + nfShell.showPage('templates?' + $.param({ + groupId: nfCanvasUtils.getGroupId() + })); + } + } + }; + + /** + * The help menu item controller. + */ + this.help = { + + /** + * The help menu item's shell controller. + */ + shell: { + + /** + * Launch the help documentation shell. + */ + launch: function () { + nfShell.showPage(config.urls.helpDocument); + } + } + }; + + /** + * The about menu item controller. + */ + this.about = { + + /** + * Initialize the about details. + */ + init: function () { + // get the about details + $.ajax({ + type: 'GET', + url: config.urls.controllerAbout, + dataType: 'json' + }).done(function (response) { + var aboutDetails = response.about; + // set the document title and the about title + document.title = aboutDetails.title; + $('#nf-version').text(aboutDetails.version); + var showVersionDetail = false; + if (aboutDetails.buildTag && aboutDetails.buildTag !== 'HEAD') { + $('#nf-about-build-tag').text(aboutDetails.buildTag); + $('#nf-version-detail-tag').show(); + showVersionDetail = true; + } + if (aboutDetails.buildRevision) { + $('#nf-about-build-revision').text(aboutDetails.buildRevision); + $('#nf-about-build-branch').text(aboutDetails.buildBranch); + $('#nf-version-detail-commit').show(); + showVersionDetail = true + } + if (aboutDetails.buildTimestamp) { + $('#nf-about-build-timestamp').text(aboutDetails.buildTimestamp); + $('#nf-version-detail-timestamp').show(); + showVersionDetail = true; + } + if (showVersionDetail) { + $('#nf-version-detail').show(); + } + + // store the content viewer url if available + if (!nfCommon.isBlank(aboutDetails.contentViewerUrl)) { + $('#nifi-content-viewer-url').text(aboutDetails.contentViewerUrl); + nfQueueListing.initFlowFileDetailsDialog(); + } + }).fail(nfErrorHandler.handleAjaxError); + + this.modal.init(); + }, + + /** + * The about menu item's modal controller. + */ + modal: { + + /** + * Gets the modal element. + * + * @returns {*|jQuery|HTMLElement} + */ + getElement: function () { + return $('#nf-about'); + }, + + /** + * Initialize the modal. + */ + init: function () { + var aboutModal = this; + + var resizeAbout = function () { + var dialog = $(this); + var top = $('#nf-about-pic-container').height() + $('.dialog-header').height() + 10; //10 for padding-top + dialog.find('.dialog-content').css('top', top); + }; + + this.getElement().modal({ + scrollableContentStyle: 'scrollable', + headerText: 'About Apache NiFi', + handler: { + resize: resizeAbout + }, + buttons: [{ + buttonText: 'Ok', + color: { + base: '#728E9B', + hover: '#004849', + text: '#ffffff' + }, + handler: { + click: function () { + aboutModal.hide(); + } + } + }] + }); + }, + + /** + * Updates the modal config. + * + * @param {string} name The name of the property to update. + * @param {object|array} config The config for the `name`. + */ + update: function (name, config) { + this.getElement().modal(name, config); + }, + + /** + * Show the modal + */ + show: function () { + this.getElement().modal('show'); + }, + + /** + * Hide the modal + */ + hide: function () { + this.getElement().modal('hide'); + } + } + }; + + /** + * The import model menu item controller. + */ + this.importModel = { + + /** + * The import model menu item's shell controller. + */ + shell: { + + /** + * Launch the import model shell. + */ + launch: function () { + $("#model-type").val("-"); + nfShell.showContent('#import-model'); + } + } + }; + + /** + * The import component specificaton menu item controller. + */ + this.importComponent = { + + /** + * The import component specification menu item's shell controller. + */ + shell: { + + /** + * Launch the import component shell. + */ + launch: function () { + nfShell.showContent('#import-component'); + } + } + }; + + /** + * The import data format menu item controller. + */ + this.importDataFormat = { + + /** + * The import data format menu item's shell controller. + */ + shell: { + + /** + * Launch the import data format shell. + */ + launch: function () { + nfShell.showContent('#import-data-format'); + } + } + }; + } + + GlobalMenuCtrl.prototype = { + constructor: GlobalMenuCtrl, + + /** + * Initialize the global menu controls. + */ + init: function () { + this.about.init(); + } + } + + var globalMenuCtrl = new GlobalMenuCtrl(); + return globalMenuCtrl; + }; +})); diff --git a/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/nf-settings.js b/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/nf-settings.js index 8c61dac..bede3f1 100644 --- a/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/nf-settings.js +++ b/mod/designtool/designtool-web/src/main/webapp/js/nf/canvas/nf-settings.js @@ -103,21 +103,6 @@ }; - var dcaeDistributorApiHostname; - - //get hostname - $.ajax({ - type: 'GET', - url: '../nifi-api/flow/config', - dataType: 'json', - contentType: 'application/json', - success: function(data){ - dcaeDistributorApiHostname= data.flowConfiguration.dcaeDistributorApiHostname; - console.log(dcaeDistributorApiHostname); - } - }); - - /** * Gets the controller services table. * @@ -573,7 +558,7 @@ // add the new distribution environment var addDistributionEnvironment= $.ajax({ type: 'POST', - url: dcaeDistributorApiHostname+'/distribution-targets', + url: '/distributor/distribution-targets', data: JSON.stringify(environmentEntity), dataType: 'json', contentType: 'application/json' @@ -670,7 +655,7 @@ // updating distribution environment var updateDistributionEnvironment = $.ajax({ type: 'PUT', - url: dcaeDistributorApiHostname+'/distribution-targets/'+environmentEntity.id, + url: '/distributor/distribution-targets/'+environmentEntity.id, data: JSON.stringify(requestEnvironmentEntity), dataType: 'json', contentType: 'application/json' @@ -1824,7 +1809,7 @@ console.log(environmentEntity); $.ajax({ type: 'DELETE', - url: dcaeDistributorApiHostname+'/distribution-targets/'+environmentEntity.id, + url: '/distributor/distribution-targets/'+environmentEntity.id, dataType: 'json' }).done(function (response) { console.log(response); @@ -2023,7 +2008,7 @@ console.log("in loadDistributionEnvironments.. "); return $.ajax({ type: 'GET', - url: dcaeDistributorApiHostname+'/distribution-targets', + url: '/distributor/distribution-targets', dataType: 'json' }).done(function (response) { console.log(response); |