Repository: incubator-ranger Updated Branches: refs/heads/tag-policy 3852419c3 -> 001ec8837
RANGER-660: TagSync process implementation - initial version Signed-off-by: Madhan Neethiraj <[email protected]> Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/001ec883 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/001ec883 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/001ec883 Branch: refs/heads/tag-policy Commit: 001ec88376cf51d43174aa3631e18b512bdd1333 Parents: 3852419 Author: Abhay Kulkarni <[email protected]> Authored: Tue Sep 22 15:55:56 2015 -0700 Committer: Madhan Neethiraj <[email protected]> Committed: Tue Sep 22 17:23:34 2015 -0700 ---------------------------------------------------------------------- pom.xml | 2 + src/main/assembly/tagsync.xml | 105 ++++ tagsync/conf.dist/log4j.xml | 42 ++ .../conf.dist/ranger-tagsync-default-site.xml | 36 ++ tagsync/pom.xml | 112 ++++ tagsync/scripts/initd | 78 +++ tagsync/scripts/ranger-tagsync-services.sh | 110 ++++ .../java/org/apache/ranger/model/TagSink.java | 35 ++ .../java/org/apache/ranger/model/TagSource.java | 52 ++ .../apache/ranger/process/TagSyncConfig.java | 326 ++++++++++++ .../apache/ranger/process/TagSynchronizer.java | 187 +++++++ .../ranger/sink/policymgr/TagRESTSink.java | 515 +++++++++++++++++++ .../ranger/source/file/TagFileSource.java | 427 +++++++++++++++ .../src/main/resources/application.properties | 29 ++ .../main/resources/etc/ranger/data/tags.json | 75 +++ .../src/main/resources/ranger-tagsync-site.xml | 67 +++ .../ranger/process/TestTagSynchronizer.java | 96 ++++ tagsync/src/test/resources/log4j.properties | 35 ++ 18 files changed, 2329 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/pom.xml ---------------------------------------------------------------------- diff --git a/pom.xml b/pom.xml index 84ecf24..aa40882 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,7 @@ <module>unixauthservice</module> <module>ranger-util</module> <module>plugin-kms</module> + <module>tagsync</module> </modules> <properties> <javac.source.version>1.7</javac.source.version> @@ -388,6 +389,7 @@ <descriptor>src/main/assembly/plugin-solr.xml</descriptor> <descriptor>src/main/assembly/admin-web.xml</descriptor> <descriptor>src/main/assembly/usersync.xml</descriptor> + <descriptor>src/main/assembly/tagsync.xml</descriptor> <descriptor>src/main/assembly/migration-util.xml</descriptor> <descriptor>src/main/assembly/kms.xml</descriptor> <descriptor>src/main/assembly/ranger-src.xml</descriptor> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/src/main/assembly/tagsync.xml ---------------------------------------------------------------------- diff --git a/src/main/assembly/tagsync.xml b/src/main/assembly/tagsync.xml new file mode 100644 index 0000000..d7262ac --- /dev/null +++ b/src/main/assembly/tagsync.xml @@ -0,0 +1,105 @@ +<?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>tagsync</id> + <formats> + <format>tar.gz</format> + <format>zip</format> + </formats> + <baseDirectory>${project.name}-${project.version}-tagsync</baseDirectory> + <includeBaseDirectory>true</includeBaseDirectory> + <moduleSets> + <moduleSet> + <binaries> + <includeDependencies>false</includeDependencies> + <unpack>false</unpack> + <directoryMode>755</directoryMode> + <fileMode>644</fileMode> + <dependencySets> + <dependencySet> + <outputDirectory>/lib</outputDirectory> + <includes> + <include>com.google.code.gson:gson</include> + <include>com.sun.jersey:jersey-bundle</include> + <include>log4j:log4j</include> + <include>commons-cli:commons-cli</include> + <include>commons-collections:commons-collections</include> + <include>commons-configuration:commons-configuration</include> + <include>commons-lang:commons-lang</include> + <include>commons-logging:commons-logging</include> + <include>com.google.guava:guava</include> + <include>org.apache.hadoop:hadoop-auth</include> + <include>org.slf4j:slf4j-api</include> + <include>org.apache.hadoop:hadoop-common</include> + <include>org.apache.commons:commons-csv</include> + <include>org.apache.ranger:credentialbuilder</include> + <include>org.apache.ranger:ranger-util</include> + <include>commons-io:commons-io:jar:${commons.io.version}</include> + <include>org.apache.htrace:htrace-core</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>security_plugins.ranger-plugins-common:ranger-plugins-common</include> + </includes> + <unpack>false</unpack> + </dependencySet> + </dependencySets> + <outputDirectory>/dist</outputDirectory> + </binaries> + <includes> + <include>org.apache.ranger:ranger-tagsync</include> + </includes> + </moduleSet> + </moduleSets> + <fileSets> + <fileSet> + <directoryMode>755</directoryMode> + <fileMode>644</fileMode> + <outputDirectory>/conf.dist</outputDirectory> + <directory>tagsync/conf.dist</directory> + </fileSet> + <fileSet> + <directoryMode>755</directoryMode> + <fileMode>544</fileMode> + <outputDirectory>/</outputDirectory> + <directory>tagsync/scripts</directory> + <excludes> + <exclude>*.properties</exclude> + <exclude>initd</exclude> + </excludes> + </fileSet> + <fileSet> + <directoryMode>755</directoryMode> + <outputDirectory>/</outputDirectory> + <directory>${project.build.directory}</directory> + <includes> + <include>version</include> + </includes> + <fileMode>444</fileMode> + </fileSet> + </fileSets> + <files> + <file> + <source>tagsync/scripts/initd</source> + <outputDirectory>/</outputDirectory> + <destName>ranger-usersync.sh</destName> + <fileMode>755</fileMode> + </file> + </files> +</assembly> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/conf.dist/log4j.xml ---------------------------------------------------------------------- diff --git a/tagsync/conf.dist/log4j.xml b/tagsync/conf.dist/log4j.xml new file mode 100644 index 0000000..fb6986f --- /dev/null +++ b/tagsync/conf.dist/log4j.xml @@ -0,0 +1,42 @@ +<?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. +--> +<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> + +<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true"> + + <appender name="logFile" class="org.apache.log4j.DailyRollingFileAppender"> + <param name="file" value="${logdir}/tagsync.log" /> + <param name="DatePattern" value="'.'yyyy-MM-dd" /> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{dd MMM yyyy HH:mm:ss} %5p %c{1} [%t] - %m%n"/> + </layout> + </appender> + + <appender name="console" class="org.apache.log4j.ConsoleAppender"> + <param name="Target" value="System.out"/> + <layout class="org.apache.log4j.PatternLayout"> + <param name="ConversionPattern" value="%d{dd MMM yyyy HH:mm:ss} %5p %c{1} [%t] - %m%n"/> + </layout> + </appender> + + <root> + <priority value ="info" /> + <appender-ref ref="logFile" /> + </root> + +</log4j:configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/conf.dist/ranger-tagsync-default-site.xml ---------------------------------------------------------------------- diff --git a/tagsync/conf.dist/ranger-tagsync-default-site.xml b/tagsync/conf.dist/ranger-tagsync-default-site.xml new file mode 100644 index 0000000..b098740 --- /dev/null +++ b/tagsync/conf.dist/ranger-tagsync-default-site.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<?xml-stylesheet type="text/xsl" href="configuration.xsl"?> +<!-- + Licensed 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. See accompanying LICENSE file. +--> + +<!-- Put site-specific property overrides in this file. --> + +<configuration> + <property> + <name>ranger.tagsync.port</name> + <value>6161</value> + </property> + <property> + <name>ranger.tagsync.ssl</name> + <value>true</value> + </property> + <property> + <name>ranger.tagsync.enabled</name> + <value>true</value> + </property> + <property> + <name>ranger.tagsync.logdir</name> + <value>./log</value> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/pom.xml ---------------------------------------------------------------------- diff --git a/tagsync/pom.xml b/tagsync/pom.xml new file mode 100644 index 0000000..83011d2 --- /dev/null +++ b/tagsync/pom.xml @@ -0,0 +1,112 @@ +<?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-tagsync</artifactId> + <name>Tag Synchronizer</name> + <description>Tag Synchronizer Java Process</description> + <packaging>jar</packaging> + + <parent> + <artifactId>ranger</artifactId> + <groupId>org.apache.ranger</groupId> + <version>0.5.0</version> + </parent> + + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencies> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + <version>${junit.version}</version> + <scope>test</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <version>${log4j.version}</version> + </dependency> + <dependency> + <groupId>com.google.code.gson</groupId> + <artifactId>gson</artifactId> + </dependency> + <dependency> + <groupId>com.sun.jersey</groupId> + <artifactId>jersey-bundle</artifactId> + <version>${jersey-bundle.version}</version> + </dependency> + <dependency> + <groupId>commons-cli</groupId> + <artifactId>commons-cli</artifactId> + <version>${commons.cli.version}</version> + </dependency> + <dependency> + <groupId>commons-collections</groupId> + <artifactId>commons-collections</artifactId> + <version>${commons.collections.version}</version> + </dependency> + <dependency> + <groupId>commons-configuration</groupId> + <artifactId>commons-configuration</artifactId> + <version>${commons.configuration.version}</version> + </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>${commons.lang.version}</version> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + <version>${commons.logging.version}</version> + </dependency> + <dependency> + <groupId>security_plugins.ranger-plugins-common</groupId> + <artifactId>ranger-plugins-common</artifactId> + <version>${project.version}</version> + </dependency> + <!-- + <dependency> + <groupId>com.google.inject</groupId> + <artifactId>guice</artifactId> + <version>4.0</version> + </dependency> + <dependency> + <groupId>org.apache.atlas</groupId> + <artifactId>atlas-notification</artifactId> + <version>0.6-incubating-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.atlas</groupId> + <artifactId>atlas-typesystem</artifactId> + <version>0.6-incubating-SNAPSHOT</version> + </dependency> + <dependency> + <groupId>org.apache.atlas</groupId> + <artifactId>atlas-client</artifactId> + <version>0.6-incubating-SNAPSHOT</version> + </dependency> + --> + </dependencies> +</project> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/scripts/initd ---------------------------------------------------------------------- diff --git a/tagsync/scripts/initd b/tagsync/scripts/initd new file mode 100644 index 0000000..9349fae --- /dev/null +++ b/tagsync/scripts/initd @@ -0,0 +1,78 @@ +#!/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. + +### BEGIN INIT INFO +# Provides: ranger-tagsync +# Required-Start: $local_fs $remote_fs $network $named $syslog $time +# Required-Stop: $local_fs $remote_fs $network $named $syslog $time +# Default-Start: 2 3 4 5 +# Default-Stop: +# Short-Description: Start/Stop Ranger tagsync +### END INIT INFO + +LINUX_USER=ranger +BIN_PATH=/usr/bin +MOD_NAME=ranger-tagsync-services.sh +pidf=/var/run/ranger/tagsync.pid +pid="" +if [ -f ${pidf} ] +then + pid=`cat $pidf` +fi + +case $1 in + start) + if [ "${pid}" != "" ] + then + echo "Ranger tagsync Service is already running" + exit 1 + else + echo "Starting Ranger tagsync." + /bin/su --login $LINUX_USER -c "${BIN_PATH}/${MOD_NAME} start" + fi + ;; + stop) + if [ "${pid}" != "" ] + then + echo "Stopping Ranger tagsync." + /bin/su --login $LINUX_USER -c "${BIN_PATH}/${MOD_NAME} stop" + else + echo "Ranger tagsync Service is NOT running" + exit 1 + fi + ;; + restart) + if [ "${pid}" != "" ] + then + echo "Stopping Ranger tagsync." + /bin/su --login $LINUX_USER -c "${BIN_PATH}/${MOD_NAME} stop" + sleep 10 + fi + echo "Starting Ranger tagsync." + /bin/su --login $LINUX_USER -c "${BIN_PATH}/${MOD_NAME} start" + ;; + status) + if [ "${pid}" != "" ] + then + echo "Ranger tagsync Service is running [pid={$pid}]" + else + echo "Ranger tagsync Service is NOT running." + fi + ;; + *) + echo "Invalid argument [$1]; Only start | stop | restart | status, are supported." + exit 1 + esac http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/scripts/ranger-tagsync-services.sh ---------------------------------------------------------------------- diff --git a/tagsync/scripts/ranger-tagsync-services.sh b/tagsync/scripts/ranger-tagsync-services.sh new file mode 100755 index 0000000..5ca5b95 --- /dev/null +++ b/tagsync/scripts/ranger-tagsync-services.sh @@ -0,0 +1,110 @@ +#!/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. + +if [[ -z $1 ]]; then + echo "Invalid argument [$1];" + echo "Usage: Only start | stop | restart | version, are supported." + exit; +fi +action=$1 +action=`echo $action | tr '[:lower:]' '[:upper:]'` +realScriptPath=`readlink -f $0` +realScriptDir=`dirname $realScriptPath` +cd $realScriptDir +cdir=`pwd` + +pidf=/var/run/ranger/tagsync.pid + + +if [ "${action}" == "START" ]; then + + #Export JAVA_HOME + if [ -f ${cdir}/conf/java_home.sh ]; then + . ${cdir}/conf/java_home.sh + fi + + for custom_env_script in `find ${cdir}/conf/ -name "ranger-tagsync-env*"`; do + if [ -f $custom_env_script ]; then + . $custom_env_script + fi + done + + if [ "$JAVA_HOME" != "" ]; then + export PATH=$JAVA_HOME/bin:$PATH + fi + + logdir=/var/log/ranger/tagsync + + cp="${cdir}/dist/*:${cdir}/lib/*:${cdir}/conf" + + if [ -f $pidf ]; then + PID=`cat $pidf` + if [ -z "`ps axf | grep ${PID} | grep -v grep`" ]; then + rm -f ${pidf} + else + kill -9 ${PID} > /dev/null 2>&1 + rm -f ${pidf} + echo "Ranger Tagsync Service [pid = ${PID}] has been stopped." + fi + fi + + cd ${cdir} + umask 0077 + nohup java -Dproc_rangertagsync ${JAVA_OPTS} -Dlogdir="${logdir}" -cp "${cp}" org.apache.ranger.process.TagSynchronizer > ${logdir}/tagsync.log 2>&1 & + echo $! > ${pidf} + chown ranger ${pidf} + sleep 5 + pid=`cat $pidf` + + if [ "${pid}" != "" ] + then + echo "Ranger Tagsync Service has started successfully." + else + echo "Ranger Tagsync Service failed to start. Please refer to log files under ${logdir} for further details." + fi + exit; + +elif [ "${action}" == "STOP" ]; then + + if [ -f $pidf ]; then + pidf=/var/run/ranger/tagsync.pid + PID=`cat $pidf` > /dev/null 2>&1 + kill -9 $PID > /dev/null 2>&1 + rm -f $pidf + echo "Ranger Tagsync Service [pid = ${PID}] has been stopped." + else + echo "Ranger Tagsync Service not running" + fi + + exit; + +elif [ "${action}" == "RESTART" ]; then + echo "Stopping Ranger Tagsync" + ${cdir}/ranger-tagsync-services.sh stop + echo "Starting Apache Ranger Tagsync" + ${cdir}/ranger-tagsync-services.sh start + exit; +elif [ "${action}" == "VERSION" ]; then + cd ${cdir}/lib + java -cp ranger-util-*.jar org.apache.ranger.common.RangerVersionInfo + exit +else + echo "Invalid argument [$1];" + echo "Usage: Only start | stop | restart | version, are supported." + exit; +fi + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/java/org/apache/ranger/model/TagSink.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/model/TagSink.java b/tagsync/src/main/java/org/apache/ranger/model/TagSink.java new file mode 100644 index 0000000..74ea5cf --- /dev/null +++ b/tagsync/src/main/java/org/apache/ranger/model/TagSink.java @@ -0,0 +1,35 @@ +/* + * 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.model; + +import org.apache.ranger.plugin.store.TagStore; +import org.apache.ranger.plugin.util.ServiceTags; + +import java.util.Map; +import java.util.Properties; + + +/** + * Created by akulkarni on 9/10/15. + */ +public interface TagSink extends TagStore { + boolean initialize(Properties properties); + void uploadServiceTags(ServiceTags serviceTags) throws Exception; +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/java/org/apache/ranger/model/TagSource.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/model/TagSource.java b/tagsync/src/main/java/org/apache/ranger/model/TagSource.java new file mode 100644 index 0000000..568d3c7 --- /dev/null +++ b/tagsync/src/main/java/org/apache/ranger/model/TagSource.java @@ -0,0 +1,52 @@ +/* + * 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.model; + +import org.apache.ranger.plugin.model.RangerTagDef; +import org.apache.ranger.plugin.model.RangerTagResourceMap; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Created by akulkarni on 9/10/15. + */ +public interface TagSource { + + boolean initialize(Properties properties); + + void setTagSink(TagSink sink); + + void updateSink() throws Exception; + + void start(); + + boolean isChanged(); + + List<RangerTagDef> fetchAllTagDefs(String syncSentinel) throws Exception; + + List<RangerTagDef> receiveUpdatesToTagDefs() throws Exception; + + List<RangerTagResourceMap> fetchAllTaggedEntities() throws Exception; + + List<RangerTagResourceMap> receiveUpdatesToTaggedEntities() throws Exception; + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/java/org/apache/ranger/process/TagSyncConfig.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/process/TagSyncConfig.java b/tagsync/src/main/java/org/apache/ranger/process/TagSyncConfig.java new file mode 100644 index 0000000..1c995b1 --- /dev/null +++ b/tagsync/src/main/java/org/apache/ranger/process/TagSyncConfig.java @@ -0,0 +1,326 @@ +/* + * 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.process; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.*; +import java.net.URL; +import java.util.Properties; + +/** + * Created by akulkarni on 9/11/15. + */ +public class TagSyncConfig { + private static final Logger LOG = Logger.getLogger(TagSyncConfig.class) ; + + public static final String CONFIG_FILE = "ranger-tagsync-site.xml"; + + public static final String DEFAULT_CONFIG_FILE = "ranger-tagsync-default-site.xml"; + + public static final String TAGSYNC_ENABLED_PROP = "ranger.tagsync.enabled" ; + + public static final String TAGSYNC_PORT_PROP = "ranger.tagsync.port" ; + + public static final String TAGSYNC_SSL_PROP = "ranger.tagsync.ssl" ; + + public static final String TAGSYNC_LOGDIR_PROP = "ranger.tagsync.logdir" ; + + private static final String TAGSYNC_PM_URL_PROP = "ranger.tagsync.policymanager.baseURL"; + + private static final String TAGSYNC_PM_SSL_CONFIG_FILE_PROP = "ranger.tagsync.policymanager.ssl.config.file"; + + private static final String TAGSYNC_PM_SSL_BASICAUTH_USERNAME_PROP = "ranger.tagsync.policymanager.basicauth.username"; + + private static final String TAGSYNC_PM_SSL_BASICAUTH_PASSWORD_PROP = "ranger.tagsync.policymanager.basicauth.password"; + + private static final String TAGSYNC_SOURCE_FILE_PROP = "ranger.tagsync.source.file"; + + private static final String TAGSYNC_SLEEP_TIME_IN_MILLIS_BETWEEN_CYCLE_PROP = "ranger.tagsync.sleeptimeinmillisbetweensynccycle"; + + private static final String TAGSYNC_SOURCE_CLASS_PROP = "ranger.tagsync.source.impl.class"; + + private static final String TAGSYNC_SINK_CLASS_PROP = "ranger.tagsync.sink.impl.class"; + + private static final String TAGSYNC_SOURCE_ATLAS_PROP = "atlas.endpoint"; + + private static volatile TagSyncConfig instance = null; + + private Properties prop = new Properties() ; + + public static TagSyncConfig getInstance() { + /* + TagSyncConfig ret = instance; + if (ret == null) { + synchronized(TagSyncConfig.class) { + if (ret == null) { + ret = instance = new TagSyncConfig(); + LOG.debug("TagSyncConfig = {" + ret + "}"); + } + } + } + */ + TagSyncConfig newConfig = new TagSyncConfig(); + newConfig.init(); + return newConfig; + } + + public Properties getProperties() { + return prop; + } + + public static InputStream getFileInputStream(String path) throws FileNotFoundException { + + InputStream ret = null; + + File f = new File(path); + + if (f.exists() && f.isFile() && f.canRead()) { + ret = new FileInputStream(f); + } else { + ret = TagSyncConfig.class.getResourceAsStream(path); + + if (ret == null) { + if (! path.startsWith("/")) { + ret = TagSyncConfig.class.getResourceAsStream("/" + path); + } + } + + if (ret == null) { + ret = ClassLoader.getSystemClassLoader().getResourceAsStream(path) ; + if (ret == null) { + if (! path.startsWith("/")) { + ret = ClassLoader.getSystemResourceAsStream("/" + path); + } + } + } + } + + return ret; + } + + public static String getResourceFileName(String path) { + + String ret = null; + + if (StringUtils.isNotBlank(path)) { + + File f = new File(path); + + if (f.exists() && f.isFile() && f.canRead()) { + ret = path; + } else { + + URL fileURL = TagSyncConfig.class.getResource(path); + if (fileURL == null) { + if (!path.startsWith("/")) { + fileURL = TagSyncConfig.class.getResource("/" + path); + } + } + + if (fileURL == null) { + fileURL = ClassLoader.getSystemClassLoader().getResource(path); + if (fileURL == null) { + if (!path.startsWith("/")) { + fileURL = ClassLoader.getSystemClassLoader().getResource("/" + path); + } + } + } + + if (fileURL != null) { + try { + ret = fileURL.getFile(); + } catch (Exception exception) { + LOG.error(path + " is not a file", exception); + } + } else { + LOG.error("URL not found for " + path + " or no privilege for reading file " + path); + } + } + } + + return ret; + } + + @Override + public String toString() { + StringBuffer sb = new StringBuffer(); + + sb.append("CONFIG_FILE=").append(CONFIG_FILE).append(", ") + .append("DEFAULT_CONFIG_FILE=").append(DEFAULT_CONFIG_FILE).append("\n"); + + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outputStream); + prop.list(printStream); + printStream.close(); + sb.append(outputStream.toString()); + + return sb.toString(); + } + + static public boolean isTagSyncEnabled(Properties prop) { + String val = prop.getProperty(TAGSYNC_ENABLED_PROP); + return !(val != null && val.trim().equalsIgnoreCase("falae")); + } + + static public String getTagSyncPort(Properties prop) { + String val = prop.getProperty(TAGSYNC_PORT_PROP); + return val; + } + + static public boolean isTagSyncSsl(Properties prop) { + String val = prop.getProperty(TAGSYNC_SSL_PROP); + return (val != null && val.trim().equalsIgnoreCase("true")); + } + + static public String getTagSyncLogdir(Properties prop) { + String val = prop.getProperty(TAGSYNC_LOGDIR_PROP); + return val; + } + + static public long getSleepTimeInMillisBetweenCycle(Properties prop) { + String val = prop.getProperty(TAGSYNC_SLEEP_TIME_IN_MILLIS_BETWEEN_CYCLE_PROP); + return Long.valueOf(val); + } + + static public String getTagSourceClassName(Properties prop) { + String val = prop.getProperty(TAGSYNC_SOURCE_CLASS_PROP); + return val; + } + + static public String getTagSinkClassName(Properties prop) { + String val = prop.getProperty(TAGSYNC_SINK_CLASS_PROP); + return val; + } + + static public String getPolicyMgrUrl(Properties prop) { + String val = prop.getProperty(TAGSYNC_PM_URL_PROP); + return val; + } + + static public String getPolicyMgrSslConfigFile(Properties prop) { + String val = prop.getProperty(TAGSYNC_PM_SSL_CONFIG_FILE_PROP); + return val; + } + + static public String getPolicyMgrUserName(Properties prop) { + String val = prop.getProperty(TAGSYNC_PM_SSL_BASICAUTH_USERNAME_PROP); + return val; + } + + static public String getPolicyMgrPassword(Properties prop) { + String val = prop.getProperty(TAGSYNC_PM_SSL_BASICAUTH_PASSWORD_PROP); + return val; + } + + static public String getTagSourceFileName(Properties prop) { + String val = prop.getProperty(TAGSYNC_SOURCE_FILE_PROP); + return val; + } + + static public String getAtlasEndpoint(Properties prop) { + String val = prop.getProperty(TAGSYNC_SOURCE_ATLAS_PROP); + return val; + } + + static public String getAtlasSslConfigFileName(Properties prop) { + return ""; + } + + private TagSyncConfig() { + init() ; + } + + private void init() { + readConfigFile(CONFIG_FILE); + readConfigFile(DEFAULT_CONFIG_FILE); + } + + private void readConfigFile(String fileName) { + try { + InputStream in = getFileInputStream(fileName); + if (in != null) { + try { + DocumentBuilderFactory xmlDocumentBuilderFactory = DocumentBuilderFactory + .newInstance(); + xmlDocumentBuilderFactory.setIgnoringComments(true); + xmlDocumentBuilderFactory.setNamespaceAware(true); + DocumentBuilder xmlDocumentBuilder = xmlDocumentBuilderFactory + .newDocumentBuilder(); + Document xmlDocument = xmlDocumentBuilder.parse(in); + xmlDocument.getDocumentElement().normalize(); + + NodeList nList = xmlDocument + .getElementsByTagName("property"); + + for (int temp = 0; temp < nList.getLength(); temp++) { + + Node nNode = nList.item(temp); + + if (nNode.getNodeType() == Node.ELEMENT_NODE) { + + Element eElement = (Element) nNode; + + String propertyName = ""; + String propertyValue = ""; + if (eElement.getElementsByTagName("name").item( + 0) != null) { + propertyName = eElement + .getElementsByTagName("name") + .item(0).getTextContent().trim(); + } + if (eElement.getElementsByTagName("value") + .item(0) != null) { + propertyValue = eElement + .getElementsByTagName("value") + .item(0).getTextContent().trim(); + } + + if (prop.get(propertyName) != null) { + prop.remove(propertyName) ; + } + + prop.put(propertyName, propertyValue); + + } + } + } + finally { + try { + in.close() ; + } + catch(IOException ioe) { + // Ignore IOE when closing stream + } + } + } + } catch (Throwable e) { + throw new RuntimeException("Unable to load configuration file [" + CONFIG_FILE + "]", e) ; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/java/org/apache/ranger/process/TagSynchronizer.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/process/TagSynchronizer.java b/tagsync/src/main/java/org/apache/ranger/process/TagSynchronizer.java new file mode 100644 index 0000000..c7e8d6e --- /dev/null +++ b/tagsync/src/main/java/org/apache/ranger/process/TagSynchronizer.java @@ -0,0 +1,187 @@ +/* + * 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.process; + +import org.apache.commons.collections.MapUtils; +import org.apache.log4j.Logger; +import org.apache.ranger.model.TagSink; +import org.apache.ranger.model.TagSource; + +import java.util.Properties; + +/** + * Created by akulkarni on 9/11/15. + */ +public class TagSynchronizer implements Runnable { + + private static final Logger LOG = Logger.getLogger(TagSynchronizer.class); + + private final static int MAX_INIT_RETRIES = 1; + + private boolean shutdownFlag = false; + private TagSink tagSink = null; + private TagSource tagSource = null; + private Properties properties = null; + + + public static void main(String[] args) { + + TagSyncConfig config = TagSyncConfig.getInstance(); + Properties props = config.getProperties(); + + LOG.info("--------------------------------"); + LOG.info(""); + LOG.info("Ranger-TagSync Configuration: {\n" + config + "\n}"); + LOG.info(""); + LOG.info("--------------------------------"); + + TagSynchronizer tagSynchronizer = new TagSynchronizer(props); + + tagSynchronizer.run(); + } + + public TagSynchronizer(Properties properties) { + if (properties == null || MapUtils.isEmpty(properties)) { + LOG.error("TagSynchronizer initialized with null properties!"); + this.properties = new Properties(); + } else { + this.properties = properties; + } + } + + public TagSink getTagSink() { + return tagSink; + } + + public TagSource getTagSource() { + return tagSource; + } + + @Override + public void run() { + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagSynchronizer.run()"); + } + try { + long sleepTimeBetweenCycleInMillis = TagSyncConfig.getSleepTimeInMillisBetweenCycle(properties); + + boolean initDone = initLoop(); + + if (initDone) { + + tagSource.start(); + + while (!shutdownFlag) { + try { + LOG.debug("Sleeping for [" + sleepTimeBetweenCycleInMillis + "] milliSeconds"); + Thread.sleep(sleepTimeBetweenCycleInMillis); + } catch (InterruptedException e) { + LOG.error("Failed to wait for [" + sleepTimeBetweenCycleInMillis + "] milliseconds before attempting to synchronize tag information", e); + } + } + } else { + LOG.error("Failed to initialize TagSynchonizer after " + MAX_INIT_RETRIES + " retries. Exiting thread"); + } + + } catch (Throwable t) { + LOG.error("tag-sync thread got an error", t); + } finally { + LOG.error("Shutting down the tag-sync thread"); + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagSynchronizer.run()"); + } + } + + public boolean initLoop() { + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagSynchronizer.initLoop()"); + } + boolean ret = false; + + long sleepTimeBetweenCycleInMillis = TagSyncConfig.getSleepTimeInMillisBetweenCycle(properties); + + for (int initRetries = 0; initRetries < MAX_INIT_RETRIES && !ret; initRetries++) { + + ret = init(); + + if (!ret) { + LOG.error("Failed to initialize TAG source/sink. Will retry after " + sleepTimeBetweenCycleInMillis + " milliseconds."); + try { + LOG.debug("Sleeping for [" + sleepTimeBetweenCycleInMillis + "] milliSeconds"); + Thread.sleep(sleepTimeBetweenCycleInMillis); + } catch (Exception e) { + LOG.error("Failed to wait for [" + sleepTimeBetweenCycleInMillis + "] milliseconds before attempting to initialize tag source/sink", e); + } + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagSynchronizer.initLoop()"); + } + return ret; + } + + public boolean init() { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagSynchronizer.init()"); + } + boolean ret = false; + try { + LOG.info("Initializing TAG source and sink"); + // Initialize tagSink and tagSource + String tagSourceClassName = TagSyncConfig.getTagSourceClassName(properties); + String tagSinkClassName = TagSyncConfig.getTagSinkClassName(properties); + + if (LOG.isDebugEnabled()) { + LOG.debug("tagSourceClassName=" + tagSourceClassName + ", tagSinkClassName=" + tagSinkClassName); + } + + Class<TagSource> tagSourceClass = (Class<TagSource>) Class.forName(tagSourceClassName); + Class<TagSink> tagSinkClass = (Class<TagSink>) Class.forName(tagSinkClassName); + + tagSink = tagSinkClass.newInstance(); + tagSource = tagSourceClass.newInstance(); + + if (LOG.isDebugEnabled()) { + LOG.debug("Created instance of " + tagSourceClassName + ", " + tagSinkClassName); + } + + ret = tagSink.initialize(properties) && tagSource.initialize(properties); + + tagSource.setTagSink(tagSink); + + LOG.info("Done initializing TAG source and sink"); + } catch (Throwable t) { + LOG.error("Failed to initialize TAG source/sink. Error details: ", t); + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagSynchronizer.init(), result=" + ret); + } + + return ret; + } + + public void shutdown(String reason) { + LOG.error("Received shutdown(), reason=" + reason); + this.shutdownFlag = true; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/java/org/apache/ranger/sink/policymgr/TagRESTSink.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/sink/policymgr/TagRESTSink.java b/tagsync/src/main/java/org/apache/ranger/sink/policymgr/TagRESTSink.java new file mode 100644 index 0000000..0695cd3 --- /dev/null +++ b/tagsync/src/main/java/org/apache/ranger/sink/policymgr/TagRESTSink.java @@ -0,0 +1,515 @@ +/* + * 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.sink.policymgr; + +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.WebResource; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.admin.client.datatype.RESTResponse; +import org.apache.ranger.model.TagSink; +import org.apache.ranger.plugin.model.*; +import org.apache.ranger.plugin.store.PList; +import org.apache.ranger.plugin.store.ServiceStore; +import org.apache.ranger.plugin.util.RangerRESTClient; +import org.apache.ranger.plugin.util.SearchFilter; +import org.apache.ranger.plugin.util.ServiceTags; +import org.apache.ranger.process.TagSyncConfig; + +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Created by akulkarni on 9/11/15. + */ +public class TagRESTSink implements TagSink { + private static final Log LOG = LogFactory.getLog(TagRESTSink.class); + + private static final String REST_PREFIX = "/service"; + private static final String MODULE_PREFIX = "/tags"; + + private static final String REST_MIME_TYPE_JSON = "application/json" ; + private static final String REST_URL_TAGDEFS_RESOURCE = REST_PREFIX + MODULE_PREFIX + "/tagdefs/" ; + private static final String REST_URL_TAGDEF_RESOURCE = REST_PREFIX + MODULE_PREFIX + "/tagdef/" ; + private static final String REST_URL_SERVICERESOURCES_RESOURCE = REST_PREFIX + MODULE_PREFIX + "resources/" ; + private static final String REST_URL_SERVICERESOURCE_RESOURCE = REST_PREFIX + MODULE_PREFIX + "resource/" ; + private static final String REST_URL_TAGS_RESOURCE = REST_PREFIX + MODULE_PREFIX + "/tags/" ; + private static final String REST_URL_TAG_RESOURCE = REST_PREFIX + MODULE_PREFIX + "/tag/" ; + private static final String REST_URL_TAGRESOURCEMAP_IDS_RESOURCE = REST_PREFIX + MODULE_PREFIX + "/tagresourcemapids/"; + private static final String REST_URL_IMPORT_SERVICETAGS_RESOURCE = REST_PREFIX + MODULE_PREFIX + "/importservicetags/"; + public static final String REST_URL_IMPORT_SERVICETAGS_PARAM = "op"; + + + private RangerRESTClient tagRESTClient = null; + + @Override + public void init() {} + + @Override + public boolean initialize(Properties properties) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> TagRESTSink.initialize()"); + } + + boolean ret = false; + + String restUrl = TagSyncConfig.getPolicyMgrUrl(properties); + String sslConfigFile = TagSyncConfig.getPolicyMgrSslConfigFile(properties); + String userName = TagSyncConfig.getPolicyMgrUserName(properties); + String password = TagSyncConfig.getPolicyMgrPassword(properties); + + if (LOG.isDebugEnabled()) { + LOG.debug("restUrl=" + restUrl); + LOG.debug("sslConfigFile=" + sslConfigFile); + LOG.debug("userName=" + userName); + LOG.debug("password=" + password); + } + tagRESTClient = new RangerRESTClient(restUrl, sslConfigFile); + if (tagRESTClient != null) { + tagRESTClient.setBasicAuthInfo(userName, password); + ret = true; + } else { + LOG.error("Could not create RangerRESTClient"); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== TagRESTSink.initialize(), result=" + ret); + } + return ret; + } + + @Override + public void setServiceStore(ServiceStore svcStore) { + + } + + @Override + public RangerTagDef createTagDef(RangerTagDef tagDef) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> createTagDef(" + tagDef + ")"); + } + + RangerTagDef ret = null; + + WebResource webResource = createWebResource(REST_URL_TAGDEFS_RESOURCE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class, tagRESTClient.toJson(tagDef)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerTagDef.class); + } else { + LOG.error("RangerAdmin REST call returned with response={" + response +"}"); + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== createTagDef(" + tagDef + "): " + ret); + } + + return ret; + } + + @Override + public RangerTagDef updateTagDef(RangerTagDef TagDef) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public void deleteTagDefByName(String name) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public void deleteTagDef(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> deleteTagDef(" + id + ")"); + } + WebResource webResource = createWebResource(REST_URL_TAGDEF_RESOURCE + Long.toString(id)); + + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).delete(ClientResponse.class); + + if(response != null && response.getStatus() == 204) { + } else { + LOG.error("RangerAdmin REST call returned with response={" + response + "}"); + + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== deleteTagDef(" + id + ")"); + } + } + + @Override + public RangerTagDef getTagDef(Long id) throws Exception { + throw new Exception("Not implemented"); + + } + + @Override + public RangerTagDef getTagDefByGuid(String guid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public RangerTagDef getTagDefByName(String name) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagDef> getTagDefs(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public PList<RangerTagDef> getPaginatedTagDefs(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + + @Override + public RangerTag createTag(RangerTag tag) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> createTag(" + tag + ")"); + } + + RangerTag ret = null; + + WebResource webResource = createWebResource(REST_URL_TAGS_RESOURCE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class, tagRESTClient.toJson(tag)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerTag.class); + } else { + LOG.error("RangerAdmin REST call returned with response={" + response +"}"); + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== createTag(" + tag + "): " + ret); + } + + return ret; + } + + @Override + public RangerTag updateTag(RangerTag tag) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public void deleteTag(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> deleteTag(" + id + ")"); + } + WebResource webResource = createWebResource(REST_URL_TAG_RESOURCE + Long.toString(id)); + + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).delete(ClientResponse.class); + + if(response != null && response.getStatus() == 204) { + } else { + LOG.error("RangerAdmin REST call returned with response={" + response + "}"); + + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== deleteTag(" + id + ")"); + } + } + + @Override + public RangerTag getTag(Long id) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public RangerTag getTagByGuid(String guid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTag> getTagsByType(String name) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTag> getTagsForResourceId(Long resourceId) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTag> getTagsForResourceGuid(String resourceGuid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTag> getTags(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public PList<RangerTag> getPaginatedTags(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + + @Override + public RangerServiceResource createServiceResource(RangerServiceResource resource) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> createServiceResource(" + resource + ")"); + } + + RangerServiceResource ret = null; + + WebResource webResource = createWebResource(REST_URL_SERVICERESOURCES_RESOURCE); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class, tagRESTClient.toJson(resource)); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerServiceResource.class); + } else { + LOG.error("RangerAdmin REST call returned with response={" + response +"}"); + + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== createServiceResource(" + resource + "): " + ret); + } + + return ret; + } + + @Override + public RangerServiceResource updateServiceResource(RangerServiceResource resource) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public void deleteServiceResource(Long id) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> deleteServiceResource(" + id + ")"); + } + WebResource webResource = createWebResource(REST_URL_SERVICERESOURCE_RESOURCE + Long.toString(id)); + + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).delete(ClientResponse.class); + + if(response != null && response.getStatus() == 204) { + } else { + LOG.error("RangerAdmin REST call returned with response={" + response + "}"); + + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== deleteServiceResource(" + id + ")"); + } + } + + @Override + public RangerServiceResource getServiceResource(Long id) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public RangerServiceResource getServiceResourceByGuid(String guid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerServiceResource> getServiceResourcesByService(String serviceName) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public RangerServiceResource getServiceResourceByResourceSignature(String resourceSignature) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerServiceResource> getServiceResources(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public PList<RangerServiceResource> getPaginatedServiceResources(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + + @Override + public RangerTagResourceMap createTagResourceMap(RangerTagResourceMap tagResourceMap) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> createTagResourceMap(" + tagResourceMap + ")"); + } + + RangerTagResourceMap ret = null; + + WebResource webResource = createWebResource(REST_URL_TAGRESOURCEMAP_IDS_RESOURCE) + .queryParam("tag-id", Long.toString(tagResourceMap.getTagId())) + .queryParam("resource-id", Long.toString(tagResourceMap.getResourceId())); + + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).post(ClientResponse.class); + + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(RangerTagResourceMap.class); + } else { + LOG.error("RangerAdmin REST call returned with response={" + response +"}"); + + RESTResponse resp = RESTResponse.fromClientResponse(response); + + throw new Exception(resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== createTagResourceMap(" + tagResourceMap + "): " + ret); + } + + return ret; + } + + @Override + public void deleteTagResourceMap(Long id) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public void uploadServiceTags(ServiceTags serviceTags) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> uploadServiceTags()"); + } + WebResource webResource = createWebResource(REST_URL_IMPORT_SERVICETAGS_RESOURCE); + + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).type(REST_MIME_TYPE_JSON).put(ClientResponse.class, tagRESTClient.toJson(serviceTags)); + + if(response != null && response.getStatus() == 204) { + } else { + LOG.error("RangerAdmin REST call returned with response={" + response + "}"); + + RESTResponse resp = RESTResponse.fromClientResponse(response); + + LOG.error("Upload of service-tags failed with message " + resp.getMessage()); + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== uploadServiceTags()"); + } + } + + @Override + public RangerTagResourceMap getTagResourceMap(Long id) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public RangerTagResourceMap getTagResourceMapByGuid(String guid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> getTagResourceMapsForTagId(Long tagId) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> getTagResourceMapsForTagGuid(String tagGuid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> getTagResourceMapsForResourceId(Long resourceId) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> getTagResourceMapsForResourceGuid(String resourceGuid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public RangerTagResourceMap getTagResourceMapForTagAndResourceId(Long tagId, Long resourceId) throws Exception { + throw new Exception("Not implemented"); + } + + + @Override + public RangerTagResourceMap getTagResourceMapForTagAndResourceGuid(String tagGuid, String resourceGuid) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> getTagResourceMaps(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public PList<RangerTagResourceMap> getPaginatedTagResourceMaps(SearchFilter filter) throws Exception { + throw new Exception("Not implemented"); + } + + + @Override + public ServiceTags getServiceTagsIfUpdated(String serviceName, Long lastKnownVersion) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<String> getTagTypes(String serviceName) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<String> lookupTagTypes(String serviceName, String pattern) throws Exception { + throw new Exception("Not implemented"); + } + + private WebResource createWebResource(String url) { + return createWebResource(url, null); + } + + private WebResource createWebResource(String url, SearchFilter filter) { + WebResource ret = tagRESTClient.getResource(url); + + if(filter != null && !MapUtils.isEmpty(filter.getParams())) { + for(Map.Entry<String, String> e : filter.getParams().entrySet()) { + String name = e.getKey(); + String value = e.getValue(); + + ret.queryParam(name, value); + } + } + + return ret; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/java/org/apache/ranger/source/file/TagFileSource.java ---------------------------------------------------------------------- diff --git a/tagsync/src/main/java/org/apache/ranger/source/file/TagFileSource.java b/tagsync/src/main/java/org/apache/ranger/source/file/TagFileSource.java new file mode 100644 index 0000000..2952edb --- /dev/null +++ b/tagsync/src/main/java/org/apache/ranger/source/file/TagFileSource.java @@ -0,0 +1,427 @@ +/* + * 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.source.file; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.model.TagSink; +import org.apache.ranger.model.TagSource; +import org.apache.ranger.plugin.model.RangerServiceResource; +import org.apache.ranger.plugin.model.RangerTag; +import org.apache.ranger.plugin.model.RangerTagDef; +import org.apache.ranger.plugin.model.RangerTagResourceMap; +import org.apache.ranger.plugin.util.ServiceTags; +import org.apache.ranger.process.TagSyncConfig; + +import java.io.*; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +/** + * Created by akulkarni on 9/11/15. + */ +public class TagFileSource implements TagSource, Runnable { + private static final Log LOG = LogFactory.getLog(TagFileSource.class); + + public static final String CREATE_OR_UPDATE_SERVICETAGS_OP = "CREATE_OR_UPDATE"; + public static final String DELETE_SERVICETAGS_OP = "DELETE"; + + private String sourceFileName; + private long lastModifiedTimeInMillis = 0L; + + private Gson gson; + private TagSink tagSink; + private Properties properties; + + @Override + public boolean initialize(Properties properties) { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.initialize()"); + } + + if (properties == null || MapUtils.isEmpty(properties)) { + LOG.error("No properties specified for TagFileSource initialization"); + this.properties = new Properties(); + } else { + this.properties = properties; + } + + boolean ret = true; + + if (ret) { + + sourceFileName = TagSyncConfig.getTagSourceFileName(properties); + + if (LOG.isDebugEnabled()) { + LOG.debug("Provided sourceFileName=" + sourceFileName); + } + + String realFileName = TagSyncConfig.getResourceFileName(sourceFileName); + if (realFileName != null) { + if (LOG.isDebugEnabled()) { + LOG.debug("Real sourceFileName=" + realFileName); + } + sourceFileName = realFileName; + } else { + LOG.error(sourceFileName + " is not a file or is not readable"); + ret = false; + } + } + + if (ret) { + try { + gson = new GsonBuilder().setDateFormat("yyyyMMdd-HH:mm:ss.SSS-Z").setPrettyPrinting().create(); + } catch (Throwable excp) { + LOG.fatal("failed to create GsonBuilder object", excp); + ret = false; + } + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.initialize(): sourceFileName=" + sourceFileName + ", result=" + ret); + } + + return ret; + } + + @Override + public void setTagSink(TagSink sink) { + if (sink == null) { + LOG.error("Sink is null!!!"); + } else { + this.tagSink = sink; + } + } + + @Override + public void start() { + (new Thread(this)).start(); + } + + @Override + public void run() { + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.run()"); + } + long sleepTimeBetweenCycleInMillis = TagSyncConfig.getSleepTimeInMillisBetweenCycle(properties); + boolean shutdownFlag = false; + + while (!shutdownFlag) { + + try { + if (isChanged()) { + LOG.info("Begin: update tags from source==>sink"); + if (TagSyncConfig.isTagSyncEnabled(properties)) { + updateSink(); + LOG.info("End: update tags from source==>sink"); + } else { + LOG.info("Tag-sync is not enabled."); + } + } else { + LOG.debug("TagFileSource: no change found for synchronization."); + } + + LOG.debug("Sleeping for [" + sleepTimeBetweenCycleInMillis + "] milliSeconds"); + + Thread.sleep(sleepTimeBetweenCycleInMillis); + } + catch (InterruptedException e) { + LOG.error("Failed to wait for [" + sleepTimeBetweenCycleInMillis + "] milliseconds before attempting to synchronize tag information", e); + shutdownFlag = true; + } + catch (Throwable t) { + LOG.error("tag-sync thread got an error", t); + shutdownFlag = true; + } + + } + + LOG.error("Shutting down the Tag-file-source thread"); + + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.run()"); + } + } + + @Override + public void updateSink() throws Exception { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.updateSink()"); + } + ServiceTags serviceTags = readFromFile(); + + if (serviceTags != null) { + + tagSink.uploadServiceTags(serviceTags); + + } else { + LOG.error("Could not read ServiceTags from file"); + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.updateSink()"); + } + } + + /* + private void createTagObjects(ServiceTags serviceTags) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.createTagObjects()"); + } + + Map<Long, RangerTagDef> tagDefsMap = serviceTags.getTagDefinitions(); + if (MapUtils.isNotEmpty(tagDefsMap)) { + for (Map.Entry<Long, RangerTagDef> entry : tagDefsMap.entrySet()) { + RangerTagDef tagDef = entry.getValue(); + try { + tagSink.createTagDef(tagDef); + } catch (Exception exception) { + // Ignore and continue + LOG.error("createTagDef failed, tagDef=" + tagDef, exception); + } + } + } + + List<RangerServiceResource> serviceResources = serviceTags.getServiceResources(); + if (CollectionUtils.isNotEmpty(serviceResources)) { + for (RangerServiceResource serviceResource : serviceResources) { + try { + tagSink.createServiceResource(serviceResource); + } catch (Exception exception) { + // Ignore and continue + LOG.error("createServiceResource failed, serviceResource=" + serviceResource, exception); + } + } + } + + Map<Long, RangerTag> tagsMap = serviceTags.getTags(); + if (MapUtils.isNotEmpty(tagsMap)) { + for (Map.Entry<Long, RangerTag> entry : tagsMap.entrySet()) { + RangerTag tag = entry.getValue(); + try { + tagSink.createTag(tag); + } catch (Exception exception) { + // Ignore and continue + LOG.error("createTag failed, tag=" + tag, exception); + } + } + } + + Map<Long, List<Long>> resourceTagIdsMap = serviceTags.getResourceToTagIds(); + if (MapUtils.isNotEmpty(resourceTagIdsMap)) { + for (Map.Entry<Long, List<Long>> entry : resourceTagIdsMap.entrySet()) { + Long resourceId = entry.getKey(); + List<Long> tagIds = entry.getValue(); + for (Long tagId : tagIds) { + RangerTagResourceMap tagResourceMap = new RangerTagResourceMap(); + tagResourceMap.setResourceId(resourceId); + tagResourceMap.setTagId(tagId); + try { + tagSink.createTagResourceMap(tagResourceMap); + } catch (Exception exception) { + LOG.error("createTagResourceMap failed, resourceId=" + resourceId + ", tagId=" + tagId, exception); + } + } + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.createTagObjects()"); + } + } + */ + /* + private void deleteTagObjects(ServiceTags serviceTags) { + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.deleteTagObjects()"); + } + + Map<Long, List<Long>> resourceTagIdsMap = serviceTags.getResourceToTagIds(); + if (MapUtils.isNotEmpty(resourceTagIdsMap)) { + for (Map.Entry<Long, List<Long>> entry : resourceTagIdsMap.entrySet()) { + Long resourceId = entry.getKey(); + List<Long> tagIds = entry.getValue(); + for (Long tagId : tagIds) { + try { + tagSink.deleteTagResourceMap(tagId, resourceId); + } catch (Exception exception) { + LOG.error("deleteTagResourceMap failed, resourceId=" + resourceId + ", tagId=" + tagId +")", exception); + } + } + } + } + + List<RangerServiceResource> serviceResources = serviceTags.getServiceResources(); + if (CollectionUtils.isNotEmpty(serviceResources)) { + for (RangerServiceResource serviceResource : serviceResources) { + try { + tagSink.deleteServiceResource(serviceResource.getId()); + } catch (Exception exception) { + // Ignore and continue + LOG.error("deleteServiceResource failed, serviceResource=" + serviceResource, exception); + } + } + } + + Map<Long, RangerTag> tagsMap = serviceTags.getTags(); + if (MapUtils.isNotEmpty(tagsMap)) { + for (Map.Entry<Long, RangerTag> entry : tagsMap.entrySet()) { + Long tagId = entry.getKey(); + try { + tagSink.deleteTag(tagId); + } catch (Exception exception) { + // Ignore and continue + LOG.error("deleteTag failed, tagId=" + tagId, exception); + } + } + } + + Map<Long, RangerTagDef> tagDefsMap = serviceTags.getTagDefinitions(); + if (MapUtils.isNotEmpty(tagDefsMap)) { + for (Map.Entry<Long, RangerTagDef> entry : tagDefsMap.entrySet()) { + Long tagDefId = entry.getKey(); + try { + tagSink.deleteTagDef(tagDefId); + } catch (Exception exception) { + // Ignore and continue + LOG.error("deleteTagDef failed, tagDefId=" + tagDefId, exception); + } + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.deleteTagObjects()"); + } + } + */ + + @Override + public boolean isChanged() { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.isChanged()"); + } + boolean ret = false; + + long modificationTime = getModificationTime(); + + if (modificationTime > lastModifiedTimeInMillis) { + if (LOG.isDebugEnabled()) { + Date modifiedDate = new Date(modificationTime); + Date lastModifiedDate = new Date(lastModifiedTimeInMillis); + LOG.debug("File modified at " + modifiedDate + "last-modified at " + lastModifiedDate); + } + lastModifiedTimeInMillis = modificationTime; + ret = true; + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.isChanged(): result=" + ret); + } + return ret; + } + + @Override + public List<RangerTagDef> fetchAllTagDefs(String syncSentinel) throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagDef> receiveUpdatesToTagDefs() throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> fetchAllTaggedEntities() throws Exception { + throw new Exception("Not implemented"); + } + + @Override + public List<RangerTagResourceMap> receiveUpdatesToTaggedEntities() throws Exception { + throw new Exception("Not implemented"); + } + + private ServiceTags readFromFile() { + + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.readFromFile(): sourceFileName=" + sourceFileName); + } + + ServiceTags ret = null; + + Reader reader = null; + try { + + reader = new InputStreamReader(TagSyncConfig.getFileInputStream(sourceFileName)); + + ret = gson.fromJson(reader, ServiceTags.class); + + } + catch (FileNotFoundException exception) { + LOG.warn("Tag-source file does not exist or not readble '" + sourceFileName + "'"); + } + catch (Exception excp) { + LOG.error("failed to load service-tags from Tag-source file " + sourceFileName, excp); + } + finally { + if (reader != null) { + try { + reader.close(); + } catch (Exception excp) { + LOG.error("error while closing opened Tag-source file " + sourceFileName, excp); + } + } + } + + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.readFromFile(): sourceFileName=" + sourceFileName); + } + + return ret; + } + + private long getModificationTime() { + if (LOG.isDebugEnabled()) { + LOG.debug("==> TagFileSource.getLastModificationTime(): sourceFileName=" + sourceFileName); + } + long ret = 0L; + + File sourceFile = new File(sourceFileName); + + if (sourceFile.exists() && sourceFile.isFile() && sourceFile.canRead()) { + ret = sourceFile.lastModified(); + } else { + ret = new Date().getTime(); + } + if (LOG.isDebugEnabled()) { + LOG.debug("<== TagFileSource.lastModificationTime(): sourceFileName=" + sourceFileName + " result=" + new Date(ret)); + } + + return ret; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/resources/application.properties ---------------------------------------------------------------------- diff --git a/tagsync/src/main/resources/application.properties b/tagsync/src/main/resources/application.properties new file mode 100644 index 0000000..7c874b6 --- /dev/null +++ b/tagsync/src/main/resources/application.properties @@ -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. + + +# This file is used currently to satisfy needs of Injection of EntityChangeConsumer and its +# initialization. +# +# Basic configuration required to create EntityChangeConsumer +# +atlas.notification.kafka.bootstrap.servers=ranger-tag-policy-akulkarni-1:6667 +atlas.notification.kafka.zookeeper.connect=ranger-tag-policy-akulkarni-1:2181 + +# +# These properties seem to be internal to Atlas. They probably are used for generating notifications. +atlas.notification.embedded=false +atlas.notification.kafka.acks=1 +atlas.notification.kafka.data=${sys:atlas.home}/data/kafka http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/resources/etc/ranger/data/tags.json ---------------------------------------------------------------------- diff --git a/tagsync/src/main/resources/etc/ranger/data/tags.json b/tagsync/src/main/resources/etc/ranger/data/tags.json new file mode 100644 index 0000000..28e7922 --- /dev/null +++ b/tagsync/src/main/resources/etc/ranger/data/tags.json @@ -0,0 +1,75 @@ +{ + "op":"create_or_update", + "serviceName": "cl1_hive", + "tagVersion": 24, + "tagUpdateTime": "20150901-20:03:17.000-+0000", + "tagDefinitions": { + "1": { + "name": "EXPIRES_ON", + "source": "Internal", + "attributeDefs": [ + { + "name": "expiry_date", + "type": "datetime" + } + ], + "id": 1, + "guid": "1441137512654_323_77", + "isEnabled": true, + "createdBy": "Admin", + "updatedBy": "Admin", + "createTime": "20150901-19:58:33.000-+0000", + "updateTime": "20150901-19:58:33.000-+0000" + } + }, + "tags": { + "1": { + "type": "EXPIRES_ON", + "attributes": { + "expiry_date": "2014/12/31" + }, + "id": 1, + "guid": "1441137512698_844_80", + "isEnabled": true, + "createdBy": "Admin", + "updatedBy": "Admin", + "createTime": "20150901-19:58:33.000-+0000", + "updateTime": "20150901-20:03:17.000-+0000" + } + }, + "serviceResources": [ + { + "serviceName": "cl1_hive", + "resourceElements": { + "table": { + "values": [ + "tax_2010" + ], + "isExcludes": false, + "isRecursive": false + }, + "database": { + "values": [ + "finance" + ], + "isExcludes": false, + "isRecursive": false + } + }, + "resourceSignature": "c1114679b35a65d28e0dca4fdffc27d6", + "id": 1, + "guid": "1441137512756_887_83", + "isEnabled": true, + "createdBy": "Admin", + "updatedBy": "Admin", + "createTime": "20150901-19:58:33.000-+0000", + "updateTime": "20150901-19:58:33.000-+0000" + } + ], + "resourceToTagIds": { + "1": [ + 1 + ] + } +} + http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/main/resources/ranger-tagsync-site.xml ---------------------------------------------------------------------- diff --git a/tagsync/src/main/resources/ranger-tagsync-site.xml b/tagsync/src/main/resources/ranger-tagsync-site.xml new file mode 100644 index 0000000..63b9727 --- /dev/null +++ b/tagsync/src/main/resources/ranger-tagsync-site.xml @@ -0,0 +1,67 @@ +<!-- + Licensed 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. See accompanying LICENSE file. +--> + + +<configuration> + <property> + <name>ranger.authentication.method</name> + <value>NONE</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.policymanager.baseURL</name> + <value>http://ranger-tag-policy-akulkarni-1:6080</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.policymanager.ssl.config.file</name> + <value></value> + <description></description> + </property> + <property> + <name>ranger.tagsync.policymanager.basicauth.username</name> + <value>admin</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.policymanager.basicauth.password</name> + <value>admin</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.sleeptimeinmillisbetweensynccycle</name> + <value>60000</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.source.file</name> + <value>/etc/ranger/data/tags.txt</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.source.impl.class</name> + <value>org.apache.ranger.source.file.TagFileSource</value> + <description></description> + </property> + <property> + <name>ranger.tagsync.sink.impl.class</name> + <value>org.apache.ranger.sink.policymgr.TagRESTSink</value> + <description></description> + </property> + <property> + <name>atlas.endpoint</name> + <value>http://ranger-tag-policy-akulkarni-1:21000/</value> + <description></description> + </property> +</configuration> http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/test/java/org/apache/ranger/process/TestTagSynchronizer.java ---------------------------------------------------------------------- diff --git a/tagsync/src/test/java/org/apache/ranger/process/TestTagSynchronizer.java b/tagsync/src/test/java/org/apache/ranger/process/TestTagSynchronizer.java new file mode 100644 index 0000000..d810048 --- /dev/null +++ b/tagsync/src/test/java/org/apache/ranger/process/TestTagSynchronizer.java @@ -0,0 +1,96 @@ +/* + * 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.process; + + +import org.apache.ranger.model.TagSource; +//import org.apache.ranger.source.atlas.TagAtlasSource; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.*; +import java.util.Properties; + +import static org.junit.Assert.*; + + +public class TestTagSynchronizer { + + private static TagSynchronizer tagSynchronizer; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + System.out.println("setUpBeforeClass() called"); + + TagSyncConfig config = TagSyncConfig.getInstance(); + + Properties props = config.getProperties(); + + System.out.println("Tester is configured with following properties--"); + System.out.println("--------------------"); + + config.toString(); + + System.out.println("--------------------"); + + tagSynchronizer = new TagSynchronizer(props); + + } + + @AfterClass + public static void tearDownAfterClass() throws Exception { + System.out.println("tearDownAfterClass() called"); + + } + + @Test + public void testTagSynchronizer() { + + System.out.println("testTagSynchronizer() called"); + + //tagSynchronizer.run(); + + tagSynchronizer.shutdown("From testTagSynchronizer: time=up"); + + System.out.println("Exiting test"); + + + } + + @Test + public void testTagDownload() { + + boolean initDone = tagSynchronizer.init(); + + System.out.println("TagSynchronizer initialization result=" + initDone); + + TagSource tagSource = tagSynchronizer.getTagSource(); + + try { + //TagAtlasSource tagAtlasSource = (TagAtlasSource) tagSource; + //tagAtlasSource.printAllEntities(); + } catch (ClassCastException exception) { + System.err.println("TagSource is not of TagAtlasSource"); + } + + System.out.println("Exiting testTagDownload()"); + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/001ec883/tagsync/src/test/resources/log4j.properties ---------------------------------------------------------------------- diff --git a/tagsync/src/test/resources/log4j.properties b/tagsync/src/test/resources/log4j.properties new file mode 100644 index 0000000..57118de --- /dev/null +++ b/tagsync/src/test/resources/log4j.properties @@ -0,0 +1,35 @@ +# 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. + +##-- To prevent junits from cluttering the build run by default all test runs send output to null appender +log4j.appender.devnull=org.apache.log4j.varia.NullAppender +# ranger.root.logger=FATAL,devnull + +##-- uncomment the following line during during development/debugging so see debug messages during test run to be emitted to console +ranger.root.logger=DEBUG,console + +log4j.rootLogger=${ranger.root.logger} + +# Logging Threshold +log4j.threshold=ALL + +# +# console +# Add "console" to rootlogger above if you want to use this +# +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %L %m%n
