42
42
import java .nio .file .Files ;
43
43
import java .nio .file .Path ;
44
44
import java .nio .file .Paths ;
45
+ import java .security .AccessController ;
46
+ import java .security .PrivilegedAction ;
45
47
import java .time .Duration ;
46
48
import java .util .Arrays ;
47
49
import java .util .Iterator ;
@@ -175,57 +177,60 @@ private EhcacheDiskCache(Builder<K, V> builder) {
175
177
176
178
@ SuppressWarnings ({ "rawtypes" })
177
179
private Cache <ICacheKey , ByteArrayWrapper > buildCache (Duration expireAfterAccess , Builder <K , V > builder ) {
178
- try {
179
- return this .cacheManager .createCache (
180
- this .diskCacheAlias ,
181
- CacheConfigurationBuilder .newCacheConfigurationBuilder (
182
- ICacheKey .class ,
183
- ByteArrayWrapper .class ,
184
- ResourcePoolsBuilder .newResourcePoolsBuilder ().disk (maxWeightInBytes , MemoryUnit .B )
185
- ).withExpiry (new ExpiryPolicy <>() {
186
- @ Override
187
- public Duration getExpiryForCreation (ICacheKey key , ByteArrayWrapper value ) {
188
- return INFINITE ;
189
- }
190
-
191
- @ Override
192
- public Duration getExpiryForAccess (ICacheKey key , Supplier <? extends ByteArrayWrapper > value ) {
193
- return expireAfterAccess ;
194
- }
195
-
196
- @ Override
197
- public Duration getExpiryForUpdate (
198
- ICacheKey key ,
199
- Supplier <? extends ByteArrayWrapper > oldValue ,
200
- ByteArrayWrapper newValue
201
- ) {
202
- return INFINITE ;
203
- }
204
- })
205
- .withService (getListenerConfiguration (builder ))
206
- .withService (
207
- new OffHeapDiskStoreConfiguration (
208
- this .threadPoolAlias ,
209
- (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType )
210
- .get (DISK_WRITE_CONCURRENCY_KEY )
211
- .get (settings ),
212
- (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType ).get (DISK_SEGMENT_KEY ).get (settings )
180
+ // Creating the cache requires permissions specified in plugin-security.policy
181
+ return AccessController .doPrivileged ((PrivilegedAction <Cache <ICacheKey , ByteArrayWrapper >>) () -> {
182
+ try {
183
+ return this .cacheManager .createCache (
184
+ this .diskCacheAlias ,
185
+ CacheConfigurationBuilder .newCacheConfigurationBuilder (
186
+ ICacheKey .class ,
187
+ ByteArrayWrapper .class ,
188
+ ResourcePoolsBuilder .newResourcePoolsBuilder ().disk (maxWeightInBytes , MemoryUnit .B )
189
+ ).withExpiry (new ExpiryPolicy <>() {
190
+ @ Override
191
+ public Duration getExpiryForCreation (ICacheKey key , ByteArrayWrapper value ) {
192
+ return INFINITE ;
193
+ }
194
+
195
+ @ Override
196
+ public Duration getExpiryForAccess (ICacheKey key , Supplier <? extends ByteArrayWrapper > value ) {
197
+ return expireAfterAccess ;
198
+ }
199
+
200
+ @ Override
201
+ public Duration getExpiryForUpdate (
202
+ ICacheKey key ,
203
+ Supplier <? extends ByteArrayWrapper > oldValue ,
204
+ ByteArrayWrapper newValue
205
+ ) {
206
+ return INFINITE ;
207
+ }
208
+ })
209
+ .withService (getListenerConfiguration (builder ))
210
+ .withService (
211
+ new OffHeapDiskStoreConfiguration (
212
+ this .threadPoolAlias ,
213
+ (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType )
214
+ .get (DISK_WRITE_CONCURRENCY_KEY )
215
+ .get (settings ),
216
+ (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType ).get (DISK_SEGMENT_KEY ).get (settings )
217
+ )
213
218
)
214
- )
215
- .withKeySerializer (new KeySerializerWrapper (keySerializer ))
216
- .withValueSerializer (new ByteArrayWrapperSerializer ())
219
+ .withKeySerializer (new KeySerializerWrapper (keySerializer ))
220
+ .withValueSerializer (new ByteArrayWrapperSerializer ())
217
221
// We pass ByteArrayWrapperSerializer as ehcache's value serializer. If V is an interface, and we pass its
218
222
// serializer directly to ehcache, ehcache requires the classes match exactly before/after serialization.
219
223
// This is not always feasible or necessary, like for BytesReference. So, we handle the value serialization
220
224
// before V hits ehcache.
221
- );
222
- } catch (IllegalArgumentException ex ) {
223
- logger .error ("Ehcache disk cache initialization failed due to illegal argument: {}" , ex .getMessage ());
224
- throw ex ;
225
- } catch (IllegalStateException ex ) {
226
- logger .error ("Ehcache disk cache initialization failed: {}" , ex .getMessage ());
227
- throw ex ;
228
- }
225
+ );
226
+ } catch (IllegalArgumentException ex ) {
227
+ logger .error ("Ehcache disk cache initialization failed due to illegal argument: {}" , ex .getMessage ());
228
+ throw ex ;
229
+ } catch (IllegalStateException ex ) {
230
+ logger .error ("Ehcache disk cache initialization failed: {}" , ex .getMessage ());
231
+ throw ex ;
232
+ }
233
+ });
229
234
}
230
235
231
236
private CacheEventListenerConfigurationBuilder getListenerConfiguration (Builder <K , V > builder ) {
@@ -252,25 +257,28 @@ Map<ICacheKey<K>, CompletableFuture<Tuple<ICacheKey<K>, V>>> getCompletableFutur
252
257
@ SuppressForbidden (reason = "Ehcache uses File.io" )
253
258
private PersistentCacheManager buildCacheManager () {
254
259
// In case we use multiple ehCaches, we can define this cache manager at a global level.
255
- return CacheManagerBuilder .newCacheManagerBuilder ()
256
- .with (CacheManagerBuilder .persistence (new File (storagePath )))
257
-
258
- .using (
259
- PooledExecutionServiceConfigurationBuilder .newPooledExecutionServiceConfigurationBuilder ()
260
- .defaultPool (THREAD_POOL_ALIAS_PREFIX + "Default#" + UNIQUE_ID , 1 , 3 ) // Default pool used for other tasks
261
- // like event listeners
262
- .pool (
263
- this .threadPoolAlias ,
264
- (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType )
265
- .get (DISK_WRITE_MIN_THREADS_KEY )
266
- .get (settings ),
267
- (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType )
268
- .get (DISK_WRITE_MAXIMUM_THREADS_KEY )
269
- .get (settings )
270
- )
271
- .build ()
272
- )
273
- .build (true );
260
+ // Creating the cache manager also requires permissions specified in plugin-security.policy
261
+ return AccessController .doPrivileged ((PrivilegedAction <PersistentCacheManager >) () -> {
262
+ return CacheManagerBuilder .newCacheManagerBuilder ()
263
+ .with (CacheManagerBuilder .persistence (new File (storagePath )))
264
+
265
+ .using (
266
+ PooledExecutionServiceConfigurationBuilder .newPooledExecutionServiceConfigurationBuilder ()
267
+ .defaultPool (THREAD_POOL_ALIAS_PREFIX + "Default#" + UNIQUE_ID , 1 , 3 ) // Default pool used for other tasks
268
+ // like event listeners
269
+ .pool (
270
+ this .threadPoolAlias ,
271
+ (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType )
272
+ .get (DISK_WRITE_MIN_THREADS_KEY )
273
+ .get (settings ),
274
+ (Integer ) EhcacheDiskCacheSettings .getSettingListForCacheType (cacheType )
275
+ .get (DISK_WRITE_MAXIMUM_THREADS_KEY )
276
+ .get (settings )
277
+ )
278
+ .build ()
279
+ )
280
+ .build (true );
281
+ });
274
282
}
275
283
276
284
@ Override
0 commit comments