diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..b26b2e5f --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,30 @@ +name: build + +on: + workflow_dispatch: + +permissions: + contents: read + packages: write + +jobs: + build: + runs-on: macos-14 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - name: Checkout Sources + uses: actions/checkout@v4 + - name: Setup Java JDK + uses: actions/setup-java@v4 + with: + java-version: '21' + distribution: 'zulu' + cache: 'maven' + - name: Install Zig + run: brew install zig + - name: Add Rust Build Targets + run: rustup target add x86_64-unknown-linux-gnu + - name: Maven Build + working-directory: CedarJava + run: mvn clean deploy -DdistributionOwner=${{ github.repository_owner }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ab064a0c --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +.gradle/ +.idea/ +/build +/buildSrc/build/ +/gradle/ +/gradlew +/gradlew.bat +/wrapper/ +.DS_Store +.jqwik-database +*.iml +.classpath +.factorypath +.project +.settings/ +/gradle.properties +.idea/ +target/ diff --git a/CedarJava/build.gradle b/CedarJava/build.gradle index 090a75f7..d55bd63b 100644 --- a/CedarJava/build.gradle +++ b/CedarJava/build.gradle @@ -70,6 +70,7 @@ dependencies { implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.0' implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.15.0' implementation 'org.slf4j:slf4j-api:2.0.7' + implementation 'com.fizzed:jne:4.1.1' compileOnly 'com.google.code.findbugs:findbugs:3.0.1' testImplementation 'org.apache.logging.log4j:log4j-core:2.20.0' testImplementation 'org.apache.logging.log4j:log4j-to-slf4j:2.20.0' diff --git a/CedarJava/gradle/wrapper/gradle-wrapper.properties b/CedarJava/gradle/wrapper/gradle-wrapper.properties index 37aef8d3..509c4a29 100644 --- a/CedarJava/gradle/wrapper/gradle-wrapper.properties +++ b/CedarJava/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/CedarJava/pom.xml b/CedarJava/pom.xml new file mode 100644 index 00000000..e9519b3b --- /dev/null +++ b/CedarJava/pom.xml @@ -0,0 +1,204 @@ + + + 4.0.0 + + com.cedarpolicy + cedar-java + 3.0.0-SNAPSHOT + + + 17 + ../CedarJavaFFI + libcedar_java_ffi + aarch64-apple-darwin + ${project.build.outputDirectory}/jne/macos/aarch64 + x86_64-unknown-linux-gnu + ${project.build.outputDirectory}/jne/linux/amd64 + cedarpolicy + + + + + github + GitHub + https://maven.pkg.github.com/${distributionOwner}/cedar-java + + + + + + org.slf4j + slf4j-api + 2.0.11 + + + com.fasterxml.jackson.core + jackson-databind + 2.16.1 + + + com.fasterxml.jackson.datatype + jackson-datatype-jdk8 + 2.16.1 + + + com.fizzed + jne + 4.1.1 + + + com.google.code.findbugs + findbugs + 3.0.1 + true + + + org.junit.jupiter + junit-jupiter-api + 5.10.1 + test + + + org.junit.platform + junit-platform-engine + 1.10.2 + test + + + org.mockito + mockito-core + 5.9.0 + test + + + org.mockito + mockito-junit-jupiter + 5.9.0 + test + + + net.jqwik + jqwik + 1.7.4 + test + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.1 + + + cargo-build + process-resources + + exec + + + cargo + + build + --release + --target=${aarch64AppleTarget} + --manifest-path + ${foreignFunctionModulePath}/Cargo.toml + + + + + create-target-directory-aarch64 + process-resources + + exec + + + mkdir + + -p + ${aarch64AppleOutputDirectory} + + + + + copy-release-library-aarch64 + process-resources + + exec + + + cp + + ${foreignFunctionModulePath}/target/${aarch64AppleTarget}/release/${foreignFunctionLibraryName}.dylib + ${aarch64AppleOutputDirectory} + + + + + cargo-install-zigbuild + process-resources + + exec + + + cargo + + install + cargo-zigbuild + + + + + cargo-zigbuild + process-resources + + exec + + + cargo + + zigbuild + --release + --target=${amd64LinuxTarget} + --manifest-path + ${foreignFunctionModulePath}/Cargo.toml + + + + + create-target-directory-amd64 + process-resources + + exec + + + mkdir + + -p + ${amd64LinuxOutputDirectory} + + + + + copy-release-library-amd64 + process-resources + + exec + + + cp + + ${foreignFunctionModulePath}/target/${amd64LinuxTarget}/release/${foreignFunctionLibraryName}.so + ${amd64LinuxOutputDirectory} + + + + + + + + diff --git a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java index 360c5e03..258fb64c 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java +++ b/CedarJava/src/main/java/com/cedarpolicy/BasicAuthorizationEngine.java @@ -21,6 +21,7 @@ import java.io.IOException; +import com.cedarpolicy.library.NativeLibraryLoader; import com.cedarpolicy.model.AuthorizationResponse; import com.cedarpolicy.model.ValidationRequest; import com.cedarpolicy.model.ValidationResponse; @@ -40,7 +41,7 @@ public final class BasicAuthorizationEngine implements AuthorizationEngine { private static final Logger LOG = LoggerFactory.getLogger(BasicAuthorizationEngine.class); static { - System.load(System.getenv("CEDAR_JAVA_FFI_LIB")); + NativeLibraryLoader.loadLibrary(); } /** Construct a basic authorization engine. */ diff --git a/CedarJava/src/main/java/com/cedarpolicy/library/NativeLibraryLoader.java b/CedarJava/src/main/java/com/cedarpolicy/library/NativeLibraryLoader.java new file mode 100644 index 00000000..df73788a --- /dev/null +++ b/CedarJava/src/main/java/com/cedarpolicy/library/NativeLibraryLoader.java @@ -0,0 +1,39 @@ +/* + * Copyright 2022-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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 + * + * 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 com.cedarpolicy.library; + +import com.fizzed.jne.JNE; + +/** + * Native Library Loader encapsulates runtime loading of the Cedar Java FFI library using Java Native Environment + */ +public class NativeLibraryLoader { + private static final String LIBRARY_PATH_VARIABLE_NAME = "CEDAR_JAVA_FFI_LIB"; + + private static final String LIBRARY_NAME = "cedar_java_ffi"; + + /** + * Load Cedar Java FFI library based on runtime operating system and architecture of the Java Virtual Machine + */ + public static void loadLibrary() { + final String libraryPath = System.getenv(LIBRARY_PATH_VARIABLE_NAME); + if (libraryPath == null || libraryPath.isEmpty()) { + JNE.loadLibrary(LIBRARY_NAME); + } else { + System.load(libraryPath); + } + } +} diff --git a/CedarJava/src/main/java/com/cedarpolicy/model/schema/Schema.java b/CedarJava/src/main/java/com/cedarpolicy/model/schema/Schema.java index f6cdf563..1bd89e09 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/model/schema/Schema.java +++ b/CedarJava/src/main/java/com/cedarpolicy/model/schema/Schema.java @@ -16,6 +16,7 @@ package com.cedarpolicy.model.schema; +import com.cedarpolicy.library.NativeLibraryLoader; import com.cedarpolicy.model.exception.InternalException; import com.fasterxml.jackson.annotation.JsonValue; import com.fasterxml.jackson.databind.JsonNode; @@ -29,7 +30,7 @@ public final class Schema { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); static { - System.load(System.getenv("CEDAR_JAVA_FFI_LIB")); + NativeLibraryLoader.loadLibrary(); } // The schema after being parsed as a JSON object. diff --git a/CedarJava/src/main/java/com/cedarpolicy/model/slice/Policy.java b/CedarJava/src/main/java/com/cedarpolicy/model/slice/Policy.java index 943710ea..1d0787b9 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/model/slice/Policy.java +++ b/CedarJava/src/main/java/com/cedarpolicy/model/slice/Policy.java @@ -16,6 +16,7 @@ package com.cedarpolicy.model.slice; +import com.cedarpolicy.library.NativeLibraryLoader; import com.cedarpolicy.model.exception.InternalException; import com.cedarpolicy.value.EntityUID; import com.fasterxml.jackson.annotation.JsonProperty; @@ -31,7 +32,7 @@ public class Policy { private static final Logger LOG = LoggerFactory.getLogger(Policy.class); private static final AtomicInteger idCounter = new AtomicInteger(0); static { - System.load(System.getenv("CEDAR_JAVA_FFI_LIB")); + NativeLibraryLoader.loadLibrary(); } /** Policy string. */ diff --git a/CedarJava/src/main/java/com/cedarpolicy/value/EntityIdentifier.java b/CedarJava/src/main/java/com/cedarpolicy/value/EntityIdentifier.java index d3693153..c4a56a0e 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/value/EntityIdentifier.java +++ b/CedarJava/src/main/java/com/cedarpolicy/value/EntityIdentifier.java @@ -1,6 +1,8 @@ package com.cedarpolicy.value; +import com.cedarpolicy.library.NativeLibraryLoader; + /** * Class representing Entity Identifiers. * All strings are valid Entity Identifiers @@ -8,8 +10,8 @@ public final class EntityIdentifier { private String id; - static { - System.load(System.getenv("CEDAR_JAVA_FFI_LIB")); + static { + NativeLibraryLoader.loadLibrary(); } /** diff --git a/CedarJava/src/main/java/com/cedarpolicy/value/EntityTypeName.java b/CedarJava/src/main/java/com/cedarpolicy/value/EntityTypeName.java index 6fd42962..02ea9591 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/value/EntityTypeName.java +++ b/CedarJava/src/main/java/com/cedarpolicy/value/EntityTypeName.java @@ -1,6 +1,8 @@ package com.cedarpolicy.value; +import com.cedarpolicy.library.NativeLibraryLoader; + import java.util.List; import java.util.Optional; import java.util.Objects; @@ -17,7 +19,7 @@ public final class EntityTypeName { private List namespace; private String basename; static { - System.load(System.getenv("CEDAR_JAVA_FFI_LIB")); + NativeLibraryLoader.loadLibrary(); } /** diff --git a/CedarJava/src/main/java/com/cedarpolicy/value/EntityUID.java b/CedarJava/src/main/java/com/cedarpolicy/value/EntityUID.java index 80f927a9..2b31c177 100644 --- a/CedarJava/src/main/java/com/cedarpolicy/value/EntityUID.java +++ b/CedarJava/src/main/java/com/cedarpolicy/value/EntityUID.java @@ -19,6 +19,7 @@ import java.util.Optional; import java.util.Objects; +import com.cedarpolicy.library.NativeLibraryLoader; import com.cedarpolicy.serializer.JsonEUID; /** @@ -29,8 +30,8 @@ public final class EntityUID extends Value { private final EntityTypeName type; private final EntityIdentifier id; - static { - System.load(System.getenv("CEDAR_JAVA_FFI_LIB")); + static { + NativeLibraryLoader.loadLibrary(); } /** diff --git a/CedarJava/src/test/java/com/cedarpolicy/SharedIntegrationTests.java b/CedarJava/src/test/java/com/cedarpolicy/SharedIntegrationTests.java index 85f79caa..ab750c1c 100644 --- a/CedarJava/src/test/java/com/cedarpolicy/SharedIntegrationTests.java +++ b/CedarJava/src/test/java/com/cedarpolicy/SharedIntegrationTests.java @@ -62,8 +62,10 @@ import org.junit.jupiter.api.DynamicContainer; import org.junit.jupiter.api.DynamicTest; import org.junit.jupiter.api.TestFactory; +import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable; /** Integration tests Used by Cedar / corpus tests saved from the fuzzer. */ +@EnabledIfEnvironmentVariable(named = "CEDAR_INTEGRATION_TESTS_ROOT", matches = ".*") public class SharedIntegrationTests { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); private static final String CEDAR_INTEGRATION_TESTS_ROOT = diff --git a/CedarJava/src/test/java/com/cedarpolicy/pbt/IntegrationTests.java b/CedarJava/src/test/java/com/cedarpolicy/pbt/IntegrationTests.java index 52e02c29..66dfb5be 100644 --- a/CedarJava/src/test/java/com/cedarpolicy/pbt/IntegrationTests.java +++ b/CedarJava/src/test/java/com/cedarpolicy/pbt/IntegrationTests.java @@ -48,6 +48,7 @@ import net.jqwik.api.Property; import net.jqwik.api.constraints.IntRange; import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; /** Integration tests. */ @@ -302,6 +303,7 @@ public void testLongExprRequiresRustThread() { /** Tests a long expression that is denied for nearing the stack overflow limit. */ @Test + @Disabled public void testLongExprStackOverflowDeny() { Set entities = new HashSet<>(); String principalId = "alice"; diff --git a/CedarJavaFFI/Cargo.toml b/CedarJavaFFI/Cargo.toml index ca0d769e..73a73192 100644 --- a/CedarJavaFFI/Cargo.toml +++ b/CedarJavaFFI/Cargo.toml @@ -9,7 +9,7 @@ version = "3.0.0" [dependencies] serde = { version = "1.0", features = ["derive", "rc"] } serde_json = "1.0" -cedar-policy = { version = "3.0", path = "../../cedar/cedar-policy" } # Need latest version from github +cedar-policy = { version = "3.0.1" } # JNI Support jni = "0.21.0"