You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by tk...@apache.org on 2015/11/19 07:21:06 UTC
[23/24] nifi git commit: NIFI-1054: Fixing Line endings of source code
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java
index 6aebe62..2fda022 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServiceManager.java
@@ -1,430 +1,430 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-import org.apache.nifi.bootstrap.notification.NotificationContext;
-import org.apache.nifi.bootstrap.notification.NotificationInitializationContext;
-import org.apache.nifi.bootstrap.notification.NotificationService;
-import org.apache.nifi.bootstrap.notification.NotificationType;
-import org.apache.nifi.bootstrap.notification.NotificationValidationContext;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.components.ValidationContext;
-import org.apache.nifi.components.ValidationResult;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-public class NotificationServiceManager {
- private static final Logger logger = LoggerFactory.getLogger(NotificationServiceManager.class);
- private final Map<String, ConfiguredNotificationService> servicesById = new HashMap<>();
- private final Map<NotificationType, List<ConfiguredNotificationService>> servicesByNotificationType = new HashMap<>();
-
- private final ScheduledExecutorService notificationExecutor;
- private int maxAttempts = 5;
-
- public NotificationServiceManager() {
- notificationExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
- @Override
- public Thread newThread(final Runnable r) {
- final Thread t = Executors.defaultThreadFactory().newThread(r);
- t.setName("Notification Service Dispatcher");
- t.setDaemon(true);
- return t;
- }
- });
- }
-
- public void setMaxNotificationAttempts(final int maxAttempts) {
- this.maxAttempts = maxAttempts;
- }
-
- /**
- * Loads the Notification Services from the given XML configuration file.
- *
- * File is expected to have the following format:
- *
- * <pre>
- * <services>
- * <service>
- * <id>service-identifier</id>
- * <class>org.apache.nifi.MyNotificationService</class>
- * <property name="My First Property">Property Value</property>
- * </service>
- * <service>
- * <id>other-service</id>
- * <class>org.apache.nifi.MyOtherNotificationService</class>
- * <property name="Another Property">Property Value 2</property>
- * </service>
- * ...
- * <service>
- * <id>service-identifier-2</id>
- * <class>org.apache.nifi.FinalNotificationService</class>
- * <property name="Yet Another Property">3rd Prop Value</property>
- * </service>
- * </services>
- * </pre>
- *
- * Note that as long as the file can be interpreted properly, a misconfigured service will result in a warning
- * or error being logged and the service will be unavailable but will not prevent the rest of the services from loading.
- *
- * @param servicesFile the XML file to load services from.
- * @throws IOException if unable to read from the given file
- * @throws ParserConfigurationException if unable to parse the given file as XML properly
- * @throws SAXException if unable to parse the given file properly
- */
- public void loadNotificationServices(final File servicesFile) throws IOException, ParserConfigurationException, SAXException {
- final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
- docBuilderFactory.setNamespaceAware(false);
- final DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
-
- final Map<String, ConfiguredNotificationService> serviceMap = new HashMap<>();
- try (final InputStream fis = new FileInputStream(servicesFile);
- final InputStream in = new BufferedInputStream(fis)) {
-
- final Document doc = docBuilder.parse(new InputSource(in));
- final List<Element> serviceElements = getChildElementsByTagName(doc.getDocumentElement(), "service");
- logger.debug("Found {} service elements", serviceElements.size());
-
- for (final Element serviceElement : serviceElements) {
- final ConfiguredNotificationService config = createService(serviceElement);
- final NotificationService service = config.getService();
-
- if (service == null) {
- continue; // reason will have already been logged, so just move on.
- }
-
- final String id = service.getIdentifier();
- if (serviceMap.containsKey(id)) {
- logger.error("Found two different Notification Services configured with the same ID: '{}'. Loaded the first service.", id);
- continue;
- }
-
- // Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications
- final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config));
- final Collection<ValidationResult> validationResults = service.validate(validationContext);
- final List<String> invalidReasons = new ArrayList<>();
-
- for (final ValidationResult result : validationResults) {
- if (!result.isValid()) {
- invalidReasons.add(result.toString());
- }
- }
-
- if (!invalidReasons.isEmpty()) {
- logger.warn("Configured Notification Service {} is not valid for the following reasons: {}", service, invalidReasons);
- }
-
- serviceMap.put(id, config);
- }
- }
-
- logger.info("Successfully loaded the following {} services: {}", serviceMap.size(), serviceMap.keySet());
-
- servicesById.clear();
- servicesById.putAll(serviceMap);
- }
-
- public void notify(final NotificationType type, final String subject, final String message) {
- final List<ConfiguredNotificationService> configs = servicesByNotificationType.get(type);
- if (configs == null || configs.isEmpty()) {
- return;
- }
-
- for (final ConfiguredNotificationService config : configs) {
- final NotificationService service = config.getService();
- final AtomicInteger attemptCount = new AtomicInteger(0);
-
- notificationExecutor.submit(new Runnable() {
- @Override
- public void run() {
- // Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications
- final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config));
- final Collection<ValidationResult> validationResults = service.validate(validationContext);
- final List<String> invalidReasons = new ArrayList<>();
-
- for (final ValidationResult result : validationResults) {
- if (!result.isValid()) {
- invalidReasons.add(result.toString());
- }
- }
-
- // If the service is valid, attempt to send the notification
- boolean failure = false;
- if (invalidReasons.isEmpty()) {
- final NotificationContext context = buildNotificationContext(config);
- try {
- service.notify(context, subject, message);
- logger.info("Successfully sent notification of type {} to {}", type, service);
- } catch (final Throwable t) { // keep running even if a Throwable is caught because we need to ensure that we are able to restart NiFi
- logger.error("Failed to send notification of type {} to {} with Subject {} due to {}. Will ",
- type, service == null ? "Unknown Notification Service" : service.toString(), subject, t.toString());
- logger.error("", t);
- failure = true;
- }
- } else {
- logger.warn("Notification Service {} is not valid for the following reasons: {}", service, invalidReasons);
- failure = true;
- }
-
- final int attempts = attemptCount.incrementAndGet();
- if (failure) {
- if (attempts < maxAttempts) {
- logger.info("After failing to send notification to {} {} times, will attempt again in 1 minute", service, attempts);
- notificationExecutor.schedule(this, 1, TimeUnit.MINUTES);
- } else {
- logger.info("After failing to send notification of type {} to {} {} times, will no longer attempt to send notification", type, service, attempts);
- }
- }
- }
- });
-
- if (NotificationType.NIFI_STOPPED.equals(type)) {
- // If we are stopping NiFi, we want to block until we've tried to send the notification at least once before
- // we return. We do this because the executor used to run the task marks the threads as daemon, and on shutdown
- // we don't want to return before the notifier has had a chance to perform its task.
- while (attemptCount.get() == 0) {
- try {
- Thread.sleep(1000L);
- } catch (final InterruptedException ie) {
- }
- }
- }
- }
- }
-
- private NotificationContext buildNotificationContext(final ConfiguredNotificationService config) {
- return new NotificationContext() {
- @Override
- public PropertyValue getProperty(final PropertyDescriptor descriptor) {
- final PropertyDescriptor fullPropDescriptor = config.getService().getPropertyDescriptor(descriptor.getName());
- if (fullPropDescriptor == null) {
- return null;
- }
-
- String configuredValue = config.getProperties().get(fullPropDescriptor.getName());
- if (configuredValue == null) {
- configuredValue = fullPropDescriptor.getDefaultValue();
- }
-
- return new NotificationServicePropertyValue(configuredValue);
- }
-
- @Override
- public Map<PropertyDescriptor, String> getProperties() {
- final Map<PropertyDescriptor, String> props = new HashMap<>();
- final Map<String, String> configuredProps = config.getProperties();
-
- final NotificationService service = config.getService();
- for (final PropertyDescriptor descriptor : service.getPropertyDescriptors()) {
- final String configuredValue = configuredProps.get(descriptor.getName());
- if (configuredValue == null) {
- props.put(descriptor, descriptor.getDefaultValue());
- } else {
- props.put(descriptor, configuredValue);
- }
- }
-
- return props;
- }
-
- };
- }
-
- /**
- * Registers the service that has the given identifier to respond to notifications of the given type
- *
- * @param type the type of notification to register the service for
- * @param serviceId the identifier of the service
- */
- public void registerNotificationService(final NotificationType type, final String serviceId) {
- final ConfiguredNotificationService service = servicesById.get(serviceId);
- if (service == null) {
- throw new IllegalArgumentException("No Notification Service exists with ID " + serviceId);
- }
-
- List<ConfiguredNotificationService> services = servicesByNotificationType.get(type);
- if (services == null) {
- services = new ArrayList<>();
- servicesByNotificationType.put(type, services);
- }
-
- services.add(service);
- }
-
- /**
- * Creates a Notification Service and initializes it. Then returns the service and its configured properties
- *
- * @param serviceElement the XML element from which to build the Notification Service
- * @return a Tuple with the NotificationService as the key and the configured properties as the value, or <code>null</code> if
- * unable to create the service
- */
- private ConfiguredNotificationService createService(final Element serviceElement) {
- final Element idElement = getChild(serviceElement, "id");
- if (idElement == null) {
- logger.error("Found configuration for Notification Service with no 'id' element; this service cannot be referenced so it will not be loaded");
- return null;
- }
-
- final String serviceId = idElement.getTextContent().trim();
- logger.debug("Loading Notification Service with ID {}", serviceId);
-
- final Element classElement = getChild(serviceElement, "class");
- if (classElement == null) {
- logger.error("Found configuration for Notification Service with no 'class' element; Service ID is '{}'. This service annot be loaded", serviceId);
- return null;
- }
-
- final String className = classElement.getTextContent().trim();
- final Class<?> clazz;
- try {
- clazz = Class.forName(className);
- } catch (final Exception e) {
- logger.error("Found configuration for Notification Service with ID '{}' and Class '{}' but could not load class.", serviceId, className);
- logger.error("", e);
- return null;
- }
-
- if (!NotificationService.class.isAssignableFrom(clazz)) {
- logger.error("Found configuration for Notification Service with ID '{}' and Class '{}' but class is not a Notification Service.", serviceId, className);
- return null;
- }
-
- final Object serviceObject;
- try {
- serviceObject = clazz.newInstance();
- } catch (final Exception e) {
- logger.error("Found configuration for Notification Service with ID '{}' and Class '{}' but could not instantiate Notification Service.", serviceId, className);
- logger.error("", e);
- return null;
- }
-
- final Map<String, String> propertyValues = new HashMap<>();
- final List<Element> propertyElements = getChildElementsByTagName(serviceElement, "property");
- for (final Element propertyElement : propertyElements) {
- final String propName = propertyElement.getAttribute("name");
- if (propName == null || propName.trim().isEmpty()) {
- logger.warn("Found configuration for Notification Service with ID '{}' that has property value configured but no name for the property.", serviceId);
- continue;
- }
-
- final String propValue = propertyElement.getTextContent().trim();
- propertyValues.put(propName, propValue);
- }
-
- final NotificationService service = (NotificationService) serviceObject;
-
- try {
- service.initialize(new NotificationInitializationContext() {
- @Override
- public PropertyValue getProperty(final PropertyDescriptor descriptor) {
- final String propName = descriptor.getName();
- String value = propertyValues.get(propName);
- if (value == null) {
- value = descriptor.getDefaultValue();
- }
-
- return new NotificationServicePropertyValue(value);
- }
-
- @Override
- public String getIdentifier() {
- return serviceId;
- }
- });
- } catch (final Exception e) {
- logger.error("Failed to load Notification Service with ID '{}'", serviceId);
- logger.error("", e);
- }
-
- return new ConfiguredNotificationService(service, propertyValues);
- }
-
- public static Element getChild(final Element element, final String tagName) {
- final List<Element> children = getChildElementsByTagName(element, tagName);
- if (children.isEmpty()) {
- return null;
- }
-
- if (children.size() > 1) {
- return null;
- }
-
- return children.get(0);
- }
-
- public static List<Element> getChildElementsByTagName(final Element element, final String tagName) {
- final List<Element> matches = new ArrayList<>();
- final NodeList nodeList = element.getChildNodes();
- for (int i = 0; i < nodeList.getLength(); i++) {
- final Node node = nodeList.item(i);
- if (!(node instanceof Element)) {
- continue;
- }
-
- final Element child = (Element) nodeList.item(i);
- if (child.getNodeName().equals(tagName)) {
- matches.add(child);
- }
- }
-
- return matches;
- }
-
- private static class ConfiguredNotificationService {
- private final NotificationService service;
- private final Map<String, String> properties;
-
- public ConfiguredNotificationService(final NotificationService service, final Map<String, String> properties) {
- this.service = service;
- this.properties = properties;
- }
-
- public NotificationService getService() {
- return service;
- }
-
- public Map<String, String> getProperties() {
- return properties;
- }
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.apache.nifi.bootstrap.notification.NotificationContext;
+import org.apache.nifi.bootstrap.notification.NotificationInitializationContext;
+import org.apache.nifi.bootstrap.notification.NotificationService;
+import org.apache.nifi.bootstrap.notification.NotificationType;
+import org.apache.nifi.bootstrap.notification.NotificationValidationContext;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.components.ValidationResult;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+public class NotificationServiceManager {
+ private static final Logger logger = LoggerFactory.getLogger(NotificationServiceManager.class);
+ private final Map<String, ConfiguredNotificationService> servicesById = new HashMap<>();
+ private final Map<NotificationType, List<ConfiguredNotificationService>> servicesByNotificationType = new HashMap<>();
+
+ private final ScheduledExecutorService notificationExecutor;
+ private int maxAttempts = 5;
+
+ public NotificationServiceManager() {
+ notificationExecutor = Executors.newScheduledThreadPool(1, new ThreadFactory() {
+ @Override
+ public Thread newThread(final Runnable r) {
+ final Thread t = Executors.defaultThreadFactory().newThread(r);
+ t.setName("Notification Service Dispatcher");
+ t.setDaemon(true);
+ return t;
+ }
+ });
+ }
+
+ public void setMaxNotificationAttempts(final int maxAttempts) {
+ this.maxAttempts = maxAttempts;
+ }
+
+ /**
+ * Loads the Notification Services from the given XML configuration file.
+ *
+ * File is expected to have the following format:
+ *
+ * <pre>
+ * <services>
+ * <service>
+ * <id>service-identifier</id>
+ * <class>org.apache.nifi.MyNotificationService</class>
+ * <property name="My First Property">Property Value</property>
+ * </service>
+ * <service>
+ * <id>other-service</id>
+ * <class>org.apache.nifi.MyOtherNotificationService</class>
+ * <property name="Another Property">Property Value 2</property>
+ * </service>
+ * ...
+ * <service>
+ * <id>service-identifier-2</id>
+ * <class>org.apache.nifi.FinalNotificationService</class>
+ * <property name="Yet Another Property">3rd Prop Value</property>
+ * </service>
+ * </services>
+ * </pre>
+ *
+ * Note that as long as the file can be interpreted properly, a misconfigured service will result in a warning
+ * or error being logged and the service will be unavailable but will not prevent the rest of the services from loading.
+ *
+ * @param servicesFile the XML file to load services from.
+ * @throws IOException if unable to read from the given file
+ * @throws ParserConfigurationException if unable to parse the given file as XML properly
+ * @throws SAXException if unable to parse the given file properly
+ */
+ public void loadNotificationServices(final File servicesFile) throws IOException, ParserConfigurationException, SAXException {
+ final DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
+ docBuilderFactory.setNamespaceAware(false);
+ final DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+
+ final Map<String, ConfiguredNotificationService> serviceMap = new HashMap<>();
+ try (final InputStream fis = new FileInputStream(servicesFile);
+ final InputStream in = new BufferedInputStream(fis)) {
+
+ final Document doc = docBuilder.parse(new InputSource(in));
+ final List<Element> serviceElements = getChildElementsByTagName(doc.getDocumentElement(), "service");
+ logger.debug("Found {} service elements", serviceElements.size());
+
+ for (final Element serviceElement : serviceElements) {
+ final ConfiguredNotificationService config = createService(serviceElement);
+ final NotificationService service = config.getService();
+
+ if (service == null) {
+ continue; // reason will have already been logged, so just move on.
+ }
+
+ final String id = service.getIdentifier();
+ if (serviceMap.containsKey(id)) {
+ logger.error("Found two different Notification Services configured with the same ID: '{}'. Loaded the first service.", id);
+ continue;
+ }
+
+ // Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications
+ final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config));
+ final Collection<ValidationResult> validationResults = service.validate(validationContext);
+ final List<String> invalidReasons = new ArrayList<>();
+
+ for (final ValidationResult result : validationResults) {
+ if (!result.isValid()) {
+ invalidReasons.add(result.toString());
+ }
+ }
+
+ if (!invalidReasons.isEmpty()) {
+ logger.warn("Configured Notification Service {} is not valid for the following reasons: {}", service, invalidReasons);
+ }
+
+ serviceMap.put(id, config);
+ }
+ }
+
+ logger.info("Successfully loaded the following {} services: {}", serviceMap.size(), serviceMap.keySet());
+
+ servicesById.clear();
+ servicesById.putAll(serviceMap);
+ }
+
+ public void notify(final NotificationType type, final String subject, final String message) {
+ final List<ConfiguredNotificationService> configs = servicesByNotificationType.get(type);
+ if (configs == null || configs.isEmpty()) {
+ return;
+ }
+
+ for (final ConfiguredNotificationService config : configs) {
+ final NotificationService service = config.getService();
+ final AtomicInteger attemptCount = new AtomicInteger(0);
+
+ notificationExecutor.submit(new Runnable() {
+ @Override
+ public void run() {
+ // Check if the service is valid; if not, warn now so that users know this before they fail to receive notifications
+ final ValidationContext validationContext = new NotificationValidationContext(buildNotificationContext(config));
+ final Collection<ValidationResult> validationResults = service.validate(validationContext);
+ final List<String> invalidReasons = new ArrayList<>();
+
+ for (final ValidationResult result : validationResults) {
+ if (!result.isValid()) {
+ invalidReasons.add(result.toString());
+ }
+ }
+
+ // If the service is valid, attempt to send the notification
+ boolean failure = false;
+ if (invalidReasons.isEmpty()) {
+ final NotificationContext context = buildNotificationContext(config);
+ try {
+ service.notify(context, subject, message);
+ logger.info("Successfully sent notification of type {} to {}", type, service);
+ } catch (final Throwable t) { // keep running even if a Throwable is caught because we need to ensure that we are able to restart NiFi
+ logger.error("Failed to send notification of type {} to {} with Subject {} due to {}. Will ",
+ type, service == null ? "Unknown Notification Service" : service.toString(), subject, t.toString());
+ logger.error("", t);
+ failure = true;
+ }
+ } else {
+ logger.warn("Notification Service {} is not valid for the following reasons: {}", service, invalidReasons);
+ failure = true;
+ }
+
+ final int attempts = attemptCount.incrementAndGet();
+ if (failure) {
+ if (attempts < maxAttempts) {
+ logger.info("After failing to send notification to {} {} times, will attempt again in 1 minute", service, attempts);
+ notificationExecutor.schedule(this, 1, TimeUnit.MINUTES);
+ } else {
+ logger.info("After failing to send notification of type {} to {} {} times, will no longer attempt to send notification", type, service, attempts);
+ }
+ }
+ }
+ });
+
+ if (NotificationType.NIFI_STOPPED.equals(type)) {
+ // If we are stopping NiFi, we want to block until we've tried to send the notification at least once before
+ // we return. We do this because the executor used to run the task marks the threads as daemon, and on shutdown
+ // we don't want to return before the notifier has had a chance to perform its task.
+ while (attemptCount.get() == 0) {
+ try {
+ Thread.sleep(1000L);
+ } catch (final InterruptedException ie) {
+ }
+ }
+ }
+ }
+ }
+
+ private NotificationContext buildNotificationContext(final ConfiguredNotificationService config) {
+ return new NotificationContext() {
+ @Override
+ public PropertyValue getProperty(final PropertyDescriptor descriptor) {
+ final PropertyDescriptor fullPropDescriptor = config.getService().getPropertyDescriptor(descriptor.getName());
+ if (fullPropDescriptor == null) {
+ return null;
+ }
+
+ String configuredValue = config.getProperties().get(fullPropDescriptor.getName());
+ if (configuredValue == null) {
+ configuredValue = fullPropDescriptor.getDefaultValue();
+ }
+
+ return new NotificationServicePropertyValue(configuredValue);
+ }
+
+ @Override
+ public Map<PropertyDescriptor, String> getProperties() {
+ final Map<PropertyDescriptor, String> props = new HashMap<>();
+ final Map<String, String> configuredProps = config.getProperties();
+
+ final NotificationService service = config.getService();
+ for (final PropertyDescriptor descriptor : service.getPropertyDescriptors()) {
+ final String configuredValue = configuredProps.get(descriptor.getName());
+ if (configuredValue == null) {
+ props.put(descriptor, descriptor.getDefaultValue());
+ } else {
+ props.put(descriptor, configuredValue);
+ }
+ }
+
+ return props;
+ }
+
+ };
+ }
+
+ /**
+ * Registers the service that has the given identifier to respond to notifications of the given type
+ *
+ * @param type the type of notification to register the service for
+ * @param serviceId the identifier of the service
+ */
+ public void registerNotificationService(final NotificationType type, final String serviceId) {
+ final ConfiguredNotificationService service = servicesById.get(serviceId);
+ if (service == null) {
+ throw new IllegalArgumentException("No Notification Service exists with ID " + serviceId);
+ }
+
+ List<ConfiguredNotificationService> services = servicesByNotificationType.get(type);
+ if (services == null) {
+ services = new ArrayList<>();
+ servicesByNotificationType.put(type, services);
+ }
+
+ services.add(service);
+ }
+
+ /**
+ * Creates a Notification Service and initializes it. Then returns the service and its configured properties
+ *
+ * @param serviceElement the XML element from which to build the Notification Service
+ * @return a Tuple with the NotificationService as the key and the configured properties as the value, or <code>null</code> if
+ * unable to create the service
+ */
+ private ConfiguredNotificationService createService(final Element serviceElement) {
+ final Element idElement = getChild(serviceElement, "id");
+ if (idElement == null) {
+ logger.error("Found configuration for Notification Service with no 'id' element; this service cannot be referenced so it will not be loaded");
+ return null;
+ }
+
+ final String serviceId = idElement.getTextContent().trim();
+ logger.debug("Loading Notification Service with ID {}", serviceId);
+
+ final Element classElement = getChild(serviceElement, "class");
+ if (classElement == null) {
+ logger.error("Found configuration for Notification Service with no 'class' element; Service ID is '{}'. This service annot be loaded", serviceId);
+ return null;
+ }
+
+ final String className = classElement.getTextContent().trim();
+ final Class<?> clazz;
+ try {
+ clazz = Class.forName(className);
+ } catch (final Exception e) {
+ logger.error("Found configuration for Notification Service with ID '{}' and Class '{}' but could not load class.", serviceId, className);
+ logger.error("", e);
+ return null;
+ }
+
+ if (!NotificationService.class.isAssignableFrom(clazz)) {
+ logger.error("Found configuration for Notification Service with ID '{}' and Class '{}' but class is not a Notification Service.", serviceId, className);
+ return null;
+ }
+
+ final Object serviceObject;
+ try {
+ serviceObject = clazz.newInstance();
+ } catch (final Exception e) {
+ logger.error("Found configuration for Notification Service with ID '{}' and Class '{}' but could not instantiate Notification Service.", serviceId, className);
+ logger.error("", e);
+ return null;
+ }
+
+ final Map<String, String> propertyValues = new HashMap<>();
+ final List<Element> propertyElements = getChildElementsByTagName(serviceElement, "property");
+ for (final Element propertyElement : propertyElements) {
+ final String propName = propertyElement.getAttribute("name");
+ if (propName == null || propName.trim().isEmpty()) {
+ logger.warn("Found configuration for Notification Service with ID '{}' that has property value configured but no name for the property.", serviceId);
+ continue;
+ }
+
+ final String propValue = propertyElement.getTextContent().trim();
+ propertyValues.put(propName, propValue);
+ }
+
+ final NotificationService service = (NotificationService) serviceObject;
+
+ try {
+ service.initialize(new NotificationInitializationContext() {
+ @Override
+ public PropertyValue getProperty(final PropertyDescriptor descriptor) {
+ final String propName = descriptor.getName();
+ String value = propertyValues.get(propName);
+ if (value == null) {
+ value = descriptor.getDefaultValue();
+ }
+
+ return new NotificationServicePropertyValue(value);
+ }
+
+ @Override
+ public String getIdentifier() {
+ return serviceId;
+ }
+ });
+ } catch (final Exception e) {
+ logger.error("Failed to load Notification Service with ID '{}'", serviceId);
+ logger.error("", e);
+ }
+
+ return new ConfiguredNotificationService(service, propertyValues);
+ }
+
+ public static Element getChild(final Element element, final String tagName) {
+ final List<Element> children = getChildElementsByTagName(element, tagName);
+ if (children.isEmpty()) {
+ return null;
+ }
+
+ if (children.size() > 1) {
+ return null;
+ }
+
+ return children.get(0);
+ }
+
+ public static List<Element> getChildElementsByTagName(final Element element, final String tagName) {
+ final List<Element> matches = new ArrayList<>();
+ final NodeList nodeList = element.getChildNodes();
+ for (int i = 0; i < nodeList.getLength(); i++) {
+ final Node node = nodeList.item(i);
+ if (!(node instanceof Element)) {
+ continue;
+ }
+
+ final Element child = (Element) nodeList.item(i);
+ if (child.getNodeName().equals(tagName)) {
+ matches.add(child);
+ }
+ }
+
+ return matches;
+ }
+
+ private static class ConfiguredNotificationService {
+ private final NotificationService service;
+ private final Map<String, String> properties;
+
+ public ConfiguredNotificationService(final NotificationService service, final Map<String, String> properties) {
+ this.service = service;
+ this.properties = properties;
+ }
+
+ public NotificationService getService() {
+ return service;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServicePropertyValue.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServicePropertyValue.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServicePropertyValue.java
index 944dff6..582b342 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServicePropertyValue.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/NotificationServicePropertyValue.java
@@ -1,120 +1,120 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap;
-
-import java.util.concurrent.TimeUnit;
-
-import org.apache.nifi.attribute.expression.language.PreparedQuery;
-import org.apache.nifi.attribute.expression.language.Query;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.expression.AttributeValueDecorator;
-import org.apache.nifi.flowfile.FlowFile;
-import org.apache.nifi.processor.DataUnit;
-import org.apache.nifi.processor.exception.ProcessException;
-import org.apache.nifi.util.FormatUtils;
-
-public class NotificationServicePropertyValue implements PropertyValue {
- private final String rawValue;
- private final PreparedQuery preparedQuery;
-
- public NotificationServicePropertyValue(final String rawValue) {
- this.rawValue = rawValue;
- this.preparedQuery = Query.prepare(rawValue);
- }
-
- @Override
- public String getValue() {
- return rawValue;
- }
-
- @Override
- public Integer asInteger() {
- return (rawValue == null) ? null : Integer.parseInt(rawValue.trim());
- }
-
- @Override
- public Long asLong() {
- return (rawValue == null) ? null : Long.parseLong(rawValue.trim());
- }
-
- @Override
- public Boolean asBoolean() {
- return (rawValue == null) ? null : Boolean.parseBoolean(rawValue.trim());
- }
-
- @Override
- public Float asFloat() {
- return (rawValue == null) ? null : Float.parseFloat(rawValue.trim());
- }
-
- @Override
- public Double asDouble() {
- return (rawValue == null) ? null : Double.parseDouble(rawValue.trim());
- }
-
- @Override
- public Long asTimePeriod(final TimeUnit timeUnit) {
- return (rawValue == null) ? null : FormatUtils.getTimeDuration(rawValue.trim(), timeUnit);
- }
-
- @Override
- public Double asDataSize(final DataUnit dataUnit) {
- return rawValue == null ? null : DataUnit.parseDataSize(rawValue.trim(), dataUnit);
- }
-
- @Override
- public PropertyValue evaluateAttributeExpressions() throws ProcessException {
- return evaluateAttributeExpressions((AttributeValueDecorator) null);
- }
-
- @Override
- public PropertyValue evaluateAttributeExpressions(final AttributeValueDecorator decorator) throws ProcessException {
- return new NotificationServicePropertyValue(preparedQuery.evaluateExpressions((FlowFile) null, decorator));
- }
-
- @Override
- public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile) throws ProcessException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String toString() {
- return rawValue;
- }
-
- @Override
- public ControllerService asControllerService() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public <T extends ControllerService> T asControllerService(final Class<T> serviceType) throws IllegalArgumentException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public boolean isSet() {
- return rawValue != null;
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap;
+
+import java.util.concurrent.TimeUnit;
+
+import org.apache.nifi.attribute.expression.language.PreparedQuery;
+import org.apache.nifi.attribute.expression.language.Query;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.expression.AttributeValueDecorator;
+import org.apache.nifi.flowfile.FlowFile;
+import org.apache.nifi.processor.DataUnit;
+import org.apache.nifi.processor.exception.ProcessException;
+import org.apache.nifi.util.FormatUtils;
+
+public class NotificationServicePropertyValue implements PropertyValue {
+ private final String rawValue;
+ private final PreparedQuery preparedQuery;
+
+ public NotificationServicePropertyValue(final String rawValue) {
+ this.rawValue = rawValue;
+ this.preparedQuery = Query.prepare(rawValue);
+ }
+
+ @Override
+ public String getValue() {
+ return rawValue;
+ }
+
+ @Override
+ public Integer asInteger() {
+ return (rawValue == null) ? null : Integer.parseInt(rawValue.trim());
+ }
+
+ @Override
+ public Long asLong() {
+ return (rawValue == null) ? null : Long.parseLong(rawValue.trim());
+ }
+
+ @Override
+ public Boolean asBoolean() {
+ return (rawValue == null) ? null : Boolean.parseBoolean(rawValue.trim());
+ }
+
+ @Override
+ public Float asFloat() {
+ return (rawValue == null) ? null : Float.parseFloat(rawValue.trim());
+ }
+
+ @Override
+ public Double asDouble() {
+ return (rawValue == null) ? null : Double.parseDouble(rawValue.trim());
+ }
+
+ @Override
+ public Long asTimePeriod(final TimeUnit timeUnit) {
+ return (rawValue == null) ? null : FormatUtils.getTimeDuration(rawValue.trim(), timeUnit);
+ }
+
+ @Override
+ public Double asDataSize(final DataUnit dataUnit) {
+ return rawValue == null ? null : DataUnit.parseDataSize(rawValue.trim(), dataUnit);
+ }
+
+ @Override
+ public PropertyValue evaluateAttributeExpressions() throws ProcessException {
+ return evaluateAttributeExpressions((AttributeValueDecorator) null);
+ }
+
+ @Override
+ public PropertyValue evaluateAttributeExpressions(final AttributeValueDecorator decorator) throws ProcessException {
+ return new NotificationServicePropertyValue(preparedQuery.evaluateExpressions((FlowFile) null, decorator));
+ }
+
+ @Override
+ public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile) throws ProcessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public PropertyValue evaluateAttributeExpressions(final FlowFile flowFile, final AttributeValueDecorator decorator) throws ProcessException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String toString() {
+ return rawValue;
+ }
+
+ @Override
+ public ControllerService asControllerService() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public <T extends ControllerService> T asControllerService(final Class<T> serviceType) throws IllegalArgumentException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public boolean isSet() {
+ return rawValue != null;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/AbstractNotificationService.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/AbstractNotificationService.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/AbstractNotificationService.java
index a91a377..109b1bc 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/AbstractNotificationService.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/AbstractNotificationService.java
@@ -1,37 +1,37 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-import org.apache.nifi.components.AbstractConfigurableComponent;
-
-public abstract class AbstractNotificationService extends AbstractConfigurableComponent implements NotificationService {
- private String identifier; // effectively final
-
- @Override
- public final void initialize(final NotificationInitializationContext context) {
- this.identifier = context.getIdentifier();
- init(context);
- }
-
- protected void init(final NotificationInitializationContext context) {
- }
-
- @Override
- public String getIdentifier() {
- return identifier;
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+import org.apache.nifi.components.AbstractConfigurableComponent;
+
+public abstract class AbstractNotificationService extends AbstractConfigurableComponent implements NotificationService {
+ private String identifier; // effectively final
+
+ @Override
+ public final void initialize(final NotificationInitializationContext context) {
+ this.identifier = context.getIdentifier();
+ init(context);
+ }
+
+ protected void init(final NotificationInitializationContext context) {
+ }
+
+ @Override
+ public String getIdentifier() {
+ return identifier;
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationContext.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationContext.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationContext.java
index 2c030a1..ba4ba93 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationContext.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationContext.java
@@ -1,44 +1,44 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-import java.util.Map;
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.PropertyValue;
-
-public interface NotificationContext {
-
- /**
- * Returns the configured value for the given PropertyDescriptor. Note that the implementation
- * of PropertyValue will throw an Exception if calling {@link PropertyValue#asControllerService()} or
- * {@link PropertyValue#asControllerService(Class)}, as Controller Services are not allowed to be
- * referenced by Notification Services
- *
- * @param descriptor the property whose value should be returned
- * @return the configured value for the given PropertyDescriptor, or the default
- * value for the PropertyDescriptor if no value has been configured
- */
- PropertyValue getProperty(PropertyDescriptor descriptor);
-
- /**
- * @return a Map of all PropertyDescriptors to their configured values. This
- * Map may or may not be modifiable, but modifying its values will not
- * change the values of the processor's properties
- */
- Map<PropertyDescriptor, String> getProperties();
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+import java.util.Map;
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.PropertyValue;
+
+public interface NotificationContext {
+
+ /**
+ * Returns the configured value for the given PropertyDescriptor. Note that the implementation
+ * of PropertyValue will throw an Exception if calling {@link PropertyValue#asControllerService()} or
+ * {@link PropertyValue#asControllerService(Class)}, as Controller Services are not allowed to be
+ * referenced by Notification Services
+ *
+ * @param descriptor the property whose value should be returned
+ * @return the configured value for the given PropertyDescriptor, or the default
+ * value for the PropertyDescriptor if no value has been configured
+ */
+ PropertyValue getProperty(PropertyDescriptor descriptor);
+
+ /**
+ * @return a Map of all PropertyDescriptors to their configured values. This
+ * Map may or may not be modifiable, but modifying its values will not
+ * change the values of the processor's properties
+ */
+ Map<PropertyDescriptor, String> getProperties();
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationFailedException.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationFailedException.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationFailedException.java
index fcab95b..93c3459 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationFailedException.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationFailedException.java
@@ -1,33 +1,33 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-public class NotificationFailedException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public NotificationFailedException(final String message) {
- super(message);
- }
-
- public NotificationFailedException(final String message, final Throwable t) {
- super(message, t);
- }
-
- public NotificationFailedException(final Throwable t) {
- super(t);
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+public class NotificationFailedException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public NotificationFailedException(final String message) {
+ super(message);
+ }
+
+ public NotificationFailedException(final String message, final Throwable t) {
+ super(message, t);
+ }
+
+ public NotificationFailedException(final Throwable t) {
+ super(t);
+ }
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationInitializationContext.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationInitializationContext.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationInitializationContext.java
index c75c8f4..88e0445 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationInitializationContext.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationInitializationContext.java
@@ -1,39 +1,39 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.PropertyValue;
-
-public interface NotificationInitializationContext {
-
- /**
- * Returns the configured value for the given PropertyDescriptor
- *
- * @param descriptor the property to fetch the value for
- * @return the configured value for the given PropertyDescriptor, or the default value for the PropertyDescriptor
- * if no value has been configured.
- */
- PropertyValue getProperty(PropertyDescriptor descriptor);
-
- /**
- * @return the identifier for the NotificationService
- */
- String getIdentifier();
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.PropertyValue;
+
+public interface NotificationInitializationContext {
+
+ /**
+ * Returns the configured value for the given PropertyDescriptor
+ *
+ * @param descriptor the property to fetch the value for
+ * @return the configured value for the given PropertyDescriptor, or the default value for the PropertyDescriptor
+ * if no value has been configured.
+ */
+ PropertyValue getProperty(PropertyDescriptor descriptor);
+
+ /**
+ * @return the identifier for the NotificationService
+ */
+ String getIdentifier();
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationService.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationService.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationService.java
index 044d906..abf9e80 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationService.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationService.java
@@ -1,56 +1,56 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-import org.apache.nifi.components.ConfigurableComponent;
-
-/**
- * <p>
- * A NotificationService is simple mechanism that the Bootstrap can use to notify
- * interested parties when some event takes place, such as NiFi being started, stopped,
- * or restarted because the process died.
- * </p>
- *
- * <p>
- * <b>Note:</b> This feature was introduced in version 0.3.0 of NiFi and is likely to undergo
- * significant refactorings. As such, at this time it is NOT considered a public API and may well
- * change from version to version until the API has stabilized. At that point, it will become a public
- * API.
- * </p>
- *
- * @since 0.3.0
- */
-public interface NotificationService extends ConfigurableComponent {
-
- /**
- * Provides the NotificatoinService with access to objects that may be of use
- * throughout the life of the service
- *
- * @param context of initialization
- */
- void initialize(NotificationInitializationContext context);
-
- /**
- * Notifies the configured recipients of some event
- *
- * @param context the context that is relevant for this notification
- * @param subject the subject of the message
- * @param message the message to be provided to recipients
- */
- void notify(NotificationContext context, String subject, String message) throws NotificationFailedException;
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+import org.apache.nifi.components.ConfigurableComponent;
+
+/**
+ * <p>
+ * A NotificationService is simple mechanism that the Bootstrap can use to notify
+ * interested parties when some event takes place, such as NiFi being started, stopped,
+ * or restarted because the process died.
+ * </p>
+ *
+ * <p>
+ * <b>Note:</b> This feature was introduced in version 0.3.0 of NiFi and is likely to undergo
+ * significant refactorings. As such, at this time it is NOT considered a public API and may well
+ * change from version to version until the API has stabilized. At that point, it will become a public
+ * API.
+ * </p>
+ *
+ * @since 0.3.0
+ */
+public interface NotificationService extends ConfigurableComponent {
+
+ /**
+ * Provides the NotificatoinService with access to objects that may be of use
+ * throughout the life of the service
+ *
+ * @param context of initialization
+ */
+ void initialize(NotificationInitializationContext context);
+
+ /**
+ * Notifies the configured recipients of some event
+ *
+ * @param context the context that is relevant for this notification
+ * @param subject the subject of the message
+ * @param message the message to be provided to recipients
+ */
+ void notify(NotificationContext context, String subject, String message) throws NotificationFailedException;
+
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationType.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationType.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationType.java
index 26d90da..a2645ec 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationType.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationType.java
@@ -1,23 +1,23 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-public enum NotificationType {
- NIFI_STARTED,
- NIFI_STOPPED,
- NIFI_DIED;
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+public enum NotificationType {
+ NIFI_STARTED,
+ NIFI_STOPPED,
+ NIFI_DIED;
+}
http://git-wip-us.apache.org/repos/asf/nifi/blob/e2d3d1b7/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java
----------------------------------------------------------------------
diff --git a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java
index 8f556da..a02b108 100644
--- a/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java
+++ b/nifi-bootstrap/src/main/java/org/apache/nifi/bootstrap/notification/NotificationValidationContext.java
@@ -1,105 +1,105 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.nifi.bootstrap.notification;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.nifi.attribute.expression.language.Query;
-import org.apache.nifi.attribute.expression.language.Query.Range;
-import org.apache.nifi.attribute.expression.language.StandardExpressionLanguageCompiler;
-import org.apache.nifi.bootstrap.NotificationServicePropertyValue;
-import org.apache.nifi.components.PropertyDescriptor;
-import org.apache.nifi.components.PropertyValue;
-import org.apache.nifi.components.ValidationContext;
-import org.apache.nifi.controller.ControllerService;
-import org.apache.nifi.controller.ControllerServiceLookup;
-import org.apache.nifi.expression.ExpressionLanguageCompiler;
-
-public class NotificationValidationContext implements ValidationContext {
- private final NotificationContext context;
- private final Map<String, Boolean> expressionLanguageSupported;
-
- public NotificationValidationContext(final NotificationContext processContext) {
- this.context = processContext;
-
- final Map<PropertyDescriptor, String> properties = processContext.getProperties();
- expressionLanguageSupported = new HashMap<>(properties.size());
- for (final PropertyDescriptor descriptor : properties.keySet()) {
- expressionLanguageSupported.put(descriptor.getName(), descriptor.isExpressionLanguageSupported());
- }
- }
-
-
- @Override
- public PropertyValue newPropertyValue(final String rawValue) {
- return new NotificationServicePropertyValue(rawValue);
- }
-
- @Override
- public ExpressionLanguageCompiler newExpressionLanguageCompiler() {
- return new StandardExpressionLanguageCompiler();
- }
-
- @Override
- public ValidationContext getControllerServiceValidationContext(final ControllerService controllerService) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public PropertyValue getProperty(final PropertyDescriptor property) {
- return context.getProperty(property);
- }
-
- @Override
- public Map<PropertyDescriptor, String> getProperties() {
- return context.getProperties();
- }
-
- @Override
- public String getAnnotationData() {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public ControllerServiceLookup getControllerServiceLookup() {
- return null;
- }
-
- @Override
- public boolean isValidationRequired(final ControllerService service) {
- return true;
- }
-
- @Override
- public boolean isExpressionLanguagePresent(final String value) {
- if (value == null) {
- return false;
- }
-
- final List<Range> elRanges = Query.extractExpressionRanges(value);
- return (elRanges != null && !elRanges.isEmpty());
- }
-
- @Override
- public boolean isExpressionLanguageSupported(final String propertyName) {
- final Boolean supported = expressionLanguageSupported.get(propertyName);
- return Boolean.TRUE.equals(supported);
- }
-
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.bootstrap.notification;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.nifi.attribute.expression.language.Query;
+import org.apache.nifi.attribute.expression.language.Query.Range;
+import org.apache.nifi.attribute.expression.language.StandardExpressionLanguageCompiler;
+import org.apache.nifi.bootstrap.NotificationServicePropertyValue;
+import org.apache.nifi.components.PropertyDescriptor;
+import org.apache.nifi.components.PropertyValue;
+import org.apache.nifi.components.ValidationContext;
+import org.apache.nifi.controller.ControllerService;
+import org.apache.nifi.controller.ControllerServiceLookup;
+import org.apache.nifi.expression.ExpressionLanguageCompiler;
+
+public class NotificationValidationContext implements ValidationContext {
+ private final NotificationContext context;
+ private final Map<String, Boolean> expressionLanguageSupported;
+
+ public NotificationValidationContext(final NotificationContext processContext) {
+ this.context = processContext;
+
+ final Map<PropertyDescriptor, String> properties = processContext.getProperties();
+ expressionLanguageSupported = new HashMap<>(properties.size());
+ for (final PropertyDescriptor descriptor : properties.keySet()) {
+ expressionLanguageSupported.put(descriptor.getName(), descriptor.isExpressionLanguageSupported());
+ }
+ }
+
+
+ @Override
+ public PropertyValue newPropertyValue(final String rawValue) {
+ return new NotificationServicePropertyValue(rawValue);
+ }
+
+ @Override
+ public ExpressionLanguageCompiler newExpressionLanguageCompiler() {
+ return new StandardExpressionLanguageCompiler();
+ }
+
+ @Override
+ public ValidationContext getControllerServiceValidationContext(final ControllerService controllerService) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public PropertyValue getProperty(final PropertyDescriptor property) {
+ return context.getProperty(property);
+ }
+
+ @Override
+ public Map<PropertyDescriptor, String> getProperties() {
+ return context.getProperties();
+ }
+
+ @Override
+ public String getAnnotationData() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public ControllerServiceLookup getControllerServiceLookup() {
+ return null;
+ }
+
+ @Override
+ public boolean isValidationRequired(final ControllerService service) {
+ return true;
+ }
+
+ @Override
+ public boolean isExpressionLanguagePresent(final String value) {
+ if (value == null) {
+ return false;
+ }
+
+ final List<Range> elRanges = Query.extractExpressionRanges(value);
+ return (elRanges != null && !elRanges.isEmpty());
+ }
+
+ @Override
+ public boolean isExpressionLanguageSupported(final String propertyName) {
+ final Boolean supported = expressionLanguageSupported.get(propertyName);
+ return Boolean.TRUE.equals(supported);
+ }
+
+}