Skip to content

Commit

Permalink
Make forbidden apis check cacheable and cc compatible
Browse files Browse the repository at this point in the history
  • Loading branch information
breskeby committed Oct 23, 2023
1 parent 4abc81c commit 6d126d8
Show file tree
Hide file tree
Showing 10 changed files with 671 additions and 79 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -8,50 +8,37 @@

package org.elasticsearch.gradle.internal.precommit;

import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApisExtension;
import groovy.lang.Closure;

import org.elasticsearch.gradle.internal.ExportElasticsearchBuildResourcesTask;
import org.elasticsearch.gradle.internal.conventions.precommit.PrecommitPlugin;
import org.elasticsearch.gradle.internal.info.BuildParams;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.plugins.ExtraPropertiesExtension;
import org.gradle.api.plugins.JavaBasePlugin;
import org.gradle.api.plugins.JavaPluginExtension;
import org.gradle.api.specs.Specs;
import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskProvider;

import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.io.File;
import java.util.Set;

import static de.thetaphi.forbiddenapis.gradle.ForbiddenApisPlugin.FORBIDDEN_APIS_EXTENSION_NAME;
import static de.thetaphi.forbiddenapis.gradle.ForbiddenApisPlugin.FORBIDDEN_APIS_TASK_NAME;
import static org.elasticsearch.gradle.internal.precommit.CheckForbiddenApisTask.BUNDLED_SIGNATURE_DEFAULTS;

