99
1010package org .elasticsearch .bootstrap ;
1111
12+ import org .elasticsearch .core .Nullable ;
1213import org .elasticsearch .core .SuppressForbidden ;
13- import org .elasticsearch .entitlement .runtime .policy .PolicyManager ;
14+ import org .elasticsearch .entitlement .runtime .policy .PolicyManager . PolicyScope ;
1415import org .elasticsearch .logging .LogManager ;
1516import org .elasticsearch .logging .Logger ;
1617
18+ import java .lang .module .ModuleDescriptor ;
19+ import java .lang .module .ModuleFinder ;
1720import java .net .MalformedURLException ;
1821import java .net .URL ;
1922import java .util .List ;
2225import java .util .TreeMap ;
2326import java .util .function .Function ;
2427
28+ import static java .util .Objects .requireNonNull ;
29+ import static java .util .stream .Collectors .toSet ;
2530import static org .elasticsearch .entitlement .runtime .policy .PolicyManager .ALL_UNNAMED ;
2631import static org .elasticsearch .entitlement .runtime .policy .PolicyManager .ComponentKind .PLUGIN ;
32+ import static org .elasticsearch .entitlement .runtime .policy .PolicyManager .ComponentKind .SERVER ;
33+ import static org .elasticsearch .entitlement .runtime .policy .PolicyManager .MODULES_EXCLUDED_FROM_SYSTEM_MODULES ;
2734
28- public record TestScopeResolver ( Map < String , PolicyManager . PolicyScope > scopeMap ) {
35+ public final class TestScopeResolver {
2936
3037 private static final Logger logger = LogManager .getLogger (TestScopeResolver .class );
38+ private final Map <String , PolicyScope > scopeMap ;
39+ private static final Map <String , PolicyScope > excludedSystemPackageScopes = computeExcludedSystemPackageScopes ();
3140
32- PolicyManager .PolicyScope getScope (Class <?> callerClass ) {
41+ public TestScopeResolver (Map <String , PolicyScope > scopeMap ) {
42+ this .scopeMap = scopeMap ;
43+ }
44+
45+ private static Map <String , PolicyScope > computeExcludedSystemPackageScopes () {
46+ // Within any one module layer, module names are unique, so we just need the names
47+ Set <String > systemModuleNames = ModuleFinder .ofSystem ()
48+ .findAll ()
49+ .stream ()
50+ .map (ref -> ref .descriptor ().name ())
51+ .filter (MODULES_EXCLUDED_FROM_SYSTEM_MODULES ::contains )
52+ .collect (toSet ());
53+
54+ Map <String , PolicyScope > result = new TreeMap <>();
55+ ModuleLayer .boot ().modules ().stream ().filter (m -> systemModuleNames .contains (m .getName ())).forEach (m -> {
56+ ModuleDescriptor desc = m .getDescriptor ();
57+ if (desc != null ) {
58+ desc .packages ().forEach (pkg ->
59+ // Our component identification logic returns SERVER for these
60+ result .put (pkg , new PolicyScope (SERVER , SERVER .componentName , m .getName ())));
61+ }
62+ });
63+ return result ;
64+ }
65+
66+ public static @ Nullable PolicyScope getExcludedSystemPackageScope (Class <?> callerClass ) {
67+ return excludedSystemPackageScopes .get (callerClass .getPackageName ());
68+ }
69+
70+ PolicyScope getScope (Class <?> callerClass ) {
3371 var callerCodeSource = callerClass .getProtectionDomain ().getCodeSource ();
34- assert callerCodeSource != null ;
72+ if (callerCodeSource == null ) {
73+ // This only happens for JDK classes. Furthermore, for trivially allowed modules, we shouldn't even get here.
74+ // Hence, this must be an excluded system module, so check for that.
75+ return requireNonNull (getExcludedSystemPackageScope (callerClass ));
76+ }
3577
3678 var location = callerCodeSource .getLocation ().toString ();
3779 var scope = scopeMap .get (location );
3880 if (scope == null ) {
3981 // Special cases for libraries not handled by our automatically-generated scopeMap
4082 if (callerClass .getPackageName ().startsWith ("org.bouncycastle" )) {
41- scope = new PolicyManager . PolicyScope (PLUGIN , "security" , ALL_UNNAMED );
83+ scope = new PolicyScope (PLUGIN , "security" , ALL_UNNAMED );
4284 logger .debug ("Assuming bouncycastle is part of the security plugin" );
4385 }
4486 }
4587 if (scope == null ) {
4688 logger .warn ("Cannot identify a scope for class [{}], location [{}]" , callerClass .getName (), location );
47- return PolicyManager . PolicyScope .unknown (location );
89+ return PolicyScope .unknown (location );
4890 }
4991 return scope ;
5092 }
5193
52- public static Function <Class <?>, PolicyManager . PolicyScope > createScopeResolver (
94+ public static Function <Class <?>, PolicyScope > createScopeResolver (
5395 TestBuildInfo serverBuildInfo ,
5496 List <TestBuildInfo > pluginsBuildInfo ,
5597 Set <String > modularPlugins
5698 ) {
57- Map <String , PolicyManager . PolicyScope > scopeMap = new TreeMap <>(); // Sorted to make it easier to read during debugging
99+ Map <String , PolicyScope > scopeMap = new TreeMap <>(); // Sorted to make it easier to read during debugging
58100 for (var pluginBuildInfo : pluginsBuildInfo ) {
59101 boolean isModular = modularPlugins .contains (pluginBuildInfo .component ());
60102 for (var location : pluginBuildInfo .locations ()) {
@@ -66,7 +108,7 @@ public static Function<Class<?>, PolicyManager.PolicyScope> createScopeResolver(
66108 String module = isModular ? location .module () : ALL_UNNAMED ;
67109 scopeMap .put (
68110 getCodeSource (codeSource , location .representativeClass ()),
69- PolicyManager . PolicyScope .plugin (pluginBuildInfo .component (), module )
111+ PolicyScope .plugin (pluginBuildInfo .component (), module )
70112 );
71113 } catch (MalformedURLException e ) {
72114 throw new IllegalArgumentException ("Cannot locate class [" + location .representativeClass () + "]" , e );
@@ -81,7 +123,7 @@ public static Function<Class<?>, PolicyManager.PolicyScope> createScopeResolver(
81123 continue ;
82124 }
83125 try {
84- scopeMap .put (getCodeSource (classUrl , location .representativeClass ()), PolicyManager . PolicyScope .server (location .module ()));
126+ scopeMap .put (getCodeSource (classUrl , location .representativeClass ()), PolicyScope .server (location .module ()));
85127 } catch (MalformedURLException e ) {
86128 throw new IllegalArgumentException ("Cannot locate class [" + location .representativeClass () + "]" , e );
87129 }
0 commit comments