NIFI-9601 Upgraded nifi-bootstrap to Jakarta Mail 2

Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com>

This closes #5686.
This commit is contained in:
exceptionfactory 2022-01-19 15:10:47 -06:00 committed by Pierre Villard
parent fc27b3138b
commit c42cc61f71
No known key found for this signature in database
GPG Key ID: F92A93B30C07C6D5
5 changed files with 144 additions and 125 deletions

View File

@ -58,9 +58,14 @@ language governing permissions and limitations under the License. -->
<scope>runtime</scope> <scope>runtime</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>javax.mail</groupId> <groupId>jakarta.mail</groupId>
<artifactId>mail</artifactId> <artifactId>jakarta.mail-api</artifactId>
<version>1.4.7</version> <version>2.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>jakarta.mail</artifactId>
<version>2.0.1</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.nifi</groupId> <groupId>org.apache.nifi</groupId>
@ -85,5 +90,11 @@ language governing permissions and limitations under the License. -->
<artifactId>nifi-properties-loader</artifactId> <artifactId>nifi-properties-loader</artifactId>
<version>1.16.0-SNAPSHOT</version> <version>1.16.0-SNAPSHOT</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.nifi</groupId>
<artifactId>nifi-mock</artifactId>
<version>1.16.0-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -25,16 +25,16 @@ import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Map.Entry; import java.util.Map.Entry;
import javax.mail.Authenticator; import jakarta.mail.Authenticator;
import javax.mail.Message; import jakarta.mail.Message;
import javax.mail.MessagingException; import jakarta.mail.MessagingException;
import javax.mail.PasswordAuthentication; import jakarta.mail.PasswordAuthentication;
import javax.mail.Session; import jakarta.mail.Session;
import javax.mail.Transport; import jakarta.mail.Transport;
import javax.mail.Message.RecipientType; import jakarta.mail.Message.RecipientType;
import javax.mail.internet.AddressException; import jakarta.mail.internet.AddressException;
import javax.mail.internet.InternetAddress; import jakarta.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import jakarta.mail.internet.MimeMessage;
import org.apache.nifi.bootstrap.notification.AbstractNotificationService; import org.apache.nifi.bootstrap.notification.AbstractNotificationService;
import org.apache.nifi.bootstrap.notification.NotificationContext; import org.apache.nifi.bootstrap.notification.NotificationContext;
import org.apache.nifi.bootstrap.notification.NotificationFailedException; import org.apache.nifi.bootstrap.notification.NotificationFailedException;
@ -272,20 +272,18 @@ public class EmailNotificationService extends AbstractNotificationService {
*/ */
private Session createMailSession(final Properties properties) { private Session createMailSession(final Properties properties) {
String authValue = properties.getProperty("mail.smtp.auth"); String authValue = properties.getProperty("mail.smtp.auth");
Boolean auth = Boolean.valueOf(authValue); final boolean auth = Boolean.parseBoolean(authValue);
/* /*
* Conditionally create a password authenticator if the 'auth' parameter is set. * Conditionally create a password authenticator if the 'auth' parameter is set.
*/ */
final Session mailSession = auth ? Session.getInstance(properties, new Authenticator() { return auth ? Session.getInstance(properties, new Authenticator() {
@Override @Override
public PasswordAuthentication getPasswordAuthentication() { public PasswordAuthentication getPasswordAuthentication() {
String username = properties.getProperty("mail.smtp.user"), password = properties.getProperty("mail.smtp.password"); String username = properties.getProperty("mail.smtp.user"), password = properties.getProperty("mail.smtp.password");
return new PasswordAuthentication(username, password); return new PasswordAuthentication(username, password);
} }
}) : Session.getInstance(properties); // without auth }) : Session.getInstance(properties); // without auth
return mailSession;
} }
} }

View File

@ -1,84 +0,0 @@
package org.apache.nifi.bootstrap.notification;
/*
* 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.
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.expression.ExpressionLanguageScope;
import org.apache.nifi.processor.util.StandardValidators;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestCustomNotificationService extends AbstractNotificationService {
private static Logger logger = LoggerFactory.getLogger(TestCustomNotificationService.class);
public static final PropertyDescriptor CUSTOM_HOSTNAME = new PropertyDescriptor.Builder()
.name("Custom Hostname")
.description("The hostname of the Custom Server that is used to send notifications")
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
.required(true)
.build();
public static final PropertyDescriptor CUSTOM_USERNAME = new PropertyDescriptor.Builder()
.name("Custom Username")
.description("Username for the account")
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
.required(false)
.build();
public static final PropertyDescriptor CUSTOM_PASSWORD = new PropertyDescriptor.Builder()
.name("Custom Password")
.description("Password for the account")
.expressionLanguageSupported(ExpressionLanguageScope.VARIABLE_REGISTRY)
.addValidator(StandardValidators.NON_EMPTY_VALIDATOR)
.required(false)
.sensitive(true)
.build();
/**
* Mapping of the mail properties to the NiFi PropertyDescriptors that will be evaluated at runtime
*/
private static final Map<String, PropertyDescriptor> propertyToContext = new HashMap<>();
static {
propertyToContext.put("custom.host", CUSTOM_HOSTNAME);
propertyToContext.put("custom.user", CUSTOM_USERNAME);
propertyToContext.put("custom.password", CUSTOM_PASSWORD);
}
@Override
protected List<PropertyDescriptor> getSupportedPropertyDescriptors() {
final List<PropertyDescriptor> properties = new ArrayList<>();
properties.add(CUSTOM_HOSTNAME);
properties.add(CUSTOM_USERNAME);
properties.add(CUSTOM_PASSWORD);
return properties;
}
@Override
public void notify(NotificationContext context, NotificationType type, String subject, String message) throws NotificationFailedException {
logger.info(context.getProperty(CUSTOM_HOSTNAME).evaluateAttributeExpressions().getValue());
logger.info(context.getProperty(CUSTOM_USERNAME).evaluateAttributeExpressions().getValue());
logger.info(context.getProperty(CUSTOM_PASSWORD).evaluateAttributeExpressions().getValue());
}
}