public class ForbiddenApisPrecommitPlugin extends PrecommitPlugin {

@Override
public TaskProvider<? extends Task> createTask(Project project) {
project.getPluginManager().apply(JavaBasePlugin.class);

// create Extension for defaults:
var checkForbiddenApisExtension = project.getExtensions()
.create(FORBIDDEN_APIS_EXTENSION_NAME, CheckForbiddenApisExtension.class, project);

// Create a convenience task for all checks (this does not conflict with extension, as it has higher priority in DSL):
var forbiddenTask = project.getTasks()
.register(FORBIDDEN_APIS_TASK_NAME, task -> { task.setDescription("Runs forbidden-apis checks."); });

JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);
// Define our tasks (one for each SourceSet):

TaskProvider<ExportElasticsearchBuildResourcesTask> resourcesTask = project.getTasks()
.register("forbiddenApisResources", ExportElasticsearchBuildResourcesTask.class);
Path resourcesDir = project.getBuildDir().toPath().resolve("forbidden-apis-config");
File resourcesDir = project.getLayout().getBuildDirectory().dir("forbidden-apis-config").get().getAsFile();
resourcesTask.configure(t -> {
t.setOutputDir(resourcesDir.toFile());
t.setOutputDir(resourcesDir);
t.copy("forbidden/jdk-signatures.txt");
t.copy("forbidden/jdk-deprecated.txt");
t.copy("forbidden/es-all-signatures.txt");
Expand All @@ -65,60 +52,36 @@ public TaskProvider<? extends Task> createTask(Project project) {
String sourceSetTaskName = sourceSet.getTaskName(FORBIDDEN_APIS_TASK_NAME, null);
var sourceSetTask = project.getTasks().register(sourceSetTaskName, CheckForbiddenApisTask.class, t -> {
t.setDescription("Runs forbidden-apis checks on '${sourceSet.name}' classes.");
t.setResourcesDir(resourcesDir);
t.getOutputs().upToDateWhen(Specs.SATISFIES_ALL);
t.setClassesDirs(sourceSet.getOutput().getClassesDirs());
t.dependsOn(resourcesTask);
t.setClasspath(sourceSet.getRuntimeClasspath().plus(sourceSet.getCompileClasspath()).plus(sourceSet.getOutput()));
t.setTargetCompatibility(BuildParams.getMinimumRuntimeVersion().getMajorVersion());
t.setBundledSignatures(Set.of("jdk-unsafe", "jdk-non-portable", "jdk-system-out"));
t.getBundledSignatures().set(BUNDLED_SIGNATURE_DEFAULTS);
t.setSignaturesFiles(
project.files(
resourcesDir.resolve("forbidden/jdk-signatures.txt"),
resourcesDir.resolve("forbidden/es-all-signatures.txt"),
resourcesDir.resolve("forbidden/jdk-deprecated.txt")
resourcesDir.toPath().resolve("forbidden/jdk-signatures.txt"),
resourcesDir.toPath().resolve("forbidden/es-all-signatures.txt"),
resourcesDir.toPath().resolve("forbidden/jdk-deprecated.txt")
)
);
t.setSuppressAnnotations(Set.of("**.SuppressForbidden"));
t.getSuppressAnnotations().set(Set.of("**.SuppressForbidden"));
if (t.getName().endsWith("Test")) {
t.setSignaturesFiles(
t.getSignaturesFiles()
.plus(
project.files(
resourcesDir.resolve("forbidden/es-test-signatures.txt"),
resourcesDir.resolve("forbidden/http-signatures.txt")
resourcesDir.toPath().resolve("forbidden/es-test-signatures.txt"),
resourcesDir.toPath().resolve("forbidden/http-signatures.txt")
)
)
);
} else {
t.setSignaturesFiles(
t.getSignaturesFiles().plus(project.files(resourcesDir.resolve("forbidden/es-server-signatures.txt")))
t.getSignaturesFiles().plus(project.files(resourcesDir.toPath().resolve("forbidden/es-server-signatures.txt")))
);
}
ExtraPropertiesExtension ext = t.getExtensions().getExtraProperties();
ext.set("replaceSignatureFiles", new Closure<Void>(t) {
@Override
public Void call(Object... names) {
List<Path> resources = new ArrayList<>(names.length);
for (Object name : names) {
resources.add(resourcesDir.resolve("forbidden/" + name + ".txt"));
}
t.setSignaturesFiles(project.files(resources));
return null;
}

});
ext.set("addSignatureFiles", new Closure<Void>(t) {
@Override
public Void call(Object... names) {
List<Path> resources = new ArrayList<>(names.length);
for (Object name : names) {
resources.add(resourcesDir.resolve("forbidden/" + name + ".txt"));
}
t.setSignaturesFiles(t.getSignaturesFiles().plus(project.files(resources)));
return null;
}
});

});
forbiddenTask.configure(t -> t.dependsOn(sourceSetTask));
});
Expand Down
11 changes: 7 additions & 4 deletions client/rest/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import org.elasticsearch.gradle.internal.precommit.CheckForbiddenApisTask

import org.elasticsearch.gradle.VersionProperties
import org.elasticsearch.gradle.internal.conventions.precommit.LicenseHeadersTask
Expand Down Expand Up @@ -60,7 +60,7 @@ tasks.named("processResources").configure {
]
}

tasks.withType(CheckForbiddenApis).configureEach {
tasks.withType(CheckForbiddenApisTask).configureEach {
//client does not depend on server, so only jdk and http signatures should be checked
replaceSignatureFiles('jdk-signatures', 'http-signatures')
}
Expand All @@ -71,8 +71,11 @@ tasks.named("forbiddenPatterns").configure {

tasks.named('forbiddenApisTest').configure {
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
modifyBundledSignatures { signatures ->
signatures -= 'jdk-non-portable'
signatures += 'jdk-internal'
signatures
}
}

// JarHell is part of es server, which we don't want to pull in
Expand Down
8 changes: 6 additions & 2 deletions client/sniffer/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,12 @@ tasks.named('forbiddenApisMain').configure {

tasks.named('forbiddenApisTest').configure {
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
modifyBundledSignatures { bundledSignatures ->
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
bundledSignatures
}

//client does not depend on server, so only jdk signatures should be checked
replaceSignatureFiles 'jdk-signatures'
}
Expand Down
7 changes: 5 additions & 2 deletions client/test/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,11 @@ tasks.named('forbiddenApisMain').configure {

tasks.named('forbiddenApisTest').configure {
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
modifyBundledSignatures { bundledSignatures ->
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
bundledSignatures
}
//client does not depend on core, so only jdk signatures should be checked
replaceSignatureFiles 'jdk-signatures'
}
Expand Down
4 changes: 2 additions & 2 deletions distribution/tools/server-cli/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import org.elasticsearch.gradle.internal.precommit.CheckForbiddenApisTask

apply plugin: 'elasticsearch.build'

Expand All @@ -20,7 +20,7 @@ tasks.named("test").configure {
systemProperty "tests.security.manager", "false"
}

tasks.withType(CheckForbiddenApis).configureEach {
tasks.withType(CheckForbiddenApisTask).configureEach {
replaceSignatureFiles 'jdk-signatures'
}

Expand Down
7 changes: 7 additions & 0 deletions server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ spotless {
}
}

tasks.withType(Test).configureEach {
doFirst {
it.systemProperties.each {
println it.key + " -- " + it.value
}
}
}
tasks.named("forbiddenPatterns").configure {
exclude '**/*.json'
exclude '**/*.jmx'
Expand Down
7 changes: 5 additions & 2 deletions x-pack/plugin/security/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,11 @@ tasks.named('forbiddenApisMain').configure {

tasks.named('forbiddenApisTest').configure {
//we are using jdk-internal instead of jdk-non-portable to allow for com.sun.net.httpserver.* usage
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
modifyBundledSignatures { bundledSignatures ->
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
bundledSignatures
}
}

// classes are missing, e.g. com.ibm.icu.lang.UCharacter
Expand Down
9 changes: 6 additions & 3 deletions x-pack/plugin/security/cli/build.gradle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
import org.elasticsearch.gradle.internal.precommit.CheckForbiddenApisTask
import org.elasticsearch.gradle.internal.info.BuildParams

apply plugin: 'elasticsearch.build'
Expand Down Expand Up @@ -52,7 +52,10 @@ if (BuildParams.inFipsJvm) {
}
// Forbiden APIs non-portable checks fail because bouncy castle classes being used from the FIPS JDK since those are
// not part of the Java specification - all of this is as designed, so we have to relax this check for FIPS.
tasks.withType(CheckForbiddenApis).configureEach {
bundledSignatures -= "jdk-non-portable"
tasks.withType(CheckForbiddenApisTask).configureEach {
modifyBundledSignatures { bundledSignatures ->
bundledSignatures -= "jdk-non-portable"
bundledSignatures
}
}
}
7 changes: 5 additions & 2 deletions x-pack/plugin/sql/sql-client/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ tasks.named('forbiddenApisMain').configure {
}

tasks.named('forbiddenApisTest').configure {
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
modifyBundledSignatures { bundledSignatures ->
bundledSignatures -= 'jdk-non-portable'
bundledSignatures += 'jdk-internal'
bundledSignatures
}
}

tasks.named("forbiddenPatterns").configure {
Expand Down

0 comments on commit 6d126d8

Please sign in to comment.