mirror of https://github.com/apache/nifi.git
NIFI-5623 Upgraded OkHttp3 to 4.9.1 and updated unit tests
Signed-off-by: Pierre Villard <pierre.villard.fr@gmail.com> This closes #4826.
This commit is contained in:
parent
aa726040c5
commit
f532b3ae1d
|
@ -53,12 +53,12 @@ language governing permissions and limitations under the License. -->
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>mockwebserver</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<version>${okhttp.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- This needs to be here because it is relied upon by the nifi-runtime which starts NiFi. It uses this bootstrap module
|
||||
|
|
|
@ -21,7 +21,9 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.MediaType;
|
||||
|
@ -189,15 +191,20 @@ public class HttpNotificationService extends AbstractNotificationService {
|
|||
// check if the keystore is set and add the factory if so
|
||||
if (url.toLowerCase().startsWith("https")) {
|
||||
try {
|
||||
TlsConfiguration tlsConfiguration = createTlsConfigurationFromContext(context);
|
||||
final SSLSocketFactory sslSocketFactory = SslContextFactory.createSSLSocketFactory(tlsConfiguration);
|
||||
final TlsConfiguration tlsConfiguration = createTlsConfigurationFromContext(context);
|
||||
final X509TrustManager x509TrustManager = SslContextFactory.getX509TrustManager(tlsConfiguration);
|
||||
if (sslSocketFactory != null && x509TrustManager != null) {
|
||||
okHttpClientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager);
|
||||
} else {
|
||||
// If the TLS config couldn't be parsed, throw an exception
|
||||
throw new IllegalStateException("The HTTP notification service URL indicates HTTPS but the TLS properties are not valid");
|
||||
if (x509TrustManager == null) {
|
||||
throw new IllegalStateException("Unable to get X.509 Trust Manager for HTTP Notification Service configured for TLS");
|
||||
}
|
||||
|
||||
final TrustManager[] trustManagers = new TrustManager[] { x509TrustManager };
|
||||
final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration, trustManagers);
|
||||
if (sslContext == null) {
|
||||
throw new IllegalStateException("Unable to get SSL Context for HTTP Notification Service configured for TLS");
|
||||
}
|
||||
|
||||
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||
okHttpClientBuilder.sslSocketFactory(sslSocketFactory, x509TrustManager);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
@ -214,13 +221,13 @@ public class HttpNotificationService extends AbstractNotificationService {
|
|||
String truststorePath = context.getProperty(HttpNotificationService.PROP_TRUSTSTORE).getValue();
|
||||
String truststorePassword = context.getProperty(HttpNotificationService.PROP_TRUSTSTORE_PASSWORD).getValue();
|
||||
String truststoreType = context.getProperty(HttpNotificationService.PROP_TRUSTSTORE_TYPE).getValue();
|
||||
return new StandardTlsConfiguration(keystorePath, keystorePassword, keyPassword, keystoreType, truststorePath, truststorePassword, truststoreType);
|
||||
return new StandardTlsConfiguration(keystorePath, keystorePassword, keyPassword, keystoreType, truststorePath, truststorePassword, truststoreType, TlsConfiguration.TLS_PROTOCOL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(NotificationContext context, NotificationType notificationType, String subject, String message) throws NotificationFailedException {
|
||||
try {
|
||||
final RequestBody requestBody = RequestBody.create(MediaType.parse("text/plain"), message);
|
||||
final RequestBody requestBody = RequestBody.create(message, MediaType.parse("text/plain"));
|
||||
|
||||
Request.Builder requestBuilder = new Request.Builder()
|
||||
.post(requestBody)
|
||||
|
|
|
@ -0,0 +1,242 @@
|
|||
/*
|
||||
* 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.http;
|
||||
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import okhttp3.mockwebserver.RecordedRequest;
|
||||
import okio.Buffer;
|
||||
import org.apache.nifi.attribute.expression.language.StandardPropertyValue;
|
||||
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.http.HttpNotificationService;
|
||||
import org.apache.nifi.components.PropertyDescriptor;
|
||||
import org.apache.nifi.components.PropertyValue;
|
||||
import org.apache.nifi.security.util.KeyStoreUtils;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_URL;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_CONNECTION_TIMEOUT;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_WRITE_TIMEOUT;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_KEYSTORE;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_KEYSTORE_PASSWORD;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_KEYSTORE_TYPE;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_KEY_PASSWORD;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_TRUSTSTORE;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_TRUSTSTORE_PASSWORD;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.PROP_TRUSTSTORE_TYPE;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.NOTIFICATION_SUBJECT_KEY;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.NOTIFICATION_TYPE_KEY;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
public class HttpNotificationServiceTest {
|
||||
|
||||
private static final long REQUEST_TIMEOUT = 2;
|
||||
|
||||
private static final String SUBJECT = "Subject";
|
||||
|
||||
private static final String MESSAGE = "Message";
|
||||
|
||||
private static final String LOCALHOST = "localhost";
|
||||
|
||||
private static final String BASE_PATH = "/";
|
||||
|
||||
private static final String TIMEOUT = "10s";
|
||||
|
||||
private MockWebServer mockWebServer;
|
||||
|
||||
@Before
|
||||
public void startServer() {
|
||||
mockWebServer = new MockWebServer();
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdownServer() throws IOException {
|
||||
mockWebServer.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotification() throws InterruptedException, NotificationFailedException {
|
||||
enqueueResponseCode(200);
|
||||
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
|
||||
final HttpNotificationService service = getHttpNotificationService(properties);
|
||||
service.notify(getNotificationContext(), NotificationType.NIFI_STARTED, SUBJECT, MESSAGE);
|
||||
|
||||
assertRequestMatches(NotificationType.NIFI_STARTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopNotification() throws InterruptedException, NotificationFailedException {
|
||||
enqueueResponseCode(200);
|
||||
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
|
||||
final HttpNotificationService service = getHttpNotificationService(properties);
|
||||
service.notify(getNotificationContext(), NotificationType.NIFI_STOPPED, SUBJECT, MESSAGE);
|
||||
|
||||
assertRequestMatches(NotificationType.NIFI_STOPPED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiedNotification() throws InterruptedException, NotificationFailedException {
|
||||
enqueueResponseCode(200);
|
||||
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
|
||||
final HttpNotificationService service = getHttpNotificationService(properties);
|
||||
service.notify(getNotificationContext(), NotificationType.NIFI_DIED, SUBJECT, MESSAGE);
|
||||
|
||||
assertRequestMatches(NotificationType.NIFI_DIED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationFailure() throws InterruptedException {
|
||||
enqueueResponseCode(500);
|
||||
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
|
||||
final HttpNotificationService service = getHttpNotificationService(properties);
|
||||
assertThrows(NotificationFailedException.class, () -> service.notify(getNotificationContext(), NotificationType.NIFI_STARTED, SUBJECT, MESSAGE));
|
||||
|
||||
assertRequestMatches(NotificationType.NIFI_STARTED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationHttps() throws GeneralSecurityException, NotificationFailedException, InterruptedException, IOException {
|
||||
final TlsConfiguration tlsConfiguration = KeyStoreUtils.createTlsConfigAndNewKeystoreTruststore();
|
||||
|
||||
try {
|
||||
final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration);
|
||||
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||
mockWebServer.useHttps(sslSocketFactory, false);
|
||||
|
||||
enqueueResponseCode(200);
|
||||
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
|
||||
|
||||
properties.put(PROP_KEYSTORE, createPropertyValue(tlsConfiguration.getKeystorePath()));
|
||||
properties.put(PROP_KEYSTORE_PASSWORD, createPropertyValue(tlsConfiguration.getKeystorePassword()));
|
||||
properties.put(PROP_KEY_PASSWORD, createPropertyValue(tlsConfiguration.getKeyPassword()));
|
||||
properties.put(PROP_KEYSTORE_TYPE, createPropertyValue(tlsConfiguration.getKeystoreType().getType()));
|
||||
properties.put(PROP_TRUSTSTORE, createPropertyValue(tlsConfiguration.getTruststorePath()));
|
||||
properties.put(PROP_TRUSTSTORE_PASSWORD, createPropertyValue(tlsConfiguration.getTruststorePassword()));
|
||||
properties.put(PROP_TRUSTSTORE_TYPE, createPropertyValue(tlsConfiguration.getTruststoreType().getType()));
|
||||
|
||||
final HttpNotificationService service = getHttpNotificationService(properties);
|
||||
service.notify(getNotificationContext(), NotificationType.NIFI_STARTED, SUBJECT, MESSAGE);
|
||||
|
||||
assertRequestMatches(NotificationType.NIFI_STARTED);
|
||||
} finally {
|
||||
Files.deleteIfExists(Paths.get(tlsConfiguration.getKeystorePath()));
|
||||
Files.deleteIfExists(Paths.get(tlsConfiguration.getTruststorePath()));
|
||||
}
|
||||
}
|
||||
|
||||
private void assertRequestMatches(final NotificationType notificationType) throws InterruptedException {
|
||||
final RecordedRequest recordedRequest = mockWebServer.takeRequest(REQUEST_TIMEOUT, TimeUnit.SECONDS);
|
||||
assertNotNull(recordedRequest);
|
||||
assertEquals(notificationType.name(), recordedRequest.getHeader(NOTIFICATION_TYPE_KEY));
|
||||
assertEquals(SUBJECT, recordedRequest.getHeader(NOTIFICATION_SUBJECT_KEY));
|
||||
|
||||
final Buffer bodyBuffer = recordedRequest.getBody();
|
||||
final String bodyString = new String(bodyBuffer.readByteArray(), UTF_8);
|
||||
assertEquals(MESSAGE, bodyString);
|
||||
}
|
||||
|
||||
private void enqueueResponseCode(final int responseCode) {
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(responseCode));
|
||||
}
|
||||
|
||||
private HttpNotificationService getHttpNotificationService(final Map<PropertyDescriptor, PropertyValue> properties) {
|
||||
final HttpNotificationService service = new HttpNotificationService();
|
||||
final NotificationInitializationContext context = new NotificationInitializationContext() {
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return NotificationInitializationContext.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyValue getProperty(final PropertyDescriptor descriptor) {
|
||||
return properties.get(descriptor);
|
||||
}
|
||||
|
||||
@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 Map<PropertyDescriptor, PropertyValue> getProperties() {
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = new HashMap<>();
|
||||
|
||||
// Setting localhost is necessary to avoid hostname verification failures on Windows
|
||||
final String url = mockWebServer.url(BASE_PATH).newBuilder().host(LOCALHOST).build().toString();
|
||||
properties.put(PROP_URL, createPropertyValue(url));
|
||||
properties.put(PROP_CONNECTION_TIMEOUT, createPropertyValue(TIMEOUT));
|
||||
properties.put(PROP_WRITE_TIMEOUT, createPropertyValue(TIMEOUT));
|
||||
|
||||
return properties;
|
||||
}
|
||||
|
||||
private PropertyValue createPropertyValue(final String value) {
|
||||
return new StandardPropertyValue(value, null, null);
|
||||
}
|
||||
|
||||
private NotificationContext getNotificationContext() {
|
||||
final Map<PropertyDescriptor, PropertyValue> properties = getProperties();
|
||||
return new NotificationContext() {
|
||||
@Override
|
||||
public PropertyValue getProperty(final PropertyDescriptor descriptor) {
|
||||
return properties.get(descriptor);
|
||||
}
|
||||
|
||||
@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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,61 +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.
|
||||
*/
|
||||
package org.apache.nifi.bootstrap.http;
|
||||
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.BeforeClass;
|
||||
import org.mockito.internal.util.io.IOUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class TestHttpNotificationService extends TestHttpNotificationServiceCommon{
|
||||
|
||||
|
||||
static final String CONFIGURATION_FILE_TEXT = "\n"+
|
||||
"<services>\n"+
|
||||
" <service>\n"+
|
||||
" <id>http-notification</id>\n"+
|
||||
" <class>org.apache.nifi.bootstrap.notification.http.HttpNotificationService</class>\n"+
|
||||
" <property name=\"URL\">${test.server}</property>\n"+
|
||||
" <property name=\"testProp\">${literal('testing')}</property>\n"+
|
||||
" </service>\n"+
|
||||
"</services>";
|
||||
|
||||
|
||||
@BeforeClass
|
||||
public static void startServer() throws IOException {
|
||||
tempConfigFilePath = "./target/TestHttpNotificationService-config.xml";
|
||||
|
||||
Files.deleteIfExists(Paths.get(tempConfigFilePath));
|
||||
|
||||
mockWebServer = new MockWebServer();
|
||||
|
||||
String configFileOutput = CONFIGURATION_FILE_TEXT.replace("${test.server}", String.valueOf(mockWebServer.url("/")));
|
||||
IOUtil.writeText(configFileOutput, new File(tempConfigFilePath));
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void shutdownServer() throws IOException {
|
||||
Files.deleteIfExists(Paths.get(tempConfigFilePath));
|
||||
mockWebServer.shutdown();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,128 +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.
|
||||
*/
|
||||
package org.apache.nifi.bootstrap.http;
|
||||
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import okhttp3.mockwebserver.RecordedRequest;
|
||||
import okio.Buffer;
|
||||
import org.apache.nifi.bootstrap.NotificationServiceManager;
|
||||
import org.apache.nifi.bootstrap.notification.NotificationType;
|
||||
import org.junit.Test;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.NOTIFICATION_SUBJECT_KEY;
|
||||
import static org.apache.nifi.bootstrap.notification.http.HttpNotificationService.NOTIFICATION_TYPE_KEY;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
public abstract class TestHttpNotificationServiceCommon {
|
||||
|
||||
public static String tempConfigFilePath;
|
||||
public static MockWebServer mockWebServer;
|
||||
|
||||
@Test
|
||||
public void testStartNotification() throws ParserConfigurationException, SAXException, IOException, InterruptedException {
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(200));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
notificationServiceManager.registerNotificationService(NotificationType.NIFI_STARTED, "http-notification");
|
||||
notificationServiceManager.notify(NotificationType.NIFI_STARTED, "Subject", "Message");
|
||||
|
||||
RecordedRequest recordedRequest = mockWebServer.takeRequest(2, TimeUnit.SECONDS);
|
||||
assertNotNull(recordedRequest);
|
||||
assertEquals(NotificationType.NIFI_STARTED.name(), recordedRequest.getHeader(NOTIFICATION_TYPE_KEY));
|
||||
assertEquals("Subject", recordedRequest.getHeader(NOTIFICATION_SUBJECT_KEY));
|
||||
assertEquals("testing", recordedRequest.getHeader("testProp"));
|
||||
|
||||
Buffer bodyBuffer = recordedRequest.getBody();
|
||||
String bodyString =new String(bodyBuffer.readByteArray(), UTF_8);
|
||||
assertEquals("Message", bodyString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStopNotification() throws ParserConfigurationException, SAXException, IOException, InterruptedException {
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(200));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
notificationServiceManager.registerNotificationService(NotificationType.NIFI_STOPPED, "http-notification");
|
||||
notificationServiceManager.notify(NotificationType.NIFI_STOPPED, "Subject", "Message");
|
||||
|
||||
RecordedRequest recordedRequest = mockWebServer.takeRequest(2, TimeUnit.SECONDS);
|
||||
assertNotNull(recordedRequest);
|
||||
assertEquals(NotificationType.NIFI_STOPPED.name(), recordedRequest.getHeader(NOTIFICATION_TYPE_KEY));
|
||||
assertEquals("Subject", recordedRequest.getHeader(NOTIFICATION_SUBJECT_KEY));
|
||||
|
||||
Buffer bodyBuffer = recordedRequest.getBody();
|
||||
String bodyString =new String(bodyBuffer.readByteArray(), UTF_8);
|
||||
assertEquals("Message", bodyString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDiedNotification() throws ParserConfigurationException, SAXException, IOException, InterruptedException {
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(200));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
notificationServiceManager.registerNotificationService(NotificationType.NIFI_DIED, "http-notification");
|
||||
notificationServiceManager.notify(NotificationType.NIFI_DIED, "Subject", "Message");
|
||||
|
||||
RecordedRequest recordedRequest = mockWebServer.takeRequest(2, TimeUnit.SECONDS);
|
||||
assertNotNull(recordedRequest);
|
||||
|
||||
assertEquals(NotificationType.NIFI_DIED.name(), recordedRequest.getHeader(NOTIFICATION_TYPE_KEY));
|
||||
assertEquals("Subject", recordedRequest.getHeader(NOTIFICATION_SUBJECT_KEY));
|
||||
|
||||
Buffer bodyBuffer = recordedRequest.getBody();
|
||||
String bodyString =new String(bodyBuffer.readByteArray(), UTF_8);
|
||||
assertEquals("Message", bodyString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationFailure() throws ParserConfigurationException, SAXException, IOException, InterruptedException {
|
||||
// Web server will still get the request but will return an error. Observe that it is gracefully handled.
|
||||
|
||||
mockWebServer.enqueue(new MockResponse().setResponseCode(500));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
notificationServiceManager.registerNotificationService(NotificationType.NIFI_STARTED, "http-notification");
|
||||
notificationServiceManager.notify(NotificationType.NIFI_STARTED, "Subject", "Message");
|
||||
|
||||
RecordedRequest recordedRequest = mockWebServer.takeRequest(2, TimeUnit.SECONDS);
|
||||
assertNotNull(recordedRequest);
|
||||
assertEquals(NotificationType.NIFI_STARTED.name(), recordedRequest.getHeader(NOTIFICATION_TYPE_KEY));
|
||||
assertEquals("Subject", recordedRequest.getHeader(NOTIFICATION_SUBJECT_KEY));
|
||||
|
||||
Buffer bodyBuffer = recordedRequest.getBody();
|
||||
String bodyString =new String(bodyBuffer.readByteArray(), UTF_8);
|
||||
assertEquals("Message", bodyString);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,252 +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.
|
||||
*/
|
||||
package org.apache.nifi.bootstrap.http;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.read.ListAppender;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.List;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import org.apache.nifi.bootstrap.NotificationServiceManager;
|
||||
import org.apache.nifi.security.util.SslContextFactory;
|
||||
import org.apache.nifi.security.util.StandardTlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsConfiguration;
|
||||
import org.apache.nifi.security.util.TlsException;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.internal.util.io.IOUtil;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
public class TestHttpNotificationServiceSSL extends TestHttpNotificationServiceCommon {
|
||||
|
||||
static final String CONFIGURATION_FILE_TEXT = "\n" +
|
||||
"<services>\n" +
|
||||
" <service>\n" +
|
||||
" <id>http-notification</id>\n" +
|
||||
" <class>org.apache.nifi.bootstrap.notification.http.HttpNotificationService</class>\n" +
|
||||
" <property name=\"URL\">${test.server}</property>\n" +
|
||||
" <property name=\"Truststore Filename\">./src/test/resources/truststore.jks</property>\n" +
|
||||
" <property name=\"Truststore Type\">JKS</property>\n" +
|
||||
" <property name=\"Truststore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Keystore Filename\">./src/test/resources/keystore.jks</property>\n" +
|
||||
" <property name=\"Keystore Type\">JKS</property>\n" +
|
||||
" <property name=\"Key Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Keystore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"testProp\">${literal('testing')}</property>\n" +
|
||||
" </service>\n" +
|
||||
"</services>";
|
||||
|
||||
static final String CONFIGURATION_FILE_TEXT_NO_KEYSTORE_PASSWORD = "\n" +
|
||||
"<services>\n" +
|
||||
" <service>\n" +
|
||||
" <id>http-notification</id>\n" +
|
||||
" <class>org.apache.nifi.bootstrap.notification.http.HttpNotificationService</class>\n" +
|
||||
" <property name=\"URL\">${test.server}</property>\n" +
|
||||
" <property name=\"Truststore Filename\">./src/test/resources/truststore.jks</property>\n" +
|
||||
" <property name=\"Truststore Type\">JKS</property>\n" +
|
||||
" <property name=\"Truststore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Keystore Filename\">./src/test/resources/keystore.jks</property>\n" +
|
||||
" <property name=\"Keystore Type\">JKS</property>\n" +
|
||||
" <property name=\"Key Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"testProp\">${literal('testing')}</property>\n" +
|
||||
" </service>\n" +
|
||||
"</services>";
|
||||
|
||||
static final String CONFIGURATION_FILE_TEXT_NO_KEY_PASSWORD = "\n" +
|
||||
"<services>\n" +
|
||||
" <service>\n" +
|
||||
" <id>http-notification</id>\n" +
|
||||
" <class>org.apache.nifi.bootstrap.notification.http.HttpNotificationService</class>\n" +
|
||||
" <property name=\"URL\">${test.server}</property>\n" +
|
||||
" <property name=\"Truststore Filename\">./src/test/resources/truststore.jks</property>\n" +
|
||||
" <property name=\"Truststore Type\">JKS</property>\n" +
|
||||
" <property name=\"Truststore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Keystore Filename\">./src/test/resources/keystore.jks</property>\n" +
|
||||
" <property name=\"Keystore Type\">JKS</property>\n" +
|
||||
" <property name=\"Keystore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"testProp\">${literal('testing')}</property>\n" +
|
||||
" </service>\n" +
|
||||
"</services>";
|
||||
|
||||
static final String CONFIGURATION_FILE_TEXT_BLANK_KEY_PASSWORD = "\n" +
|
||||
"<services>\n" +
|
||||
" <service>\n" +
|
||||
" <id>http-notification</id>\n" +
|
||||
" <class>org.apache.nifi.bootstrap.notification.http.HttpNotificationService</class>\n" +
|
||||
" <property name=\"URL\">${test.server}</property>\n" +
|
||||
" <property name=\"Truststore Filename\">./src/test/resources/truststore.jks</property>\n" +
|
||||
" <property name=\"Truststore Type\">JKS</property>\n" +
|
||||
" <property name=\"Truststore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Keystore Filename\">./src/test/resources/keystore.jks</property>\n" +
|
||||
" <property name=\"Keystore Type\">JKS</property>\n" +
|
||||
" <property name=\"Keystore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Key Password\"></property>\n" +
|
||||
" <property name=\"testProp\">${literal('testing')}</property>\n" +
|
||||
" </service>\n" +
|
||||
"</services>";
|
||||
|
||||
static final String CONFIGURATION_FILE_TEXT_BLANK_KEYSTORE_PASSWORD = "\n" +
|
||||
"<services>\n" +
|
||||
" <service>\n" +
|
||||
" <id>http-notification</id>\n" +
|
||||
" <class>org.apache.nifi.bootstrap.notification.http.HttpNotificationService</class>\n" +
|
||||
" <property name=\"URL\">${test.server}</property>\n" +
|
||||
" <property name=\"Truststore Filename\">./src/test/resources/truststore.jks</property>\n" +
|
||||
" <property name=\"Truststore Type\">JKS</property>\n" +
|
||||
" <property name=\"Truststore Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"Keystore Filename\">./src/test/resources/keystore.jks</property>\n" +
|
||||
" <property name=\"Keystore Type\">JKS</property>\n" +
|
||||
" <property name=\"Keystore Password\"></property>\n" +
|
||||
" <property name=\"Key Password\">passwordpassword</property>\n" +
|
||||
" <property name=\"testProp\">${literal('testing')}</property>\n" +
|
||||
" </service>\n" +
|
||||
"</services>";
|
||||
|
||||
@Before
|
||||
public void startServer() throws IOException, TlsException {
|
||||
tempConfigFilePath = "./target/TestHttpNotificationService-config.xml";
|
||||
|
||||
Files.deleteIfExists(Paths.get(tempConfigFilePath));
|
||||
|
||||
mockWebServer = new MockWebServer();
|
||||
|
||||
TlsConfiguration tlsConfiguration = new StandardTlsConfiguration("./src/test/resources/keystore.jks", "passwordpassword", null, "JKS",
|
||||
"./src/test/resources/truststore.jks", "passwordpassword", "JKS", TlsConfiguration.getHighestCurrentSupportedTlsProtocolVersion());
|
||||
final SSLContext sslContext = SslContextFactory.createSslContext(tlsConfiguration);
|
||||
mockWebServer.useHttps(sslContext.getSocketFactory(), false);
|
||||
|
||||
String configFileOutput = CONFIGURATION_FILE_TEXT.replace("${test.server}", String.valueOf(mockWebServer.url("/")));
|
||||
IOUtil.writeText(configFileOutput, new File(tempConfigFilePath));
|
||||
}
|
||||
|
||||
@After
|
||||
public void shutdownServer() throws IOException {
|
||||
Files.deleteIfExists(Paths.get(tempConfigFilePath));
|
||||
mockWebServer.shutdown();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationSucceedsNoKeystorePasswd() throws ParserConfigurationException, SAXException, IOException {
|
||||
Logger notificationServiceLogger = (Logger) LoggerFactory.getLogger(NotificationServiceManager.class);
|
||||
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
|
||||
listAppender.start();
|
||||
notificationServiceLogger.addAppender(listAppender);
|
||||
|
||||
String configFileOutput = CONFIGURATION_FILE_TEXT_NO_KEYSTORE_PASSWORD.replace("${test.server}", String.valueOf(mockWebServer.url("/")));
|
||||
IOUtil.writeText(configFileOutput, new File(tempConfigFilePath));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
|
||||
List<ILoggingEvent> logsList = listAppender.list;
|
||||
boolean notificationServiceFailed = false;
|
||||
for (ILoggingEvent logMessage : logsList) {
|
||||
if (logMessage.getFormattedMessage().contains("is not valid for the following reasons")) {
|
||||
notificationServiceFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertFalse(notificationServiceFailed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationSucceedsNoKeyPasswd() throws ParserConfigurationException, SAXException, IOException {
|
||||
Logger notificationServiceLogger = (Logger) LoggerFactory.getLogger(NotificationServiceManager.class);
|
||||
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
|
||||
listAppender.start();
|
||||
notificationServiceLogger.addAppender(listAppender);
|
||||
|
||||
String configFileOutput = CONFIGURATION_FILE_TEXT_NO_KEY_PASSWORD.replace("${test.server}", String.valueOf(mockWebServer.url("/")));
|
||||
IOUtil.writeText(configFileOutput, new File(tempConfigFilePath));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
|
||||
List<ILoggingEvent> logsList = listAppender.list;
|
||||
boolean notificationServiceFailed = false;
|
||||
for (ILoggingEvent logMessage : logsList) {
|
||||
if (logMessage.getFormattedMessage().contains("is not valid for the following reasons")) {
|
||||
notificationServiceFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertFalse(notificationServiceFailed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationFailsBlankKeystorePasswdCorrectKeypasswd() throws ParserConfigurationException, SAXException, IOException {
|
||||
Logger notificationServiceLogger = (Logger) LoggerFactory.getLogger(NotificationServiceManager.class);
|
||||
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
|
||||
listAppender.start();
|
||||
notificationServiceLogger.addAppender(listAppender);
|
||||
|
||||
String configFileOutput = CONFIGURATION_FILE_TEXT_BLANK_KEYSTORE_PASSWORD.replace("${test.server}", String.valueOf(mockWebServer.url("/")));
|
||||
IOUtil.writeText(configFileOutput, new File(tempConfigFilePath));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
|
||||
List<ILoggingEvent> logsList = listAppender.list;
|
||||
boolean notificationServiceFailed = false;
|
||||
for (ILoggingEvent logMessage : logsList) {
|
||||
if (logMessage.getFormattedMessage().contains("'Keystore Password' validated against '' is invalid because Keystore Password cannot be empty")) {
|
||||
notificationServiceFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(notificationServiceFailed);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartNotificationFailsCorrectKeystorePasswdBlankKeypasswd() throws ParserConfigurationException, SAXException, IOException {
|
||||
Logger notificationServiceLogger = (Logger) LoggerFactory.getLogger(NotificationServiceManager.class);
|
||||
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
|
||||
listAppender.start();
|
||||
notificationServiceLogger.addAppender(listAppender);
|
||||
|
||||
String configFileOutput = CONFIGURATION_FILE_TEXT_BLANK_KEY_PASSWORD.replace("${test.server}", String.valueOf(mockWebServer.url("/")));
|
||||
IOUtil.writeText(configFileOutput, new File(tempConfigFilePath));
|
||||
|
||||
NotificationServiceManager notificationServiceManager = new NotificationServiceManager();
|
||||
notificationServiceManager.setMaxNotificationAttempts(1);
|
||||
notificationServiceManager.loadNotificationServices(new File(tempConfigFilePath));
|
||||
|
||||
List<ILoggingEvent> logsList = listAppender.list;
|
||||
boolean notificationServiceFailed = false;
|
||||
for (ILoggingEvent logMessage : logsList) {
|
||||
if (logMessage.getFormattedMessage().contains("'Key Password' validated against '' is invalid because Key Password cannot be empty")) {
|
||||
notificationServiceFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
assertTrue(notificationServiceFailed);
|
||||
}
|
||||
}
|
Binary file not shown.
Binary file not shown.
|
@ -94,7 +94,7 @@
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.14.4</version>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -107,7 +107,7 @@ language governing permissions and limitations under the License. -->
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.14.4</version>
|
||||
<version>4.9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
|
|
|
@ -128,7 +128,7 @@
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.10.0</version>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- spring dependencies -->
|
||||
|
|
|
@ -158,8 +158,6 @@ class OkHttpReplicationClientTest extends GroovyTestCase {
|
|||
|
||||
// Assert
|
||||
assert client.isTLSConfigured()
|
||||
assert client.okHttpClient.sslSocketFactory
|
||||
assert client.okHttpClient.sslSocketFactory.context.getX509KeyManager().credentialsMap["nifi-key"]
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -183,8 +181,6 @@ class OkHttpReplicationClientTest extends GroovyTestCase {
|
|||
|
||||
// Assert
|
||||
assert client.isTLSConfigured()
|
||||
assert client.okHttpClient.sslSocketFactory
|
||||
assert client.okHttpClient.sslSocketFactory.context.getX509KeyManager().credentialsMap["nifi-key"]
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -260,7 +260,7 @@
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>4.9.0</version>
|
||||
<version>4.9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.burgstaller</groupId>
|
||||
|
|
|
@ -79,7 +79,7 @@
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.10.0</version>
|
||||
<version>4.9.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
|
|
|
@ -74,7 +74,7 @@
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.14.4</version>
|
||||
<version>4.9.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -21,7 +21,7 @@ language governing permissions and limitations under the License. -->
|
|||
<artifactId>nifi-toolkit-api</artifactId>
|
||||
|
||||
<properties>
|
||||
<okhttp-version>2.7.5</okhttp-version>
|
||||
<okhttp.version>2.7.5</okhttp.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -44,12 +44,12 @@ language governing permissions and limitations under the License. -->
|
|||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>${okhttp-version}</version>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp</groupId>
|
||||
<artifactId>logging-interceptor</artifactId>
|
||||
<version>${okhttp-version}</version>
|
||||
<version>${okhttp.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
|
|
1
pom.xml
1
pom.xml
|
@ -88,6 +88,7 @@
|
|||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<inceptionYear>2014</inceptionYear>
|
||||
<okhttp.version>4.9.1</okhttp.version>
|
||||
<org.bouncycastle.version>1.68</org.bouncycastle.version>
|
||||
<org.slf4j.version>1.7.30</org.slf4j.version>
|
||||
<ranger.version>2.1.0</ranger.version>
|
||||
|
|
Loading…
Reference in New Issue