View File

@ -0,0 +1,118 @@
/*
* 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.email;
import jakarta.mail.MessagingException;
import org.apache.nifi.bootstrap.notification.NotificationContext;
import org.apache.nifi.bootstrap.notification.NotificationFailedException;
import org.apache.nifi.bootstrap.notification.NotificationInitializationContext;
import org.apache.nifi.bootstrap.notification.NotificationType;
import org.apache.nifi.bootstrap.notification.email.EmailNotificationService;
import org.apache.nifi.components.PropertyDescriptor;
import org.apache.nifi.components.PropertyValue;
import org.apache.nifi.remote.io.socket.NetworkUtils;
import org.apache.nifi.util.MockPropertyValue;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class EmailNotificationServiceTest {
private static final String SUBJECT = "Subject";
private static final String MESSAGE = "Message";
private static final String LOCALHOST_ADDRESS = "127.0.0.1";
private static final String ADDRESS = "username@localhost.localdomain";
@Test
public void testNotifyMessagingException() {
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
final EmailNotificationService service = getNotificationService(properties);
final NotificationFailedException exception = assertThrows(NotificationFailedException.class, () -> service.notify(getNotificationContext(), NotificationType.NIFI_STARTED, SUBJECT, MESSAGE));
final Throwable cause = exception.getCause();
assertTrue(cause instanceof MessagingException);
}
private EmailNotificationService getNotificationService(final Map<PropertyDescriptor, PropertyValue> properties) {
final EmailNotificationService service = new EmailNotificationService();
final NotificationInitializationContext context = new NotificationInitializationContext() {
@Override
public String getIdentifier() {
return NotificationInitializationContext.class.getName();
}
@Override
public PropertyValue getProperty(final PropertyDescriptor descriptor) {
final PropertyValue propertyValue = properties.get(descriptor);
return propertyValue == null ? new MockPropertyValue(descriptor.getDefaultValue()) : propertyValue;
}
@Override
public Map<String, String> getAllProperties() {
final Map<String, String> allProperties = new HashMap<>();
for (final Map.Entry<PropertyDescriptor, PropertyValue> entry : properties.entrySet()) {
allProperties.put(entry.getKey().getName(), entry.getValue().getValue());
}
return allProperties;
}
};
service.initialize(context);
return service;
}
private NotificationContext getNotificationContext() {
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
return new NotificationContext() {
@Override
public PropertyValue getProperty(final PropertyDescriptor descriptor) {
final PropertyValue propertyValue = properties.get(descriptor);
return propertyValue == null ? new MockPropertyValue(descriptor.getDefaultValue()) : propertyValue;
}
@Override
public Map<PropertyDescriptor, String> getProperties() {
final Map<PropertyDescriptor, String> propertyValues = new HashMap<>();
for (final Map.Entry<PropertyDescriptor, PropertyValue> entry : properties.entrySet()) {
propertyValues.put(entry.getKey(), entry.getValue().getValue());
}
return propertyValues;
}
};
}
private Map<PropertyDescriptor, PropertyValue> getProperties() {
final Map<PropertyDescriptor, PropertyValue> properties = new HashMap<>();
properties.put(EmailNotificationService.SMTP_HOSTNAME, new MockPropertyValue(LOCALHOST_ADDRESS));
final int port = NetworkUtils.getAvailableTcpPort();
properties.put(EmailNotificationService.SMTP_PORT, new MockPropertyValue(Integer.toString(port)));
properties.put(EmailNotificationService.SMTP_AUTH, new MockPropertyValue(Boolean.FALSE.toString()));
properties.put(EmailNotificationService.FROM, new MockPropertyValue(ADDRESS));
properties.put(EmailNotificationService.TO, new MockPropertyValue(ADDRESS));
return properties;
}
}

View File

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<services>
<service>
<id>custom-notification</id>
<class>org.apache.nifi.bootstrap.notification.TestCustomNotificationService</class>
<property name="Custom Hostname">${test.server}</property>
<property name="Custom Username">${test.username}</property>
<property name="Custom Password">${test.password}</property>
</service>
</services>