This is an automated email from the ASF dual-hosted git repository. ctubbsii pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/accumulo-access.git
The following commit(s) were added to refs/heads/main by this push: new e6e8e19 Move and simplify the AccessExample (#51) e6e8e19 is described below commit e6e8e19619b342c7c9462afac1e29883087a99fe Author: Christopher Tubbs <ctubb...@apache.org> AuthorDate: Tue Feb 13 19:35:00 2024 -0500 Move and simplify the AccessExample (#51) * Put the example in the src/test/java directory * Remove contrib/getting-started * Simplify the instructions for running the example and add them to the main README * Bake in some improvements into the example, so it's a bit more self-descriptive, and simplify some of its internals * Clarify running example with specific auths * Add test from code review, but making it more testable * add missing POM stuffs like source-tarball-release for assembly and mavanagaiata plugin Co-authored-by: Keith Turner <ktur...@apache.org> --- README.md | 28 ++++++- contrib/getting-started/README.md | 98 ---------------------- contrib/getting-started/pom.xml | 46 ---------- contrib/getting-started/run.sh | 21 ----- .../src/main/java/gse/AccessExample.java | 66 --------------- pom.xml | 15 ++-- src/test/java/example/AccessExample.java | 86 +++++++++++++++++++ src/test/java/example/AccessExampleTest.java | 48 +++++++++++ .../accumulo/access/AccessEvaluatorTest.java | 3 - 9 files changed, 171 insertions(+), 240 deletions(-) diff --git a/README.md b/README.md index e7bbe39..28fd87e 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ --> -# Accumulo Access Control Library +# Accumulo Access Library Java library that provides the same functionality, semantics, and syntax as the Apache Accumulo [ColumnVisibility][1] and [VisibilityEvaluator][2] classes. @@ -41,9 +41,35 @@ are package private and are not part of the public API. * [AccessExpression](src/main/java/org/apache/accumulo/access/AccessExpression.java). * [Authorizations](src/main/java/org/apache/accumulo/access/Authorizations.java). +## Getting Started + +Add the library to your CLASSPATH. For Maven, use: + +```xml +<dependencies> + <dependency> + <groupId>org.apache.accumulo</groupId> + <artifactId>accumulo-access</artifactId> + <version>$version</version> + </dependency> +</dependencies> +``` + +## Running the [Example](src/test/java/example/AccessExample.java) + +``` +mvn clean package +CLASSPATH=$(ls target/accumulo-access-*.jar) java src/test/java/example/AccessExample.java +CLASSPATH=$(ls target/accumulo-access-*.jar) java src/test/java/example/AccessExample.java RED BLUE +``` + +Note that `data6` is always returned, because it has no access expression. And +remember, authorizations are case-sensitive. + ## Running the Benchmark This project includes a JMH Benchmark. To run it: + ``` mvn clean package mvn exec:exec -Dexec.executable="java" -Dexec.classpathScope=test -Dexec.args="-classpath %classpath org.apache.accumulo.access.AccessExpressionBenchmark" diff --git a/contrib/getting-started/README.md b/contrib/getting-started/README.md deleted file mode 100644 index bd9090d..0000000 --- a/contrib/getting-started/README.md +++ /dev/null @@ -1,98 +0,0 @@ -<!-- - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - https://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. - ---> - -# Getting started with Accumulo Access - -This standalone Accumulo Access example has the following components. - - * [AccessExample](src/main/java/gse/AccessExample.java) Example that shows how to evaluate if data is accessible. - * [pom.xml](pom.xml) Maven build file that shows how to use Accumulo Access as a dependency - * [run.sh](run.sh) Bash script that runs the example - -To run this example clone the Accumulo Access repository and then do the following. - -```bash -cd accumulo-access -# This step installs a snapshot version of the Accumulo Access library. -# This step will not longer be needed once Accumulo Access is released. -mvn install -cd contrib/getting-started -# Build the example. If you change the example java code, run this step again. -mvn clean package -# Run the example -./run.sh -``` - -## Example runs - -Running with the authorizations set `{BLUE,GREEN,PINK,RED}` shows the complete data set because all data is accessible with these authorizations. - -``` -$ ./run.sh BLUE GREEN PINK RED -data1 : (RED&GREEN)|(BLUE&PINK) -data2 : (RED&GREEN)|(BLUE&PINK) -data3 : (RED|GREEN)&(BLUE|PINK) -data4 : (RED&GREEN)|(BLUE&PINK) -data5 : (RED|GREEN)&(BLUE|PINK) -data6 : -data7 : PINK -data8 : RED&BLUE&GREEN&PINK -data9 : PINK|(BLUE&RED) -``` - -Running with the empty set of authorizations shows only `data6` which has an empty access expression and is always accessible with any authorization set. - -``` -$ ./run.sh -data6 : -``` - -Running with the authorizations set `{BLUE,RED}` - -``` -$ ./run.sh BLUE RED -data3 : (RED|GREEN)&(BLUE|PINK) -data5 : (RED|GREEN)&(BLUE|PINK) -data6 : -data9 : PINK|(BLUE&RED) -``` - -Running with the authorizations set `{GREEN,RED}` - -``` -$ ./run.sh GREEN RED -data1 : (RED&GREEN)|(BLUE&PINK) -data2 : (RED&GREEN)|(BLUE&PINK) -data4 : (RED&GREEN)|(BLUE&PINK) -data6 : -``` - -Running with the authorizations set `{PINK}` - -``` -$ ./run.sh PINK -data6 : -data7 : PINK -data9 : PINK|(BLUE&RED) -``` - - - diff --git a/contrib/getting-started/pom.xml b/contrib/getting-started/pom.xml deleted file mode 100644 index 729219d..0000000 --- a/contrib/getting-started/pom.xml +++ /dev/null @@ -1,46 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - https://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> - - <groupId>org.apache.accumulo</groupId> - <artifactId>getting-started</artifactId> - <version>1.0-SNAPSHOT</version> - - <name>Accumulo Access Getting Started</name> - - <properties> - <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <maven.compiler.source>11</maven.compiler.source> - <maven.compiler.target>11</maven.compiler.target> - </properties> - - <dependencies> - <dependency> - <groupId>org.apache.accumulo</groupId> - <artifactId>accumulo-access</artifactId> - <version>1.0.0-beta-SNAPSHOT</version> - </dependency> - </dependencies> - -</project> diff --git a/contrib/getting-started/run.sh b/contrib/getting-started/run.sh deleted file mode 100755 index 8a9a71e..0000000 --- a/contrib/getting-started/run.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env 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 -# -# https://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. -# - -mvn -q exec:java -Dexec.mainClass=gse.AccessExample -Dexec.args="$*" diff --git a/contrib/getting-started/src/main/java/gse/AccessExample.java b/contrib/getting-started/src/main/java/gse/AccessExample.java deleted file mode 100644 index 9cefd16..0000000 --- a/contrib/getting-started/src/main/java/gse/AccessExample.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * https://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 gse; - -import org.apache.accumulo.access.AccessEvaluator; - -import java.util.ArrayList; -import java.util.Collection; - -public class AccessExample { - - public static void main(String[] args) { - // Create an access evaluator using the all the arguments passed in on the command line as authorizations. - AccessEvaluator evaluator = AccessEvaluator.of(args); - - // For each record use the access evaluator to determine if it can be accessed using the authorizations from - // the command line and the access expression associated with each record. - for (Record record : getData()) { - if (evaluator.canAccess(record.accessExpression)) { - System.out.printf("%s : %s\n", record.data, record.accessExpression); - } - } - } - - public static Collection<Record> getData() { - Collection<Record> records = new ArrayList<>(); - - records.add(new Record("data1", "(RED&GREEN)|(BLUE&PINK)")); - records.add(new Record("data2", "(RED&GREEN)|(BLUE&PINK)")); - records.add(new Record("data3", "(RED|GREEN)&(BLUE|PINK)")); - records.add(new Record("data4", "(RED&GREEN)|(BLUE&PINK)")); - records.add(new Record("data5", "(RED|GREEN)&(BLUE|PINK)")); - records.add(new Record("data6", "")); - records.add(new Record("data7", "PINK")); - records.add(new Record("data8", "RED&BLUE&GREEN&PINK")); - records.add(new Record("data9", "PINK|(BLUE&RED)")); - - return records; - } - - public static class Record { - public final String data; - public final String accessExpression; - - public Record(String data, String accessExpression) { - this.data = data; - this.accessExpression = accessExpression; - } - } -} diff --git a/pom.xml b/pom.xml index 94016ba..bf4cf5d 100644 --- a/pom.xml +++ b/pom.xml @@ -19,7 +19,7 @@ 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"> +<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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.apache</groupId> @@ -92,9 +92,18 @@ <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <maven.javadoc.failOnWarnings>true</maven.javadoc.failOnWarnings> + <maven.site.deploy.skip>true</maven.site.deploy.skip> + <maven.site.skip>true</maven.site.skip> + <!-- surefire/failsafe plugin option --> <maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile> + <!-- versions-maven-plugin ignore patterns for snapshots, alpha, beta, milestones, and release candidates --> + <maven.version.ignore>.+-SNAPSHOT,(?i).*(alpha|beta)[0-9.-]*,(?i).*[.-](m|rc)[0-9]+</maven.version.ignore> <minimalJavaBuildVersion>17</minimalJavaBuildVersion> + <!-- timestamp for reproducible outputs, updated on release by the release plugin --> + <project.build.outputTimestamp>2023-08-14T08:11:10Z</project.build.outputTimestamp> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <rat.consoleOutput>true</rat.consoleOutput> + <sourceReleaseAssemblyDescriptor>source-release-tar</sourceReleaseAssemblyDescriptor> <version.errorprone>2.24.1</version.errorprone> <version.jmh>1.37</version.jmh> </properties> @@ -487,10 +496,6 @@ <excludes> <exclude>contrib/antlr4/src/main/antlr4/Abnf.g4</exclude> <exclude>src/test/resources/testdata.json</exclude> - <exclude>**/target/</exclude> - <exclude>**/.project</exclude> - <exclude>**/.classpath</exclude> - <exclude>**/.settings/</exclude> </excludes> </configuration> <executions> diff --git a/src/test/java/example/AccessExample.java b/src/test/java/example/AccessExample.java new file mode 100644 index 0000000..d62f309 --- /dev/null +++ b/src/test/java/example/AccessExample.java @@ -0,0 +1,86 @@ +/* + * 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 + * + * https://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 example; + +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Map; +import java.util.TreeMap; + +import org.apache.accumulo.access.AccessEvaluator; + +public class AccessExample { + + public static void main(String[] args) { + PrintStream out = System.out; + var example = new AccessExample(out); + if (args.length == 0) { + out.printf("No authorizations provided. Running several examples.%n" + + "Specify authorizations on the command line (separated by spaces) to try a specific example.%n%n"); + + example.run("BLUE", "GREEN", "PINK", "RED"); + example.run(); + example.run("BLUE", "RED"); + example.run("GREEN", "RED"); + example.run("PINK"); + } else { + example.run(args); + } + } + + private final PrintStream out; + + AccessExample(PrintStream out) { + this.out = out; + } + + void run(String... authorizations) { + out.printf("Showing accessible records using authorizations: %s%n", + Arrays.toString(authorizations)); + + // Create an access evaluator using the provided authorizations + AccessEvaluator evaluator = AccessEvaluator.of(authorizations); + + // Print each record whose access expression permits viewing using the provided authorizations + getData().forEach((record, accessExpression) -> { + if (evaluator.canAccess(accessExpression)) { + out.printf(" %s : %s%n", record, accessExpression); + } + }); + out.println(); + } + + // Create a simple example data set as a sorted map of records and their access expression + private static TreeMap<String,String> getData() { + // @formatter:off + return new TreeMap<>(Map.of( + "data1", "(RED&GREEN)|(BLUE&PINK)", + "data2", "(RED&GREEN)|(BLUE&PINK)", + "data3", "(RED|GREEN)&(BLUE|PINK)", + "data4", "(RED&GREEN)|(BLUE&PINK)", + "data5", "(RED|GREEN)&(BLUE|PINK)", + "data6", "", + "data7", "PINK", + "data8", "RED&BLUE&GREEN&PINK", + "data9", "PINK|(BLUE&RED)")); + // @formatter:on + } + +} diff --git a/src/test/java/example/AccessExampleTest.java b/src/test/java/example/AccessExampleTest.java new file mode 100644 index 0000000..2bb34bb --- /dev/null +++ b/src/test/java/example/AccessExampleTest.java @@ -0,0 +1,48 @@ +/* + * 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 + * + * https://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 example; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.List; + +import org.junit.jupiter.api.Test; + +public class AccessExampleTest { + @Test + public void testExampleCode() throws IOException { + try (final var baos = new ByteArrayOutputStream(); + final var out = new PrintStream(baos, false, UTF_8)) { + final var example = new AccessExample(out); + example.run("RED", "BLUE"); + var output = baos.toString(UTF_8); + for (var expected : List.of("data3", "data5", "data6", "data9")) { + assertTrue(output.contains(expected + " : ")); + } + for (var unexpected : List.of("data1", "data4", "data7", "data8")) { + assertFalse(output.contains(unexpected)); + } + } + } +} diff --git a/src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java b/src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java index e7d025f..8d1c522 100644 --- a/src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java +++ b/src/test/java/org/apache/accumulo/access/AccessEvaluatorTest.java @@ -54,11 +54,8 @@ public class AccessEvaluatorTest { public static class TestDataSet { String description; - String[][] auths; - List<TestExpressions> tests; - } static List<TestDataSet> readTestData() throws IOException {