This is an automated email from the ASF dual-hosted git repository.

spolavarapu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git


The following commit(s) were added to refs/heads/master by this push:
     new a4cf0b7  RANGER-2862: Client Code Final Commit
a4cf0b7 is described below

commit a4cf0b7c26723db0429f5ef8ac39b64bf1a8762c
Author: Abhishek Kumar <abhishekkumar100...@gmail.com>
AuthorDate: Mon Jul 6 20:16:03 2020 -0400

    RANGER-2862: Client Code Final Commit
    
    Signed-off-by: Sailaja Polavarapu <spolavar...@cloudera.com>
---
 intg/pom.xml                                       |  51 ++
 .../main/java/org/apache/ranger/RangerClient.java  | 530 +++++++++++++++++++++
 .../org/apache/ranger/RangerServiceException.java  |  44 ++
 intg/src/main/resources/log4j.properties           |  23 +
 .../java/org/apache/ranger/TestRangerClient.java   | 150 ++++++
 pom.xml                                            |  17 +
 ranger-examples/distro/pom.xml                     |   3 +-
 .../distro/src/main/assembly/sample-client.xml     |  92 ++++
 ranger-examples/pom.xml                            |   1 +
 ranger-examples/sample-client/pom.xml              |  60 +++
 .../sample-client/scripts/run-sample-client.sh     |  50 ++
 .../ranger/examples/sampleclient/SampleClient.java | 193 ++++++++
 .../src/main/resources/log4j.properties            |  23 +
 13 files changed, 1236 insertions(+), 1 deletion(-)

