You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2016/05/13 19:11:21 UTC
incubator-ranger git commit: RANGER-938 Adding NiFi
service-definition and the NiFiClient for resource lookups
Repository: incubator-ranger
Updated Branches:
refs/heads/master 608776712 -> b64218a34
RANGER-938 Adding NiFi service-definition and the NiFiClient for resource lookups
Signed-off-by: Madhan Neethiraj <ma...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/b64218a3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/b64218a3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/b64218a3
Branch: refs/heads/master
Commit: b64218a347e54aff132f821946de63133258d407
Parents: 6087767
Author: Bryan Bende <bb...@apache.org>
Authored: Thu Mar 31 10:59:17 2016 -0400
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri May 13 11:36:55 2016 -0700
----------------------------------------------------------------------
.../plugin/store/EmbeddedServiceDefsUtil.java | 9 +
.../service-defs/ranger-servicedef-nifi.json | 162 ++++++++++++++
plugin-nifi/.gitignore | 1 +
plugin-nifi/pom.xml | 62 ++++++
.../ranger/services/nifi/RangerServiceNiFi.java | 71 ++++++
.../services/nifi/client/NiFiAuthType.java | 29 +++
.../ranger/services/nifi/client/NiFiClient.java | 217 +++++++++++++++++++
.../services/nifi/client/NiFiConfigs.java | 37 ++++
.../services/nifi/client/NiFiConnectionMgr.java | 157 ++++++++++++++
.../services/nifi/client/TestNiFiClient.java | 196 +++++++++++++++++
.../nifi/client/TestNiFiConnectionMgr.java | 124 +++++++++++
pom.xml | 1 +
src/main/assembly/admin-web.xml | 13 ++
13 files changed, 1079 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
index 7ec8d98..bf29ee6 100755
--- a/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/EmbeddedServiceDefsUtil.java
@@ -60,6 +60,8 @@ public class EmbeddedServiceDefsUtil {
public static final String EMBEDDED_SERVICEDEF_YARN_NAME = "yarn";
public static final String EMBEDDED_SERVICEDEF_KAFKA_NAME = "kafka";
public static final String EMBEDDED_SERVICEDEF_SOLR_NAME = "solr";
+ public static final String EMBEDDED_SERVICEDEF_NIFI_NAME = "nifi";
+
public static final String PROPERTY_CREATE_EMBEDDED_SERVICE_DEFS = "ranger.service.store.create.embedded.service-defs";
public static final String HDFS_IMPL_CLASS_NAME = "org.apache.ranger.services.hdfs.RangerServiceHdfs";
@@ -71,6 +73,7 @@ public class EmbeddedServiceDefsUtil {
public static final String YARN_IMPL_CLASS_NAME = "org.apache.ranger.services.yarn.RangerServiceYarn";
public static final String KAFKA_IMPL_CLASS_NAME = "org.apache.ranger.services.kafka.RangerServiceKafka";
public static final String SOLR_IMPL_CLASS_NAME = "org.apache.ranger.services.solr.RangerServiceSolr";
+ public static final String NIFI_IMPL_CLASS_NAME = "org.apache.ranger.services.nifi.RangerServiceNiFi";
private static EmbeddedServiceDefsUtil instance = new EmbeddedServiceDefsUtil();
@@ -84,6 +87,7 @@ public class EmbeddedServiceDefsUtil {
private RangerServiceDef yarnServiceDef = null;
private RangerServiceDef kafkaServiceDef = null;
private RangerServiceDef solrServiceDef = null;
+ private RangerServiceDef nifiServiceDef = null;
private RangerServiceDef tagServiceDef = null;
@@ -120,6 +124,7 @@ public class EmbeddedServiceDefsUtil {
yarnServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_YARN_NAME);
kafkaServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_KAFKA_NAME);
solrServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_SOLR_NAME);
+ nifiServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_NIFI_NAME);
tagServiceDef = getOrCreateServiceDef(store, EMBEDDED_SERVICEDEF_TAG_NAME);
@@ -168,6 +173,10 @@ public class EmbeddedServiceDefsUtil {
return getId(solrServiceDef);
}
+ public long getNiFiServiceDefId() {
+ return getId(nifiServiceDef);
+ }
+
public long getTagServiceDefId() { return getId(tagServiceDef); }
private long getId(RangerServiceDef serviceDef) {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/agents-common/src/main/resources/service-defs/ranger-servicedef-nifi.json
----------------------------------------------------------------------
diff --git a/agents-common/src/main/resources/service-defs/ranger-servicedef-nifi.json b/agents-common/src/main/resources/service-defs/ranger-servicedef-nifi.json
new file mode 100644
index 0000000..b81785d
--- /dev/null
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-nifi.json
@@ -0,0 +1,162 @@
+{
+ "id":10,
+ "name":"nifi",
+ "implClass":"org.apache.ranger.services.nifi.RangerServiceNiFi",
+ "label":"NIFI",
+ "description":"NiFi",
+ "resources":[
+ {
+ "itemId":100,
+ "name":"nifi-resource",
+ "type":"string",
+ "level":10,
+ "parent":"",
+ "mandatory":true,
+ "lookupSupported":true,
+ "recursiveSupported":false,
+ "excludesSupported":true,
+ "matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+ "matcherOptions":{
+ "wildCard":true,
+ "ignoreCase":true
+ },
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"NiFi Resource Identifier",
+ "description":"NiFi Resource"
+ }
+
+ ],
+ "accessTypes":[
+ {
+ "itemId":100,
+ "name":"READ",
+ "label":"Read"
+ },
+ {
+ "itemId":200,
+ "name":"WRITE",
+ "label":"Write"
+ }
+ ],
+ "configs":[
+ {
+ "itemId":400,
+ "name":"nifi.url",
+ "type":"string",
+ "mandatory":true,
+ "defaultValue":"http://localhost:8080/nifi-api/resources",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"The URL of the NiFi REST API that provides the available resources.",
+ "label":"NiFi URL"
+ },
+ {
+ "itemId": 410,
+ "name": "nifi.authentication",
+ "type": "enum",
+ "subType": "authType",
+ "mandatory": true,
+ "validationRegEx":"",
+ "validationMessage": "",
+ "uiHint":"",
+ "label": "Authentication Type",
+ "defaultValue": "NONE"
+ },
+ {
+ "itemId":500,
+ "name":"nifi.ssl.keystore",
+ "type":"string",
+ "mandatory":false,
+ "defaultValue":"",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"Keystore"
+ },
+ {
+ "itemId":510,
+ "name":"nifi.ssl.keystoreType",
+ "type":"string",
+ "mandatory":false,
+ "defaultValue":"",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"Keystore Type"
+ },
+ {
+ "itemId":520,
+ "name":"nifi.ssl.keystorePassword",
+ "type":"password",
+ "mandatory":false,
+ "defaultValue":"",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"Keystore Password"
+ },
+ {
+ "itemId":530,
+ "name":"nifi.ssl.truststore",
+ "type":"string",
+ "mandatory":false,
+ "defaultValue":"",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"Truststore"
+ },
+ {
+ "itemId":540,
+ "name":"nifi.ssl.truststoreType",
+ "type":"string",
+ "mandatory":false,
+ "defaultValue":"",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"Truststore Type"
+ },
+ {
+ "itemId":550,
+ "name":"nifi.ssl.truststorePassword",
+ "type":"password",
+ "mandatory":false,
+ "defaultValue":"",
+ "validationRegEx":"",
+ "validationMessage":"",
+ "uiHint":"",
+ "label":"Truststore Password"
+ }
+ ],
+ "enums":
+ [
+ {
+ "itemId": 1,
+ "name": "authType",
+ "elements":
+ [
+ {
+ "itemId": 1,
+ "name": "NONE",
+ "label": "None"
+ },
+ {
+ "itemId": 2,
+ "name": "SSL",
+ "label": "SSL"
+ }
+ ],
+
+ "defaultIndex": 0
+ }
+ ],
+ "contextEnrichers":[
+
+ ],
+ "policyConditions":[
+
+ ]
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/.gitignore
----------------------------------------------------------------------
diff --git a/plugin-nifi/.gitignore b/plugin-nifi/.gitignore
new file mode 100644
index 0000000..ea8c4bf
--- /dev/null
+++ b/plugin-nifi/.gitignore
@@ -0,0 +1 @@
+/target
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/pom.xml
----------------------------------------------------------------------
diff --git a/plugin-nifi/pom.xml b/plugin-nifi/pom.xml
new file mode 100644
index 0000000..740b7f9
--- /dev/null
+++ b/plugin-nifi/pom.xml
@@ -0,0 +1,62 @@
+<?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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <artifactId>ranger-nifi-plugin</artifactId>
+ <name>NiFi Security Plugin</name>
+ <description>NiFi Security Plugin</description>
+ <packaging>jar</packaging>
+ <properties>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+ </properties>
+ <parent>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>ranger</artifactId>
+ <version>0.6.0-SNAPSHOT</version>
+ <relativePath>..</relativePath>
+ </parent>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>ranger-plugins-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>ranger-plugins-audit</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>credentialbuilder</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <version>${mockito.version}</version>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/RangerServiceNiFi.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/RangerServiceNiFi.java b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/RangerServiceNiFi.java
new file mode 100644
index 0000000..4f38f42
--- /dev/null
+++ b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/RangerServiceNiFi.java
@@ -0,0 +1,71 @@
+/*
+ * 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.ranger.services.nifi;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.service.RangerBaseService;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.apache.ranger.services.nifi.client.NiFiClient;
+import org.apache.ranger.services.nifi.client.NiFiConnectionMgr;
+
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * RangerService for Apache NiFi.
+ */
+public class RangerServiceNiFi extends RangerBaseService {
+
+ private static final Log LOG = LogFactory.getLog(RangerServiceNiFi.class);
+
+ @Override
+ public HashMap<String, Object> validateConfig() throws Exception {
+ HashMap<String, Object> ret = new HashMap<>();
+ String serviceName = getServiceName();
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("==> RangerServiceNiFi.validateConfig Service: (" + serviceName + " )");
+ }
+
+ if (configs != null) {
+ try {
+ ret = NiFiConnectionMgr.connectionTest(serviceName, configs);
+ } catch (Exception e) {
+ LOG.error("<== RangerServiceNiFi.validateConfig Error:", e);
+ throw e;
+ }
+ } else {
+ throw new IllegalStateException("No Configuration found");
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("<== RangerServiceNiFi.validateConfig Response : (" + ret + " )");
+ }
+
+ return ret;
+ }
+
+ @Override
+ public List<String> lookupResource(ResourceLookupContext context) throws Exception {
+ final NiFiClient client = NiFiConnectionMgr.getNiFiClient(serviceName, configs);
+ return client.getResources(context);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiAuthType.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiAuthType.java b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiAuthType.java
new file mode 100644
index 0000000..47267a4
--- /dev/null
+++ b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiAuthType.java
@@ -0,0 +1,29 @@
+/*
+ * 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.ranger.services.nifi.client;
+
+/**
+ * Possible authentication types for NiFi.
+ */
+public enum NiFiAuthType {
+
+ NONE,
+ SSL
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiClient.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiClient.java b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiClient.java
new file mode 100644
index 0000000..1c21c0e
--- /dev/null
+++ b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiClient.java
@@ -0,0 +1,217 @@
+/*
+ * 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.ranger.services.nifi.client;
+
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.ranger.plugin.client.BaseClient;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.codehaus.jackson.JsonNode;
+import org.codehaus.jackson.map.ObjectMapper;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.ws.rs.core.Response;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateParsingException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Client to communicate with NiFi and retrieve available resources.
+ */
+public class NiFiClient {
+
+ private static final Log LOG = LogFactory.getLog(NiFiClient.class) ;
+
+ static final String SUCCESS_MSG = "ConnectionTest Successful";
+ static final String FAILURE_MSG = "Unable to retrieve any resources using given parameters. ";
+
+ private final String url;
+ private final SSLContext sslContext;
+ private final HostnameVerifier hostnameVerifier;
+ private final ObjectMapper mapper = new ObjectMapper();
+
+ public NiFiClient(final String url, final SSLContext sslContext) {
+ this.url = url;
+ this.sslContext = sslContext;
+ this.hostnameVerifier = new NiFiHostnameVerifier();
+ }
+
+ public HashMap<String, Object> connectionTest() {
+ String errMsg = "";
+ boolean connectivityStatus;
+ HashMap<String, Object> responseData = new HashMap<>();
+
+ try {
+ final WebResource resource = getWebResource();
+ final ClientResponse response = getResponse(resource, "application/json");
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Got response from NiFi with status code " + response.getStatus());
+ }
+
+ if (Response.Status.OK.getStatusCode() == response.getStatus()) {
+ connectivityStatus = true;
+ } else {
+ connectivityStatus = false;
+ errMsg = "Status Code = " + response.getStatus();
+ }
+
+ } catch (Exception e) {
+ LOG.error("Connection to NiFi failed due to " + e.getMessage(), e);
+ connectivityStatus = false;
+ errMsg = e.getMessage();
+ }
+
+ if (connectivityStatus) {
+ BaseClient.generateResponseDataMap(connectivityStatus, SUCCESS_MSG, SUCCESS_MSG, null, null, responseData);
+ } else {
+ BaseClient.generateResponseDataMap(connectivityStatus, FAILURE_MSG, FAILURE_MSG + errMsg, null, null, responseData);
+ }
+
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Response Data - " + responseData);
+ }
+
+ return responseData;
+ }
+
+ public List<String> getResources(ResourceLookupContext context) throws Exception {
+ final WebResource resource = getWebResource();
+ final ClientResponse response = getResponse(resource, "application/json");
+
+ if (Response.Status.OK.getStatusCode() != response.getStatus()) {
+ String errorMsg = IOUtils.toString(response.getEntityInputStream());
+ throw new Exception("Unable to retrieve resources from NiFi due to: " + errorMsg);
+ }
+
+ JsonNode rootNode = mapper.readTree(response.getEntityInputStream());
+ if (rootNode == null) {
+ throw new Exception("Unable to retrieve resources from NiFi");
+ }
+
+ JsonNode resourcesNode = rootNode.findValue("resources");
+ List<String> identifiers = resourcesNode.findValuesAsText("identifier");
+
+ final String userInput = context.getUserInput();
+ if (StringUtils.isBlank(userInput)) {
+ return identifiers;
+ } else {
+ List<String> filteredIdentifiers = new ArrayList<>();
+
+ for (String identifier : identifiers) {
+ if (identifier.contains(userInput)) {
+ filteredIdentifiers.add(identifier);
+ }
+ }
+
+ return filteredIdentifiers;
+ }
+ }
+
+ protected WebResource getWebResource() {
+ final ClientConfig config = new DefaultClientConfig();
+ if (sslContext != null) {
+ config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+ new HTTPSProperties(hostnameVerifier, sslContext));
+ }
+
+ final Client client = Client.create(config);
+ return client.resource(url);
+ }
+
+ protected ClientResponse getResponse(WebResource resource, String accept) {
+ return resource.accept(accept).get(ClientResponse.class);
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ public SSLContext getSslContext() {
+ return sslContext;
+ }
+
+ public HostnameVerifier getHostnameVerifier() {
+ return hostnameVerifier;
+ }
+
+ /**
+ * Custom hostname verifier that checks subject alternative names against the hostname of the URI.
+ */
+ private static class NiFiHostnameVerifier implements HostnameVerifier {
+
+ @Override
+ public boolean verify(final String hostname, final SSLSession ssls) {
+ try {
+ for (final Certificate peerCertificate : ssls.getPeerCertificates()) {
+ if (peerCertificate instanceof X509Certificate) {
+ final X509Certificate x509Cert = (X509Certificate) peerCertificate;
+ final List<String> subjectAltNames = getSubjectAlternativeNames(x509Cert);
+ if (subjectAltNames.contains(hostname.toLowerCase())) {
+ return true;
+ }
+ }
+ }
+ } catch (final SSLPeerUnverifiedException | CertificateParsingException ex) {
+ LOG.warn("Hostname Verification encountered exception verifying hostname due to: " + ex, ex);
+ }
+
+ return false;
+ }
+
+ private List<String> getSubjectAlternativeNames(final X509Certificate certificate) throws CertificateParsingException {
+ final Collection<List<?>> altNames = certificate.getSubjectAlternativeNames();
+ if (altNames == null) {
+ return new ArrayList<>();
+ }
+
+ final List<String> result = new ArrayList<>();
+ for (final List<?> generalName : altNames) {
+ /**
+ * generalName has the name type as the first element a String or byte array for the second element. We return any general names that are String types.
+ *
+ * We don't inspect the numeric name type because some certificates incorrectly put IPs and DNS names under the wrong name types.
+ */
+ final Object value = generalName.get(1);
+ if (value instanceof String) {
+ result.add(((String) value).toLowerCase());
+ }
+
+ }
+
+ return result;
+ }
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConfigs.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConfigs.java b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConfigs.java
new file mode 100644
index 0000000..cc68710
--- /dev/null
+++ b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConfigs.java
@@ -0,0 +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.ranger.services.nifi.client;
+
+/**
+ * Config property names from the NiFi service definition.
+ */
+public interface NiFiConfigs {
+
+ String NIFI_URL = "nifi.url";
+ String NIFI_AUTHENTICATION_TYPE = "nifi.authentication";
+
+ String NIFI_SSL_KEYSTORE = "nifi.ssl.keystore";
+ String NIFI_SSL_KEYSTORE_TYPE = "nifi.ssl.keystoreType";
+ String NIFI_SSL_KEYSTORE_PASSWORD = "nifi.ssl.keystorePassword";
+
+ String NIFI_SSL_TRUSTSTORE = "nifi.ssl.truststore";
+ String NIFI_SSL_TRUSTSTORE_TYPE = "nifi.ssl.truststoreType";
+ String NIFI_SSL_TRUSTSTORE_PASSWORD = "nifi.ssl.truststorePassword";
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConnectionMgr.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConnectionMgr.java b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConnectionMgr.java
new file mode 100644
index 0000000..739bef6
--- /dev/null
+++ b/plugin-nifi/src/main/java/org/apache/ranger/services/nifi/client/NiFiConnectionMgr.java
@@ -0,0 +1,157 @@
+/*
+ * 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.ranger.services.nifi.client;
+
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.security.KeyManagementException;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.UnrecoverableKeyException;
+import java.security.cert.CertificateException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Creates a NiFiClient and provides method to test a connection to NiFi.
+ */
+public class NiFiConnectionMgr {
+
+ private static final Log LOG = LogFactory.getLog(NiFiConnectionMgr.class);
+
+ static final String INVALID_URL_MSG = "NiFi URL must be a valid URL of the form " +
+ "http(s)://<hostname>(:<port>)/nifi-api/resources";
+
+
+ static public NiFiClient getNiFiClient(String serviceName, Map<String, String> configs) throws Exception {
+ final String url = configs.get(NiFiConfigs.NIFI_URL);
+ validateNotBlank(url, "NiFi URL is required for " + serviceName);
+ validateUrl(url);
+
+ final String authTypeStr = configs.get(NiFiConfigs.NIFI_AUTHENTICATION_TYPE);
+ validateNotBlank(authTypeStr, "Authentication Type is required for " + serviceName);
+
+ final NiFiAuthType authType = NiFiAuthType.valueOf(authTypeStr);
+ LOG.debug("NiFiAuthType is " + authType.name());
+
+ SSLContext sslContext = null;
+
+ if (authType == NiFiAuthType.SSL) {
+
+ if (!url.startsWith("https")) {
+ throw new IllegalArgumentException("Authentication Type of SSL requires an https URL");
+ }
+
+ final String keystore = configs.get(NiFiConfigs.NIFI_SSL_KEYSTORE);
+ final String keystoreType = configs.get(NiFiConfigs.NIFI_SSL_KEYSTORE_TYPE);
+ final String keystorePassword = configs.get(NiFiConfigs.NIFI_SSL_KEYSTORE_PASSWORD);
+
+ validateNotBlank(keystore, "Keystore is required for " + serviceName + " with Authentication Type of SSL");
+ validateNotBlank(keystoreType, "Keystore Type is required for " + serviceName + " with Authentication Type of SSL");
+ validateNotBlank(keystorePassword, "Keystore Password is required for " + serviceName + " with Authentication Type of SSL");
+
+ final String truststore = configs.get(NiFiConfigs.NIFI_SSL_TRUSTSTORE);
+ final String truststoreType = configs.get(NiFiConfigs.NIFI_SSL_TRUSTSTORE_TYPE);
+ final String truststorePassword = configs.get(NiFiConfigs.NIFI_SSL_TRUSTSTORE_PASSWORD);
+
+ validateNotBlank(truststore, "Truststore is required for " + serviceName + " with Authentication Type of SSL");
+ validateNotBlank(truststoreType, "Truststore Type is required for " + serviceName + " with Authentication Type of SSL");
+ validateNotBlank(truststorePassword, "Truststore Password is required for " + serviceName + " with Authentication Type of SSL");
+
+ LOG.debug("Creating SSLContext for NiFi connection");
+
+ sslContext = createSslContext(
+ keystore.trim(),
+ keystorePassword.trim().toCharArray(),
+ keystoreType.trim(),
+ truststore.trim(),
+ truststorePassword.trim().toCharArray(),
+ truststoreType.trim(),
+ "TLS");
+ }
+
+ return new NiFiClient(url.trim(), sslContext);
+ }
+
+ public static HashMap<String, Object> connectionTest(String serviceName, Map<String, String> configs) throws Exception {
+ NiFiClient client = getNiFiClient(serviceName, configs);
+ return client.connectionTest();
+ }
+
+ private static void validateNotBlank(final String input, final String message) {
+ if (input == null || input.trim().isEmpty()) {
+ throw new IllegalArgumentException(message);
+ }
+ }
+
+ private static void validateUrl(String url) {
+ URI nifiUri;
+ try {
+ nifiUri = new URI(url);
+ if (!nifiUri.getPath().endsWith("nifi-api/resources")) {
+ throw new IllegalArgumentException(INVALID_URL_MSG);
+ }
+ } catch (URISyntaxException urie) {
+ throw new IllegalArgumentException(INVALID_URL_MSG);
+ }
+ }
+
+ private static SSLContext createSslContext(
+ final String keystore, final char[] keystorePasswd, final String keystoreType,
+ final String truststore, final char[] truststorePasswd, final String truststoreType,
+ final String protocol)
+ throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException,
+ UnrecoverableKeyException, KeyManagementException {
+
+ // prepare the keystore
+ final KeyStore keyStore = KeyStore.getInstance(keystoreType);
+ try (final InputStream keyStoreStream = new FileInputStream(keystore)) {
+ keyStore.load(keyStoreStream, keystorePasswd);
+ }
+ final KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
+ keyManagerFactory.init(keyStore, keystorePasswd);
+
+ // prepare the truststore
+ final KeyStore trustStore = KeyStore.getInstance(truststoreType);
+ try (final InputStream trustStoreStream = new FileInputStream(truststore)) {
+ trustStore.load(trustStoreStream, truststorePasswd);
+ }
+ final TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+ trustManagerFactory.init(trustStore);
+
+ // initialize the ssl context
+ final SSLContext sslContext = SSLContext.getInstance(protocol);
+ sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
+ return sslContext;
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiClient.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiClient.java b/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiClient.java
new file mode 100644
index 0000000..051c940
--- /dev/null
+++ b/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiClient.java
@@ -0,0 +1,196 @@
+/*
+ * 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.ranger.services.nifi.client;
+
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.WebResource;
+import org.apache.ranger.plugin.service.ResourceLookupContext;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import javax.ws.rs.core.Response;
+import java.io.ByteArrayInputStream;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+
+public class TestNiFiClient {
+
+ private static final String RESOURCES_RESPONSE = "{\n" +
+ " \"revision\": {\n" +
+ " \"clientId\": \"0daac173-025c-4aa7-b644-97f7b10435d2\"\n" +
+ " },\n" +
+ " \"resources\": [\n" +
+ " {\n" +
+ " \"identifier\": \"/system\",\n" +
+ " \"name\": \"System\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"identifier\": \"/controller\",\n" +
+ " \"name\": \"Controller\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"identifier\": \"/flow\",\n" +
+ " \"name\": \"NiFi Flow\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"identifier\": \"/provenance\",\n" +
+ " \"name\": \"Provenance\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"identifier\": \"/proxy\",\n" +
+ " \"name\": \"Proxy User Requests\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"identifier\": \"/resources\",\n" +
+ " \"name\": \"NiFi Resources\"\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+
+ private NiFiClient niFiClient;
+
+ @Before
+ public void setup() {
+ niFiClient = new MockNiFiClient(RESOURCES_RESPONSE, 200);
+ }
+
+ @Test
+ public void testGetResourcesNoUserInput() throws Exception {
+ ResourceLookupContext resourceLookupContext = Mockito.mock(ResourceLookupContext.class);
+ when(resourceLookupContext.getUserInput()).thenReturn("");
+
+ final List<String> expectedResources = new ArrayList<>();
+ expectedResources.add("/system");
+ expectedResources.add("/controller");
+ expectedResources.add("/flow");
+ expectedResources.add("/provenance");
+ expectedResources.add("/proxy");
+ expectedResources.add("/resources");
+
+ List<String> resources = niFiClient.getResources(resourceLookupContext);
+ Assert.assertNotNull(resources);
+ Assert.assertEquals(expectedResources.size(), resources.size());
+
+ resources.removeAll(expectedResources);
+ Assert.assertEquals(0, resources.size());
+ }
+
+ @Test
+ public void testGetResourcesWithUserInputBeginning() throws Exception {
+ ResourceLookupContext resourceLookupContext = Mockito.mock(ResourceLookupContext.class);
+ when(resourceLookupContext.getUserInput()).thenReturn("/pr");
+
+ final List<String> expectedResources = new ArrayList<>();
+ expectedResources.add("/provenance");
+ expectedResources.add("/proxy");
+
+ List<String> resources = niFiClient.getResources(resourceLookupContext);
+ Assert.assertNotNull(resources);
+ Assert.assertEquals(expectedResources.size(), resources.size());
+
+ resources.removeAll(expectedResources);
+ Assert.assertEquals(0, resources.size());
+ }
+
+ @Test
+ public void testGetResourcesWithUserInputAnywhere() throws Exception {
+ ResourceLookupContext resourceLookupContext = Mockito.mock(ResourceLookupContext.class);
+ when(resourceLookupContext.getUserInput()).thenReturn("trol");
+
+ final List<String> expectedResources = new ArrayList<>();
+ expectedResources.add("/controller");
+
+ List<String> resources = niFiClient.getResources(resourceLookupContext);
+ Assert.assertNotNull(resources);
+ Assert.assertEquals(expectedResources.size(), resources.size());
+
+ resources.removeAll(expectedResources);
+ Assert.assertEquals(0, resources.size());
+ }
+
+ @Test
+ public void testGetResourcesErrorResponse() throws Exception {
+ final String errorMsg = "unknown error";
+ niFiClient = new MockNiFiClient(errorMsg, Response.Status.BAD_REQUEST.getStatusCode());
+
+ ResourceLookupContext resourceLookupContext = Mockito.mock(ResourceLookupContext.class);
+ when(resourceLookupContext.getUserInput()).thenReturn("");
+
+ try {
+ niFiClient.getResources(resourceLookupContext);
+ Assert.fail("should have thrown exception");
+ } catch (Exception e) {
+ Assert.assertTrue(e.getMessage().contains(errorMsg));
+ }
+ }
+
+ @Test
+ public void testConnectionTestSuccess() {
+ HashMap<String, Object> ret = niFiClient.connectionTest();
+ Assert.assertNotNull(ret);
+ Assert.assertEquals(NiFiClient.SUCCESS_MSG, ret.get("message"));
+ }
+
+ @Test
+ public void testConnectionTestFailure() {
+ final String errorMsg = "unknown error";
+ niFiClient = new MockNiFiClient(errorMsg, Response.Status.BAD_REQUEST.getStatusCode());
+
+ HashMap<String, Object> ret = niFiClient.connectionTest();
+ Assert.assertNotNull(ret);
+ Assert.assertEquals(NiFiClient.FAILURE_MSG, ret.get("message"));
+ }
+
+
+ /**
+ * Extend NiFiClient to return mock responses.
+ */
+ private static final class MockNiFiClient extends NiFiClient {
+
+ private int statusCode;
+ private String responseEntity;
+
+ public MockNiFiClient(String responseEntity, int statusCode) {
+ super("http://localhost:8080/nifi-api/resources", null);
+ this.statusCode = statusCode;
+ this.responseEntity = responseEntity;
+ }
+
+ @Override
+ protected WebResource getWebResource() {
+ return Mockito.mock(WebResource.class);
+ }
+
+ @Override
+ protected ClientResponse getResponse(WebResource resource, String accept) {
+ ClientResponse response = Mockito.mock(ClientResponse.class);
+ when(response.getStatus()).thenReturn(statusCode);
+ when(response.getEntityInputStream()).thenReturn(new ByteArrayInputStream(
+ responseEntity.getBytes(StandardCharsets.UTF_8)
+ ));
+ return response;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiConnectionMgr.java
----------------------------------------------------------------------
diff --git a/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiConnectionMgr.java b/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiConnectionMgr.java
new file mode 100644
index 0000000..1726854
--- /dev/null
+++ b/plugin-nifi/src/test/java/org/apache/ranger/services/nifi/client/TestNiFiConnectionMgr.java
@@ -0,0 +1,124 @@
+/*
+ * 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.ranger.services.nifi.client;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.FileNotFoundException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class TestNiFiConnectionMgr {
+
+ @Test (expected = IllegalArgumentException.class)
+ public void testValidURLWithWrongEndPoint() throws Exception {
+ final String nifiUrl = "http://localhost:8080/nifi";
+
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, nifiUrl);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.NONE.name());
+
+ NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ }
+
+ @Test (expected = IllegalArgumentException.class)
+ public void testInvalidURL() throws Exception {
+ final String nifiUrl = "not a url";
+
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, nifiUrl);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.NONE.name());
+
+ NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ }
+
+ @Test
+ public void testAuthTypeNone() throws Exception {
+ final String nifiUrl = "http://localhost:8080/nifi-api/resources";
+
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, nifiUrl);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.NONE.name());
+
+ NiFiClient client = NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ Assert.assertNotNull(client);
+ Assert.assertEquals(nifiUrl, client.getUrl());
+ Assert.assertNull(client.getSslContext());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAuthTypeNoneMissingURL() throws Exception {
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, null);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.NONE.name());
+
+ NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ }
+
+ @Test(expected = FileNotFoundException.class)
+ public void testAuthTypeSSL() throws Exception {
+ final String nifiUrl = "https://localhost:8080/nifi-api/resources";
+
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, nifiUrl);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.SSL.name());
+
+ configs.put(NiFiConfigs.NIFI_SSL_KEYSTORE, "src/test/resources/missing.jks");
+ configs.put(NiFiConfigs.NIFI_SSL_KEYSTORE_PASSWORD, "password");
+ configs.put(NiFiConfigs.NIFI_SSL_KEYSTORE_TYPE, "JKS");
+
+ configs.put(NiFiConfigs.NIFI_SSL_TRUSTSTORE, "src/test/resources/missing.jks");
+ configs.put(NiFiConfigs.NIFI_SSL_TRUSTSTORE_PASSWORD, "password");
+ configs.put(NiFiConfigs.NIFI_SSL_TRUSTSTORE_TYPE, "JKS");
+
+ NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAuthTypeSSLWithNonHttpsUrl() throws Exception {
+ final String nifiUrl = "http://localhost:8080/nifi-api/resources";
+
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, nifiUrl);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.SSL.name());
+
+ configs.put(NiFiConfigs.NIFI_SSL_KEYSTORE, "src/test/resources/missing.jks");
+ configs.put(NiFiConfigs.NIFI_SSL_KEYSTORE_PASSWORD, "password");
+ configs.put(NiFiConfigs.NIFI_SSL_KEYSTORE_TYPE, "JKS");
+
+ configs.put(NiFiConfigs.NIFI_SSL_TRUSTSTORE, "src/test/resources/missing.jks");
+ configs.put(NiFiConfigs.NIFI_SSL_TRUSTSTORE_PASSWORD, "password");
+ configs.put(NiFiConfigs.NIFI_SSL_TRUSTSTORE_TYPE, "JKS");
+
+ NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testAuthTypeSSLMissingConfigs() throws Exception {
+ final String nifiUrl = "http://localhost:8080/nifi";
+
+ Map<String,String> configs = new HashMap<>();
+ configs.put(NiFiConfigs.NIFI_URL, nifiUrl);
+ configs.put(NiFiConfigs.NIFI_AUTHENTICATION_TYPE, NiFiAuthType.SSL.name());
+
+ NiFiConnectionMgr.getNiFiClient("nifi", configs);
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index eda7d7d..d6aa833 100644
--- a/pom.xml
+++ b/pom.xml
@@ -87,6 +87,7 @@
<module>security-admin</module>
<module>plugin-kafka</module>
<module>plugin-solr</module>
+ <module>plugin-nifi</module>
<module>ugsync</module>
<module>ugsync/ldapconfigchecktool/ldapconfigcheck</module>
<module>unixauthclient</module>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/b64218a3/src/main/assembly/admin-web.xml
----------------------------------------------------------------------
diff --git a/src/main/assembly/admin-web.xml b/src/main/assembly/admin-web.xml
index 6aeb397..7fd2abf 100644
--- a/src/main/assembly/admin-web.xml
+++ b/src/main/assembly/admin-web.xml
@@ -296,6 +296,19 @@
<include>org.apache.ranger:ranger-solr-plugin</include>
</includes>
</moduleSet>
+
+ <moduleSet>
+ <binaries>
+ <includeDependencies>true</includeDependencies>
+ <outputDirectory>/ews/webapp/WEB-INF/classes/ranger-plugins/nifi</outputDirectory>
+ <unpack>false</unpack>
+ <directoryMode>755</directoryMode>
+ <fileMode>644</fileMode>
+ </binaries>
+ <includes>
+ <include>org.apache.ranger:ranger-nifi-plugin</include>
+ </includes>
+ </moduleSet>
</moduleSets>
<fileSets>