diff --git a/intg/pom.xml b/intg/pom.xml
new file mode 100644
index 0000000..da8b910
--- /dev/null
+++ b/intg/pom.xml
@@ -0,0 +1,51 @@
+<?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";>
+    <packaging>jar</packaging>
+    <parent>
+        <artifactId>ranger</artifactId>
+        <groupId>org.apache.ranger</groupId>
+        <version>2.1.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ranger-intg</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.testng</groupId>
+            <artifactId>testng</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/intg/src/main/java/org/apache/ranger/RangerClient.java 
b/intg/src/main/java/org/apache/ranger/RangerClient.java
new file mode 100644
index 0000000..29b2ec0
--- /dev/null
+++ b/intg/src/main/java/org/apache/ranger/RangerClient.java
@@ -0,0 +1,530 @@
+/*
+ * 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;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import com.sun.jersey.api.client.ClientResponse;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.ranger.plugin.model.*;
+import org.apache.ranger.admin.client.datatype.RESTResponse;
+import org.apache.ranger.plugin.util.GrantRevokeRoleRequest;
+import org.apache.ranger.plugin.util.RangerRESTClient;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import java.net.URI;
+import java.util.*;
+
+
+public class RangerClient {
+    private static final Logger LOG = 
LoggerFactory.getLogger(RangerClient.class);
+
+    // QueryParams
+    private static final String PARAM_DAYS                          = "days";
+    private static final String PARAM_EXEC_USER                     = 
"execUser";
+    private static final String PARAM_POLICY_NAME                   = 
"policyname";
+    private static final String PARAM_SERVICE_NAME                  = 
"serviceName";
+    private static final String PARAM_RELOAD_SERVICE_POLICIES_CACHE = 
"reloadServicePoliciesCache";
+
+    // URIs
+    private static final String URI_BASE                  = 
"/service/public/v2/api";
+
+    private static final String URI_SERVICEDEF            = URI_BASE + 
"/servicedef";
+    private static final String URI_SERVICEDEF_BY_ID      = URI_SERVICEDEF + 
"/%d";
+    private static final String URI_SERVICEDEF_BY_NAME    = URI_SERVICEDEF + 
"/name/%s";
+
+    private static final String URI_SERVICE               = URI_BASE + 
"/service";
+    private static final String URI_SERVICE_BY_ID         = URI_SERVICE + 
"/%d";
+    private static final String URI_SERVICE_BY_NAME       = URI_SERVICE + 
"/name/%s";
+    private static final String URI_POLICIES_IN_SERVICE   = URI_SERVICE + 
"/%s/policy";
+
+    private static final String URI_POLICY                = URI_BASE + 
"/policy";
+    private static final String URI_APPLY_POLICY          = URI_POLICY + 
"/apply";
+    private static final String URI_POLICY_BY_ID          = URI_POLICY + "/%d";
+    private static final String URI_POLICY_BY_NAME        = URI_SERVICE + 
"/%s/policy/%s";
+
+    private static final String URI_ROLE                  = URI_BASE + 
"/roles";
+    private static final String URI_ROLE_NAMES            = URI_ROLE + 
"/names";
+    private static final String URI_ROLE_BY_ID            = URI_ROLE + "/%d";
+    private static final String URI_ROLE_BY_NAME          = URI_ROLE + 
"/name/%s";
+    private static final String URI_USER_ROLES            = URI_ROLE + 
"/user/%s";
+    private static final String URI_GRANT_ROLE            = URI_ROLE + 
"/grant/%s";
+    private static final String URI_REVOKE_ROLE           = URI_ROLE + 
"/revoke/%s";
+
+    private static final String URI_ZONE                  = URI_BASE + 
"/zones";
+    private static final String URI_ZONE_BY_ID            = URI_ZONE + "/%d";
+    private static final String URI_ZONE_BY_NAME          = URI_ZONE + 
"/name/%s";
+
+    private static final String URI_PLUGIN_INFO           = URI_BASE + 
"/plugins/info";
+    private static final String URI_POLICY_DELTAS         = URI_BASE + 
"/server/policydeltas";
+
+
+    // APIs
+    public static final API CREATE_SERVICEDEF         = new 
API(URI_SERVICEDEF, HttpMethod.POST, Response.Status.OK);
+    public static final API UPDATE_SERVICEDEF_BY_ID   = new 
API(URI_SERVICEDEF_BY_ID, HttpMethod.PUT, Response.Status.OK);
+    public static final API UPDATE_SERVICEDEF_BY_NAME = new 
API(URI_SERVICEDEF_BY_NAME, HttpMethod.PUT, Response.Status.OK);
+    public static final API DELETE_SERVICEDEF_BY_ID   = new 
API(URI_SERVICEDEF_BY_ID, HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API DELETE_SERVICEDEF_BY_NAME = new 
API(URI_SERVICEDEF_BY_NAME, HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API GET_SERVICEDEF_BY_ID      = new 
API(URI_SERVICEDEF_BY_ID, HttpMethod.GET, Response.Status.OK);
+    public static final API GET_SERVICEDEF_BY_NAME    = new 
API(URI_SERVICEDEF_BY_NAME, HttpMethod.GET, Response.Status.OK);
+    public static final API FIND_SERVICEDEFS          = new 
API(URI_SERVICEDEF, HttpMethod.GET, Response.Status.OK);
+
+    public static final API CREATE_SERVICE            = new API(URI_SERVICE, 
HttpMethod.POST, Response.Status.OK);
+    public static final API UPDATE_SERVICE_BY_ID      = new 
API(URI_SERVICE_BY_ID, HttpMethod.PUT, Response.Status.OK);
+    public static final API UPDATE_SERVICE_BY_NAME    = new 
API(URI_SERVICE_BY_NAME, HttpMethod.PUT, Response.Status.OK);
+    public static final API DELETE_SERVICE_BY_ID      = new 
API(URI_SERVICE_BY_ID, HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API DELETE_SERVICE_BY_NAME    = new 
API(URI_SERVICE_BY_NAME, HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API GET_SERVICE_BY_ID         = new 
API(URI_SERVICE_BY_ID, HttpMethod.GET, Response.Status.OK);
+    public static final API GET_SERVICE_BY_NAME       = new 
API(URI_SERVICE_BY_NAME, HttpMethod.GET, Response.Status.OK);
+    public static final API FIND_SERVICES             = new API(URI_SERVICE, 
HttpMethod.GET, Response.Status.OK);
+
+    public static final API CREATE_POLICY            = new API(URI_POLICY, 
HttpMethod.POST, Response.Status.OK);
+    public static final API UPDATE_POLICY_BY_ID      = new 
API(URI_POLICY_BY_ID, HttpMethod.PUT, Response.Status.OK);
+    public static final API UPDATE_POLICY_BY_NAME    = new 
API(URI_POLICY_BY_NAME, HttpMethod.PUT, Response.Status.OK);
+    public static final API APPLY_POLICY             = new 
API(URI_APPLY_POLICY, HttpMethod.POST, Response.Status.OK);
+    public static final API DELETE_POLICY_BY_ID      = new 
API(URI_POLICY_BY_ID, HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API DELETE_POLICY_BY_NAME    = new API(URI_POLICY, 
HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API GET_POLICY_BY_ID         = new 
API(URI_POLICY_BY_ID, HttpMethod.GET, Response.Status.OK);
+    public static final API GET_POLICY_BY_NAME       = new 
API(URI_POLICY_BY_NAME, HttpMethod.GET, Response.Status.OK);
+    public static final API GET_POLICIES_IN_SERVICE  = new 
API(URI_POLICIES_IN_SERVICE, HttpMethod.GET, Response.Status.OK);
+    public static final API FIND_POLICIES            = new API(URI_POLICY, 
HttpMethod.GET, Response.Status.OK);
+
+    public static final API CREATE_ZONE         = new API(URI_ZONE, 
HttpMethod.POST, Response.Status.OK);
+    public static final API UPDATE_ZONE_BY_ID   = new API(URI_ZONE_BY_ID, 
HttpMethod.PUT, Response.Status.OK);
+    public static final API UPDATE_ZONE_BY_NAME = new API(URI_ZONE_BY_NAME, 
HttpMethod.PUT, Response.Status.OK);
+    public static final API DELETE_ZONE_BY_ID   = new API(URI_ZONE_BY_ID, 
HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API DELETE_ZONE_BY_NAME = new API(URI_ZONE_BY_NAME, 
HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API GET_ZONE_BY_ID      = new API(URI_ZONE_BY_ID, 
HttpMethod.GET, Response.Status.OK);
+    public static final API GET_ZONE_BY_NAME    = new API(URI_ZONE_BY_NAME, 
HttpMethod.GET, Response.Status.OK);
+    public static final API FIND_ZONES          = new API(URI_ZONE, 
HttpMethod.GET, Response.Status.OK);
+
+    public static final API CREATE_ROLE         = new API(URI_ROLE, 
HttpMethod.POST, Response.Status.OK);
+    public static final API UPDATE_ROLE_BY_ID   = new API(URI_ROLE_BY_ID, 
HttpMethod.PUT, Response.Status.OK);
+    public static final API DELETE_ROLE_BY_ID   = new API(URI_ROLE_BY_ID, 
HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API DELETE_ROLE_BY_NAME = new API(URI_ROLE_BY_NAME, 
HttpMethod.DELETE, Response.Status.NO_CONTENT);
+    public static final API GET_ROLE_BY_ID      = new API(URI_ROLE_BY_ID, 
HttpMethod.GET, Response.Status.OK);
+    public static final API GET_ROLE_BY_NAME    = new API(URI_ROLE_BY_NAME, 
HttpMethod.GET, Response.Status.OK);
+    public static final API GET_ALL_ROLE_NAMES  = new API(URI_ROLE_NAMES, 
HttpMethod.GET, Response.Status.OK);
+    public static final API GET_USER_ROLES      = new API(URI_USER_ROLES, 
HttpMethod.GET, Response.Status.OK);
+    public static final API GRANT_ROLE          = new API(URI_GRANT_ROLE, 
HttpMethod.PUT, Response.Status.OK);
+    public static final API REVOKE_ROLE         = new API(URI_REVOKE_ROLE, 
HttpMethod.PUT, Response.Status.OK);
+    public static final API FIND_ROLES          = new API(URI_ROLE, 
HttpMethod.GET, Response.Status.OK);
+
+    public static final API GET_PLUGIN_INFO      = new API(URI_PLUGIN_INFO, 
HttpMethod.GET, Response.Status.OK);
+    public static final API DELETE_POLICY_DELTAS = new API(URI_POLICY_DELTAS, 
HttpMethod.DELETE, Response.Status.NO_CONTENT);
+
+
+    private final RangerRESTClient restClient;
+
+
+    public RangerClient(String hostname, String username, String password) {
+        restClient = new RangerRESTClient(hostname, "", new Configuration());
+
+        restClient.setBasicAuthInfo(username, password);
+    }
+
+    public RangerClient(RangerRESTClient restClient) {
+        this.restClient = restClient;
+    }
+
+    /*
+     * ServiceDef APIs
+     */
+    public RangerServiceDef createServiceDef(RangerServiceDef serviceDef) 
throws RangerServiceException {
+        return callAPI(CREATE_SERVICEDEF, null, serviceDef, 
RangerServiceDef.class);
+    }
+
+    public RangerServiceDef updateServiceDef(long serviceDefId, 
RangerServiceDef serviceDef) throws RangerServiceException {
+        return callAPI(UPDATE_SERVICEDEF_BY_ID.applyUrlFormat(serviceDefId), 
null, serviceDef, RangerServiceDef.class);
+    }
+
+    public RangerServiceDef updateServiceDef(String serviceDefName, 
RangerServiceDef serviceDef) throws RangerServiceException {
+        return 
callAPI(UPDATE_SERVICEDEF_BY_NAME.applyUrlFormat(serviceDefName), null, 
serviceDef, RangerServiceDef.class);
+    }
+
+    public void deleteServiceDef(long serviceDefId) throws 
RangerServiceException {
+        callAPI(DELETE_SERVICEDEF_BY_ID.applyUrlFormat(serviceDefId), null, 
null, null);
+    }
+
+    public void deleteServiceDef(String serviceDefName) throws 
RangerServiceException {
+        callAPI(DELETE_SERVICEDEF_BY_NAME.applyUrlFormat(serviceDefName), 
null, null, null);
+    }
+
+    public RangerServiceDef getServiceDef(long serviceDefId) throws 
RangerServiceException {
+        return callAPI(GET_SERVICEDEF_BY_ID.applyUrlFormat(serviceDefId), 
null, null, RangerServiceDef.class);
+    }
+
+    public RangerServiceDef getServiceDef(String serviceDefName) throws 
RangerServiceException {
+        return callAPI(GET_SERVICEDEF_BY_NAME.applyUrlFormat(serviceDefName), 
null, null, RangerServiceDef.class);
+    }
+
+    public List<RangerServiceDef> findServiceDefs(Map<String, String> filter) 
throws RangerServiceException {
+        return callAPI(FIND_SERVICEDEFS, filter, null, List.class);
+    }
+
+
+    /*
+     * Service APIs
+     */
+    public RangerService createService(RangerService service) throws 
RangerServiceException {
+        return callAPI(CREATE_SERVICE, null, service, RangerService.class);
+    }
+
+    public RangerService updateService(long serviceId, RangerService service) 
throws RangerServiceException {
+        return callAPI(UPDATE_SERVICE_BY_ID.applyUrlFormat(serviceId), null, 
service, RangerService.class);
+    }
+
+    public RangerService updateService(String serviceName, RangerService 
service) throws RangerServiceException {
+        return callAPI(UPDATE_SERVICE_BY_NAME.applyUrlFormat(serviceName), 
null, service, RangerService.class);
+    }
+
+    public void deleteService(long serviceId) throws RangerServiceException {
+        callAPI(DELETE_SERVICE_BY_ID.applyUrlFormat(serviceId), null, null, 
null);
+    }
+
+    public void deleteService(String serviceName) throws 
RangerServiceException {
+        callAPI(DELETE_SERVICE_BY_NAME.applyUrlFormat(serviceName), null, 
null, null);
+    }
+
+    public RangerService getService(long serviceId) throws 
RangerServiceException {
+        return callAPI(GET_SERVICE_BY_ID.applyUrlFormat(serviceId), null, 
null, RangerService.class);
+    }
+
+    public RangerService getService(String serviceName) throws 
RangerServiceException {
+        return callAPI(GET_SERVICE_BY_NAME.applyUrlFormat(serviceName), null, 
null, RangerService.class);
+    }
+
+    public List<RangerService> findServices(Map<String, String> filter) throws 
RangerServiceException {
+        return callAPI(FIND_SERVICES, filter, null, List.class);
+    }
+
+
+    /*
+     * Policy APIs
+     */
+    public RangerPolicy createPolicy(RangerPolicy policy) throws 
RangerServiceException {
+        return callAPI(CREATE_POLICY, null, policy, RangerPolicy.class);
+    }
+
+    public RangerPolicy updatePolicy(long policyId, RangerPolicy policy) 
throws RangerServiceException {
+        return callAPI(UPDATE_POLICY_BY_ID.applyUrlFormat(policyId), null, 
policy, RangerPolicy.class);
+    }
+
+    public RangerPolicy updatePolicy(String serviceName, String policyName, 
RangerPolicy policy) throws RangerServiceException {
+        return callAPI(UPDATE_POLICY_BY_NAME.applyUrlFormat(serviceName, 
policyName), null, policy, RangerPolicy.class);
+    }
+
+    public RangerPolicy applyPolicy(RangerPolicy policy) throws 
RangerServiceException {
+        return callAPI(APPLY_POLICY, null, policy, RangerPolicy.class);
+    }
+
+    public void deletePolicy(long policyId) throws RangerServiceException {
+        callAPI(DELETE_POLICY_BY_ID.applyUrlFormat(policyId), null, null, 
null);
+    }
+
+    public void deletePolicy(String serviceName, String policyName) throws 
RangerServiceException {
+        Map<String,String> queryParams = new HashMap<>();
+
+        queryParams.put(PARAM_POLICY_NAME, policyName);
+        queryParams.put("servicename", serviceName);
+
+        callAPI(DELETE_POLICY_BY_NAME, queryParams, null, null);
+    }
+
+    public RangerPolicy getPolicy(long policyId) throws RangerServiceException 
{
+        return callAPI(GET_POLICY_BY_ID.applyUrlFormat(policyId), null, null, 
RangerPolicy.class);
+    }
+
+    public RangerPolicy getPolicy(String serviceName, String policyName) 
throws RangerServiceException {
+        return callAPI(GET_POLICY_BY_NAME.applyUrlFormat(serviceName, 
policyName), null, null, RangerPolicy.class);
+    }
+
+    public List<RangerPolicy> getPoliciesInService(String serviceName) throws 
RangerServiceException {
+        return callAPI(GET_POLICIES_IN_SERVICE.applyUrlFormat(serviceName), 
null, null, List.class);
+    }
+
+    public List<RangerPolicy> findPolicies(Map<String, String> filter) throws 
RangerServiceException {
+        return callAPI(FIND_POLICIES, filter, null, List.class);
+    }
+
+
+    /*
+     * SecurityZone APIs
+     */
+    public RangerSecurityZone createSecurityZone(RangerSecurityZone 
securityZone) throws RangerServiceException {
+        return callAPI(CREATE_ZONE, null, securityZone, 
RangerSecurityZone.class);
+    }
+
+    public RangerSecurityZone updateSecurityZone(long zoneId, 
RangerSecurityZone securityZone) throws RangerServiceException {
+        return callAPI(UPDATE_ZONE_BY_ID.applyUrlFormat(zoneId), null, 
securityZone, RangerSecurityZone.class);
+    }
+
+    public RangerSecurityZone updateSecurityZone(String zoneName, 
RangerSecurityZone securityZone) throws RangerServiceException {
+        return callAPI(UPDATE_ZONE_BY_NAME.applyUrlFormat(zoneName), null, 
securityZone, RangerSecurityZone.class);
+    }
+
+    public void deleteSecurityZone(long zoneId) throws RangerServiceException {
+        callAPI(DELETE_ZONE_BY_ID.applyUrlFormat(zoneId), null, null, null);
+    }
+
+    public void deleteSecurityZone(String zoneName) throws 
RangerServiceException {
+        callAPI(DELETE_ZONE_BY_NAME.applyUrlFormat(zoneName), null, null, 
null);
+    }
+
+    public RangerSecurityZone getSecurityZone(long zoneId) throws 
RangerServiceException {
+        return callAPI(GET_ZONE_BY_ID.applyUrlFormat(zoneId), null, null, 
RangerSecurityZone.class);
+    }
+
+    public RangerSecurityZone getSecurityZone(String zoneName) throws 
RangerServiceException {
+        return callAPI(GET_ZONE_BY_NAME.applyUrlFormat(zoneName), null, null, 
RangerSecurityZone.class);
+    }
+
+    public List<RangerSecurityZone> findSecurityZones(Map<String, String> 
filter) throws RangerServiceException {
+        return callAPI(FIND_ZONES, filter, null, List.class);
+    }
+
+    /*
+     * Role APIs
+     */
+    public RangerRole createRole(String serviceName, RangerRole role) throws 
RangerServiceException {
+        return callAPI(CREATE_ROLE, 
Collections.singletonMap(PARAM_SERVICE_NAME, serviceName), role, 
RangerRole.class);
+    }
+
+    public RangerRole updateRole(long roleId, RangerRole role) throws 
RangerServiceException {
+        return callAPI(UPDATE_ROLE_BY_ID.applyUrlFormat(roleId), null, role, 
RangerRole.class);
+    }
+
+    public void deleteRole(long roleId) throws RangerServiceException {
+        callAPI(DELETE_ROLE_BY_ID.applyUrlFormat(roleId), null, null, null);
+    }
+
+    public void deleteRole(String roleName, String execUser, String 
serviceName) throws RangerServiceException {
+        Map<String,String> queryParams = new HashMap<>();
+
+        queryParams.put(PARAM_EXEC_USER, execUser);
+        queryParams.put(PARAM_SERVICE_NAME, serviceName);
+
+        callAPI(DELETE_ROLE_BY_NAME.applyUrlFormat(roleName), queryParams, 
null, null);
+    }
+
+    public RangerRole getRole(long roleId) throws RangerServiceException {
+        return callAPI(GET_ROLE_BY_ID.applyUrlFormat(roleId), null, null, 
RangerRole.class);
+    }
+
+    public RangerRole getRole(String roleName, String execUser, String 
serviceName) throws RangerServiceException {
+        Map<String,String> queryParams = new HashMap<>();
+
+        queryParams.put(PARAM_EXEC_USER, execUser);
+        queryParams.put(PARAM_SERVICE_NAME, serviceName);
+
+        return callAPI(GET_ROLE_BY_NAME.applyUrlFormat(roleName), queryParams, 
null, RangerRole.class);
+    }
+
+    public List<String> getAllRoleNames(String execUser, String serviceName) 
throws RangerServiceException {
+        Map<String,String> queryParams = new HashMap<>();
+
+        queryParams.put(PARAM_EXEC_USER, execUser);
+        queryParams.put(PARAM_SERVICE_NAME, serviceName);
+
+        return callAPI(GET_ALL_ROLE_NAMES.applyUrlFormat(serviceName), 
queryParams, null, List.class);
+    }
+
+    public List<String> getUserRoles(String user) throws 
RangerServiceException {
+        return callAPI(GET_USER_ROLES.applyUrlFormat(user), null, null, 
List.class);
+    }
+
+    public List<RangerRole> findRoles(Map<String, String> filter) throws 
RangerServiceException {
+        return callAPI(FIND_ROLES, filter, null, List.class);
+    }
+
+    public RESTResponse grantRole(String serviceName, GrantRevokeRoleRequest 
request) throws RangerServiceException {
+        return callAPI(GRANT_ROLE.applyUrlFormat(serviceName), null, request, 
RESTResponse.class);
+    }
+
+    public RESTResponse revokeRole(String serviceName, GrantRevokeRoleRequest 
request) throws RangerServiceException {
+        return callAPI(REVOKE_ROLE.applyUrlFormat(serviceName), null, request, 
RESTResponse.class);
+    }
+
+
+    /*
+     * Admin APIs
+     */
+    public List<RangerPluginInfo> getPluginsInfo() throws 
RangerServiceException {
+        return callAPI(GET_PLUGIN_INFO, null, null, List.class);
+    }
+
+    public void deletePolicyDeltas(int days, boolean 
reloadServicePoliciesCache) throws RangerServiceException {
+        Map<String,String> queryParams = new HashMap<>();
+
+        queryParams.put(PARAM_DAYS, String.valueOf(days));
+        queryParams.put(PARAM_RELOAD_SERVICE_POLICIES_CACHE, 
String.valueOf(reloadServicePoliciesCache));
+
+        callAPI(DELETE_POLICY_DELTAS, queryParams, null, null);
+    }
+
+
+    private <T> T callAPI(API api, Map<String, String> params, Object request, 
Class<T> responseType) throws RangerServiceException {
+        T ret = null;
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("==> callAPI({},{},{},{})",api, params, request, 
responseType);
+            
LOG.debug("------------------------------------------------------");
+            LOG.debug("Call         : {} {}", api.getMethod(), 
api.getNormalizedPath());
+            LOG.debug("Content-type : {} ", api.getConsumes());
+            LOG.debug("Accept       : {} ", api.getProduces());
+            if (request != null) {
+                LOG.debug("Request      : {}", request);
+            }
+        }
+
+        final ClientResponse clientResponse;
+
+        try {
+            switch (api.getMethod()) {
+                case HttpMethod.POST:
+                    clientResponse = restClient.post(api.getPath(), params, 
request);
+                break;
+
+                case HttpMethod.PUT:
+                    clientResponse = restClient.put(api.getPath(), params, 
request);
+                break;
+
+                case HttpMethod.GET:
+                    clientResponse = restClient.get(api.getPath(), params);
+                break;
+
+                case HttpMethod.DELETE:
+                    clientResponse = restClient.delete(api.getPath(), params);
+                break;
+
+                default:
+                    LOG.error(api.getMethod() + ": unsupported HTTP method");
+
+                    clientResponse = null;
+            }
+        } catch (Exception excp) {
+            throw new RangerServiceException(excp);
+        }
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("method={}, path={}, contentType={}, accept={}, 
httpStatus={}", api.getMethod(), api.getNormalizedPath(), api.getConsumes(), 
api.getProduces(), (clientResponse != null ? clientResponse.getStatus() : 
"null"));
+        }
+
+        if (clientResponse == null) {
+            throw new RangerServiceException(api, clientResponse);
+        } else if (clientResponse.getStatus() == 
api.getExpectedStatus().getStatusCode()) {
+            if (responseType != null) {
+                ret = clientResponse.getEntity(responseType);
+
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Response: {}", restClient.toJson(ret));
+                    
LOG.debug("------------------------------------------------------");
+                }
+            }
+        } else if (clientResponse.getStatus() == 
ClientResponse.Status.SERVICE_UNAVAILABLE.getStatusCode()) {
+            LOG.error("Ranger Admin unavailable. HTTP Status: {}", 
clientResponse.getStatus());
+        } else {
+            throw new RangerServiceException(api, clientResponse);
+        }
+
+        if(LOG.isDebugEnabled()){
+            LOG.debug("<== callAPI({},{},{},{}), result = {}", api, params, 
request, responseType, ret);
+        }
+        return ret;
+    }
+
+    public static class API {
+        private static final Logger LOG = LoggerFactory.getLogger(API.class);
+
+        private final String          path;
+        private final String          method;
+        private final Response.Status expectedStatus;
+        private final String          consumes;
+        private final String          produces;
+
+
+        public API(String path, String method, Response.Status expectedStatus) 
{
+            this(path, method, expectedStatus, MediaType.APPLICATION_JSON, 
MediaType.APPLICATION_JSON);
+        }
+
+        public API(String path, String method, Response.Status expectedStatus, 
String consumes, String produces) {
+            this.path           = path;
+            this.method         = method;
+            this.expectedStatus = expectedStatus;
+            this.consumes       = consumes;
+            this.produces       = produces;
+        }
+
+        public String getPath() {
+            return path;
+        }
+
+        public String getMethod() {
+            return method;
+        }
+
+        public Response.Status getExpectedStatus() {
+            return expectedStatus;
+        }
+
+        public String getConsumes() {
+            return consumes;
+        }
+
+        public String getProduces() {
+            return produces;
+        }
+
+        public String getNormalizedPath() {
+            // This method used to return 
Paths.get(path).normalize().toString(), but
+            // the use of Paths.get(path) on Windows produces a path with 
Windows
+            // path separators (i.e. back-slashes) which is not valid for a URI
+            // and will result in an HTTP 404 status code.
+            String ret = null;
+
+            try {
+                URI uri = new URI(path);
+
+                if (uri != null) {
+                    URI normalizedUri = uri.normalize();
+
+                    ret = normalizedUri.toString();
+                }
+            } catch (Exception e) {
+                LOG.error("getNormalizedPath() caught exception for path={}", 
path, e);
+
+                ret = null;
+            }
+
+            return ret;
+        }
+
+        public API applyUrlFormat(Object... params) throws 
RangerServiceException {
+            try{
+                return new API(String.format(path, params), method, 
expectedStatus, consumes, produces);
+            } catch(IllegalFormatException e) {
+                LOG.error("Arguments not formatted properly");
+
+                throw new RangerServiceException(e);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/intg/src/main/java/org/apache/ranger/RangerServiceException.java 
b/intg/src/main/java/org/apache/ranger/RangerServiceException.java
new file mode 100644
index 0000000..9b909a4
--- /dev/null
+++ b/intg/src/main/java/org/apache/ranger/RangerServiceException.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.ranger;
+
+import com.sun.jersey.api.client.ClientResponse;
+
+public class RangerServiceException extends Exception {
+    private final ClientResponse.Status status;
+
+    public RangerServiceException(Exception e) {
+        super(e);
+
+        this.status = null;
+    }
+
+    public RangerServiceException(RangerClient.API api, ClientResponse 
response) {
+        this(api, response == null ? null : 
ClientResponse.Status.fromStatusCode(response.getStatus()), response == null ? 
null : response.getEntity(String.class));
+    }
+
+    private RangerServiceException(RangerClient.API api, ClientResponse.Status 
status, String response) {
+        super("Ranger API " + api + " failed: statusCode=" + (status != null ? 
status.getStatusCode() : "null")
+                + ", status=" + status + ", response:" + response);
+
+        this.status = status;
+    }
+
+    public ClientResponse.Status getStatus() { return status; }
+}
diff --git a/intg/src/main/resources/log4j.properties 
b/intg/src/main/resources/log4j.properties
new file mode 100644
index 0000000..9c8bd00
--- /dev/null
+++ b/intg/src/main/resources/log4j.properties
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+log4j.rootLogger = INFO,console
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=INFO
+log4j.appender.console.Target=System.out
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} 
%-5p - %m%n
\ No newline at end of file
diff --git a/intg/src/test/java/org/apache/ranger/TestRangerClient.java 
b/intg/src/test/java/org/apache/ranger/TestRangerClient.java
new file mode 100644
index 0000000..08e1b38
--- /dev/null
+++ b/intg/src/test/java/org/apache/ranger/TestRangerClient.java
@@ -0,0 +1,150 @@
+/*
+ * 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;
+
+import com.sun.jersey.api.client.ClientResponse;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.util.RangerRESTClient;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.*;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.testng.annotations.BeforeMethod;
+
+import java.util.*;
+
+import javax.ws.rs.HttpMethod;
+import javax.ws.rs.core.Response;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.*;
+
+@RunWith(MockitoJUnitRunner.class)
+public class TestRangerClient {
+    private static final RangerClient.API GET_TEST_API  = new 
RangerClient.API("/relative/path/test", HttpMethod.GET, Response.Status.OK);
+
+
+    @BeforeMethod
+    public void setup() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    @Test
+    public void apiGet_Success() throws Exception {
+        try {
+            RangerRESTClient restClient = mock(RangerRESTClient.class);
+            ClientResponse   response   = mock(ClientResponse.class);
+            RangerClient     client     = new RangerClient(restClient);
+            RangerService    service    = new RangerService("testType", 
"testService", "MockedService", "testTag", new HashMap<>());
+
+            when(restClient.get(anyString(), any())).thenReturn(response);
+            
when(response.getStatus()).thenReturn(GET_TEST_API.getExpectedStatus().getStatusCode());
+            when(response.getEntity(RangerService.class)).thenReturn(service);
+
+            RangerService ret = client.getService(service.getName());
+
+            Assert.assertNotNull(ret);
+            Assert.assertEquals(ret.getName(), service.getName());
+        } catch(RangerServiceException excp){
+            Assert.fail("Not expected to fail! Found exception: " + excp);
+        }
+    }
+
+    @Test
+    public void apiGet_ServiceUnavailable() throws Exception {
+        try {
+            RangerRESTClient restClient = mock(RangerRESTClient.class);
+            ClientResponse   response   = mock(ClientResponse.class);
+            RangerClient     client     = new RangerClient(restClient);
+
+            when(restClient.get(anyString(), any())).thenReturn(response);
+            
when(response.getStatus()).thenReturn(ClientResponse.Status.SERVICE_UNAVAILABLE.getStatusCode());
+
+            RangerService ret = client.getService(1L);
+
+            Assert.assertNull(ret);
+        } catch(RangerServiceException excp){
+            Assert.fail("Not expected to fail! Found exception: " + excp);
+        }
+    }
+
+    @Test
+    public void apiGet_FailWithUnexpectedStatusCode() throws Exception {
+        try {
+            RangerRESTClient restClient = mock(RangerRESTClient.class);
+            ClientResponse   response   = mock(ClientResponse.class);
+            RangerClient     client     = new RangerClient(restClient);
+
+            when(restClient.get(anyString(), any())).thenReturn(response);
+            
when(response.getStatus()).thenReturn(ClientResponse.Status.INTERNAL_SERVER_ERROR.getStatusCode());
+
+            client.getService(1L);
+
+            Assert.fail("supposed to fail with RangerServiceException");
+        } catch(RangerServiceException excp) {
+            Assert.assertTrue(excp.getMessage().contains("statusCode=" + 
ClientResponse.Status.INTERNAL_SERVER_ERROR.getStatusCode()));
+            Assert.assertTrue(excp.getMessage().contains("status=" + 
ClientResponse.Status.INTERNAL_SERVER_ERROR.getReasonPhrase()));
+        }
+    }
+
+    @Test
+    public void apiGet_FailWithNullResponse() throws Exception {
+        try {
+            RangerRESTClient restClient = mock(RangerRESTClient.class);
+            RangerClient     client     = new RangerClient(restClient);
+
+            when(restClient.get(anyString(), any())).thenReturn(null);
+
+            client.getService(1L);
+
+            Assert.fail("supposed to fail with RangerServiceException");
+        } catch(RangerServiceException excp) {
+            Assert.assertTrue(excp.getMessage().contains("statusCode=null"));
+            Assert.assertTrue(excp.getMessage().contains("status=null"));
+        }
+    }
+
+    @Test
+    public void api_UrlMissingFormat() {
+        try {
+            new RangerClient.API("%dtest%dpath%d", HttpMethod.GET, 
Response.Status.OK).applyUrlFormat(1,1);
+            Assert.fail("supposed to fail with RangerServiceException");
+        } catch(RangerServiceException exp){
+            
Assert.assertTrue(exp.getMessage().contains("MissingFormatArgumentException"));
+        }
+    }
+
+    @Test
+    public void api_UrlIllegalFormatConversion() {
+        try {
+            new RangerClient.API("testpath%d", HttpMethod.GET, 
Response.Status.OK).applyUrlFormat("1");
+            Assert.fail("supposed to fail with RangerServiceException");
+        } catch(RangerServiceException exp){
+            
Assert.assertTrue(exp.getMessage().contains("IllegalFormatConversionException"));
+        }
+
+        try {
+            new RangerClient.API("testpath%f", HttpMethod.GET, 
Response.Status.OK).applyUrlFormat(1);
+            Assert.fail("supposed to fail with RangerServiceException");
+        } catch(RangerServiceException exp){
+            
Assert.assertTrue(exp.getMessage().contains("IllegalFormatConversionException"));
+        }
+    }
+}
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d798f6c..3e97f0a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -189,6 +189,7 @@
         <storm.version>1.2.0</storm.version>
         <sun-jersey-bundle.version>1.19</sun-jersey-bundle.version>
         <tomcat.embed.version>7.0.104</tomcat.embed.version>
+        <testng.version>6.9.4</testng.version>
         <velocity.version>1.7</velocity.version>
         <zookeeper.version>3.4.14</zookeeper.version>
         
<codehaus.woodstox.stax2api.version>3.1.4</codehaus.woodstox.stax2api.version>
@@ -233,6 +234,7 @@
                 <module>agents-audit</module>
                 <module>agents-common</module>
                 <module>agents-cred</module>
+                <module>intg</module>
                 <module>agents-installer</module>
                 <module>credentialbuilder</module>
                 <module>embeddedwebserver</module>
@@ -289,6 +291,14 @@
             </modules>
         </profile>
         <profile>
+            <id>ranger-examples</id>
+            <modules>
+                <module>agents-common</module>
+                <module>intg</module>
+                <module>ranger-examples</module>
+            </modules>
+        </profile>
+        <profile>
             <id>ranger-admin</id>
             <modules>
                 <module>agents-common</module>
@@ -600,6 +610,7 @@
                 <module>agents-audit</module>
                 <module>agents-common</module>
                 <module>agents-cred</module>
+                <module>intg</module>
                 <module>agents-installer</module>
                 <module>credentialbuilder</module>
                 <module>embeddedwebserver</module>
@@ -714,6 +725,12 @@
                 <scope>test</scope>
             </dependency>
             <dependency>
+                <groupId>org.testng</groupId>
+                <artifactId>testng</artifactId>
+                <version>${testng.version}</version>
+                <scope>test</scope>
+            </dependency>
+            <dependency>
                 <groupId>mysql</groupId>
                 <artifactId>mysql-connector-java</artifactId>
                 <version>${mysql-connector-java.version}</version>
diff --git a/ranger-examples/distro/pom.xml b/ranger-examples/distro/pom.xml
index ce62785..91849e5 100644
--- a/ranger-examples/distro/pom.xml
+++ b/ranger-examples/distro/pom.xml
@@ -54,6 +54,7 @@
                                     <descriptors>
                                         
<descriptor>src/main/assembly/sampleapp.xml</descriptor>
                                         
<descriptor>src/main/assembly/plugin-sampleapp.xml</descriptor>
+                                        
<descriptor>src/main/assembly/sample-client.xml</descriptor>
                                     </descriptors>
                                 </configuration>
                             </execution>
@@ -68,7 +69,7 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.ranger</groupId>
-            <artifactId>ranger-sampleapp-plugin</artifactId>
+            <artifactId>sample-client</artifactId>
             <version>${project.version}</version>
         </dependency>
     </dependencies>
diff --git a/ranger-examples/distro/src/main/assembly/sample-client.xml 
b/ranger-examples/distro/src/main/assembly/sample-client.xml
new file mode 100644
index 0000000..ea915a6
--- /dev/null
+++ b/ranger-examples/distro/src/main/assembly/sample-client.xml
@@ -0,0 +1,92 @@
+<?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.
+-->
+<assembly>
+    <id>sample-client</id>
+    <formats>
+        <format>tar.gz</format>
+    </formats>
+    
<baseDirectory>${project.name}-${project.version}-sample-client</baseDirectory>
+    <includeBaseDirectory>false</includeBaseDirectory>
+    <moduleSets>
+        <moduleSet>
+            <useAllReactorProjects>true</useAllReactorProjects>
+            <includes>
+                <include>org.apache.ranger:sample-client</include>
+                <include>org.apache.ranger:ranger-intg</include>
+                <include>org.apache.ranger:ranger-plugins-common</include>
+            </includes>
+            <binaries>
+                <outputDirectory>lib</outputDirectory>
+                <includeDependencies>true</includeDependencies>
+                <unpack>false</unpack>
+                <directoryMode>755</directoryMode>
+                <fileMode>644</fileMode>
+                <includes>
+                    <include>commons-cli:commons-cli</include>
+                    
<include>commons-logging:commons-logging:jar:${commons.logging.version}</include>
+                    <include>commons-lang:commons-lang</include>
+                    <include>com.google.code.gson:gson</include>
+                    
<include>org.slf4j:slf4j-api:jar:${slf4j-api.version}</include>
+                    <include>org.slf4j:slf4j-log4j12</include>
+                    <include>log4j:log4j</include>
+                    
<include>org.apache.commons:commons-configuration2:jar:${commons.configuration.version}</include>
+                    
<include>org.apache.hadoop:hadoop-common:jar:${hadoop.version}</include>
+                    
<include>org.apache.hadoop:hadoop-auth:jar:${hadoop.version}</include>
+                    <include>org.eclipse.persistence:eclipselink</include>
+                    
<include>org.eclipse.persistence:javax.persistence</include>
+                    <include>commons-collections:commons-collections</include>
+                    <include>com.sun.jersey:jersey-bundle</include>
+                    <include>commons-io:commons-io</include>
+                    
<include>com.google.guava:guava:jar:${google.guava.version}</include>
+                    
<include>org.apache.httpcomponents:httpmime:jar:${httpcomponents.httpmime.version}</include>
+                    <include>org.noggit:noggit:jar:${noggit.version}</include>
+                    <include>org.codehaus.jackson:jackson-core-asl</include>
+                    <include>org.codehaus.jackson:jackson-jaxrs</include>
+                    <include>org.codehaus.jackson:jackson-mapper-asl</include>
+                    <include>org.codehaus.jackson:jackson-xc</include>
+                    <include>org.apache.ranger:ranger-plugins-audit</include>
+                    
<include>com.kstruct:gethostname4j:jar:${kstruct.gethostname4j.version}</include>
+                    <include>net.java.dev.jna:jna:jar:${jna.version}</include>
+                    
<include>net.java.dev.jna:jna-platform:jar:${jna-platform.version}</include>
+                    
<include>com.fasterxml.woodstox:woodstox-core:jar:${fasterxml.woodstox.version}</include>
+                    
<include>org.codehaus.woodstox:stax2-api:jar:${codehaus.woodstox.stax2api.version}</include>
+                </includes>
+            </binaries>
+        </moduleSet>
+    </moduleSets>
+
+    <fileSets>
+        <fileSet>
+            <outputDirectory></outputDirectory>
+            
<directory>${project.parent.basedir}/sample-client/scripts</directory>
+            <includes>
+                <include>*.sh</include>
+            </includes>
+            <fileMode>755</fileMode>
+        </fileSet>
+        <fileSet>
+            <directoryMode>755</directoryMode>
+            <fileMode>644</fileMode>
+            <outputDirectory>lib</outputDirectory>
+            <directory>../sample-client/src/main/resources</directory>
+            <includes>
+                <include>*.properties</include>
+            </includes>
+        </fileSet>
+    </fileSets>
+</assembly>
diff --git a/ranger-examples/pom.xml b/ranger-examples/pom.xml
index b3ceed4..ed35be8 100644
--- a/ranger-examples/pom.xml
+++ b/ranger-examples/pom.xml
@@ -29,5 +29,6 @@
         <module>sampleapp</module>
         <module>plugin-sampleapp</module>
         <module>distro</module>
+        <module>sample-client</module>
     </modules>
 </project>
diff --git a/ranger-examples/sample-client/pom.xml 
b/ranger-examples/sample-client/pom.xml
new file mode 100644
index 0000000..1e205a4
--- /dev/null
+++ b/ranger-examples/sample-client/pom.xml
@@ -0,0 +1,60 @@
+<?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";>
+    <parent>
+        <artifactId>ranger-examples</artifactId>
+        <groupId>org.apache.ranger</groupId>
+        <version>2.1.0-SNAPSHOT</version>
+    </parent>
+    <packaging>jar</packaging>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>sample-client</artifactId>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-intg</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.ranger</groupId>
+            <artifactId>ranger-plugins-common</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-cli</groupId>
+            <artifactId>commons-cli</artifactId>
+            <version>${commons.cli.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.guava</groupId>
+            <artifactId>guava</artifactId>
+            <version>${google.guava.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <version>${slf4j-api.version}</version>
+        </dependency>
+    </dependencies>
+</project>
\ No newline at end of file
diff --git a/ranger-examples/sample-client/scripts/run-sample-client.sh 
b/ranger-examples/sample-client/scripts/run-sample-client.sh
new file mode 100644
index 0000000..2260476
--- /dev/null
+++ b/ranger-examples/sample-client/scripts/run-sample-client.sh
@@ -0,0 +1,50 @@
+#!/bin/bash
+
+# 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.
+
+usage() {
+  echo "usage: run-sample-client.sh
+  -n <arg> Hostname to connect to
+  -h       show help."
+  exit 1
+}
+JARS=
+  for i in lib/*.jar
+do
+    JARS="${JARS}:$i"
+done
+JAVA_CMD="java -Dlog4j.configuration=file:lib/log4j.properties -cp ${JARS} 
org.apache.ranger.examples.sampleclient.SampleClient"
+while getopts "n:h" opt; do
+  case $opt in
+    n) HOST=$OPTARG
+       JAVA_CMD="$JAVA_CMD -h $HOST"
+       ;;
+    h) usage
+       ;;
+    \?) echo -e \\n"Option -$OPTARG not allowed."
+       usage
+       ;;
+  esac
+done
+
+prompt="Sample Authentication User Name:"
+read -p "$prompt" userName
+prompt="Sample Authentication User Password:"
+read -p "$prompt" -s password
+printf "\n"
+JAVA_CMD="$JAVA_CMD -u $userName -p $password"
+printf "Java command : $JAVA_CMD\n"
+$JAVA_CMD
\ No newline at end of file
diff --git 
a/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java
 
b/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java
new file mode 100644
index 0000000..b6ab313
--- /dev/null
+++ 
b/ranger-examples/sample-client/src/main/java/org/apache/ranger/examples/sampleclient/SampleClient.java
@@ -0,0 +1,193 @@
+/*
+ * 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.examples.sampleclient;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.commons.cli.*;
+import org.apache.ranger.RangerClient;
+import org.apache.ranger.RangerServiceException;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerRole;
+import org.apache.ranger.plugin.model.RangerService;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.*;
+
+public class SampleClient {
+    private static final Logger LOG = 
LoggerFactory.getLogger(SampleClient.class);
+
+
+    @SuppressWarnings("static-access")
+    public static void main(String[] args) throws RangerServiceException {
+        Gson gsonBuilder = new 
GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").setPrettyPrinting().create();
+        Options options  = new Options();
+
+        Option host = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("host").withDescription("hostname").create('h');
+        Option user = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("user").withDescription("username").create('u');
+        Option pass = 
OptionBuilder.hasArgs(1).isRequired().withLongOpt("pass").withDescription("password").create('p');
+
+        options.addOption(host);
+        options.addOption(user);
+        options.addOption(pass);
+
+        CommandLineParser parser = new BasicParser();
+        CommandLine cmd;
+
+        try {
+            cmd = parser.parse(options, args);
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        String hostName = cmd.getOptionValue('h');
+        String userName = cmd.getOptionValue('u');
+        String password = cmd.getOptionValue('p');
+
+        RangerClient rangerClient = new RangerClient(hostName, userName, 
password);
+
+        String serviceDefName     = "sampleServiceDef";
+        String serviceName        = "sampleService";
+        String policyName         = "samplePolicy";
+        String roleName           = "sampleRole";
+        Map<String,String> filter = Collections.emptyMap();
+
+
+        /*
+        Create a new Service Definition
+         */
+
+        RangerServiceDef.RangerServiceConfigDef config = new 
RangerServiceDef.RangerServiceConfigDef();
+        config.setItemId(1L);
+        config.setName("sampleConfig");
+        config.setType("string");
+        List<RangerServiceDef.RangerServiceConfigDef> configs = 
Collections.singletonList(config);
+
+        RangerServiceDef.RangerAccessTypeDef accessType = new 
RangerServiceDef.RangerAccessTypeDef();
+        accessType.setItemId(1L);
+        accessType.setName("sampleAccess");
+        List<RangerServiceDef.RangerAccessTypeDef> accessTypes = 
Collections.singletonList(accessType);
+
+        RangerServiceDef.RangerResourceDef resourceDef = new 
RangerServiceDef.RangerResourceDef();
+        resourceDef.setItemId(1L);
+        resourceDef.setName("root");
+        resourceDef.setType("string");
+        List<RangerServiceDef.RangerResourceDef> resourceDefs = 
Collections.singletonList(resourceDef);
+
+        RangerServiceDef serviceDef = new RangerServiceDef();
+        serviceDef.setName(serviceDefName);
+        serviceDef.setConfigs(configs);
+        serviceDef.setAccessTypes(accessTypes);
+        serviceDef.setResources(resourceDefs);
+
+        RangerServiceDef createdServiceDef = 
rangerClient.createServiceDef(serviceDef);
+        LOG.info("New Service Definition created successfully {}", 
gsonBuilder.toJson(createdServiceDef));
+
+        /*
+        Create a new Service
+         */
+        RangerService service = new RangerService();
+        service.setType(serviceDefName);
+        service.setName(serviceName);
+
+        RangerService createdService = rangerClient.createService(service);
+        LOG.info("New Service created successfully {}", 
gsonBuilder.toJson(createdService));
+
+        /*
+        Policy Management
+         */
+
+
+        /*
+        Create a new Policy
+         */
+        Map<String, RangerPolicy.RangerPolicyResource> resource = 
Collections.singletonMap(
+                "root", new 
RangerPolicy.RangerPolicyResource(Collections.singletonList("/path/to/sample/resource"),false,false));
+        RangerPolicy policy = new RangerPolicy();
+        policy.setService(serviceName);
+        policy.setName(policyName);
+        policy.setResources(resource);
+
+        RangerPolicy createdPolicy = rangerClient.createPolicy(policy);
+        LOG.info("New Policy created successfully {}", 
gsonBuilder.toJson(createdPolicy));
+
+        /*
+        Get a policy by name
+         */
+        RangerPolicy fetchedPolicy = rangerClient.getPolicy(serviceName, 
policyName);
+        LOG.info("Policy: {} fetched {}", policyName, 
gsonBuilder.toJson(fetchedPolicy));
+
+
+        /*
+        Delete a policy
+         */
+        rangerClient.deletePolicy(serviceName, policyName);
+        LOG.info("Policy {} successfully deleted", policyName);
+
+
+        /*
+        Delete a Service
+         */
+        rangerClient.deleteService(serviceName);
+        LOG.info("Service {} successfully deleted", serviceName);
+
+
+        /*
+        Delete a Service Definition
+         */
+        rangerClient.deleteServiceDef(serviceDefName);
+        LOG.info("Service Definition {} successfully deleted", serviceDefName);
+
+
+        /*
+        Role Management
+         */
+
+        /*
+        Create a role in Ranger
+         */
+        RangerRole sampleRole = new RangerRole();
+        sampleRole.setName(roleName);
+        sampleRole.setDescription("Sample Role");
+        sampleRole.setUsers(Collections.singletonList(new 
RangerRole.RoleMember(null,true)));
+        sampleRole = rangerClient.createRole(serviceName, sampleRole);
+        LOG.info("New Role successfully created {}", 
gsonBuilder.toJson(sampleRole));
+
+        /*
+        Update a role in Ranger
+         */
+        sampleRole.setDescription("Updated Sample Role");
+        RangerRole updatedRole = rangerClient.updateRole(sampleRole.getId(), 
sampleRole);
+        LOG.info("Role {} successfully updated {}", roleName, 
gsonBuilder.toJson(updatedRole));
+
+        /*
+        Get all roles in Ranger
+         */
+        List<RangerRole> allRoles = rangerClient.findRoles(filter);
+        LOG.info("List of Roles {}", gsonBuilder.toJson(allRoles));
+
+        /*
+        Delete a role in Ranger
+         */
+        rangerClient.deleteRole(roleName, userName, serviceName);
+        LOG.info("Role {} successfully deleted", roleName);
+    }
+}
diff --git a/ranger-examples/sample-client/src/main/resources/log4j.properties 
b/ranger-examples/sample-client/src/main/resources/log4j.properties
new file mode 100644
index 0000000..9c8bd00
--- /dev/null
+++ b/ranger-examples/sample-client/src/main/resources/log4j.properties
@@ -0,0 +1,23 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+log4j.rootLogger = INFO,console
+log4j.appender.console=org.apache.log4j.ConsoleAppender
+log4j.appender.console.Threshold=INFO
+log4j.appender.console.Target=System.out
+log4j.appender.console.layout=org.apache.log4j.PatternLayout
+log4j.appender.console.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} 
%-5p - %m%n
\ No newline at end of file

Reply via email to