From 7bed1a7cf5a0de45928566f0c75cec1310010c8d Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Fri, 29 Jan 2021 13:49:04 +0100 Subject: [PATCH 1/2] Configurable COLLISION_BUFFER_POWER Signed-off-by: Jorge Bescos Gascon --- .../jersey/server/ServerProperties.java | 10 +++++- .../monitoring/core/ReservoirConstants.java | 33 +++++++++++++++++-- .../AbstractNanosReservoirTest.java | 9 ++--- .../TimeWindowStatisticsImplTest.java | 33 ++++++++++++++----- core-server/src/test/resources/server.policy | 5 ++- 5 files changed, 73 insertions(+), 17 deletions(-) diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java b/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java index 391d063586..6055e2cb46 100644 --- a/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java +++ b/core-server/src/main/java/org/glassfish/jersey/server/ServerProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -741,6 +741,14 @@ public final class ServerProperties { public static final String UNWRAP_COMPLETION_STAGE_IN_WRITER_ENABLE = "jersey.config.server.unwrap.completion.stage.writer.enable"; + /** + * JVM argument to define the value of + * {@link org.glassfish.jersey.server.internal.monitoring.core.ReservoirConstants#COLLISION_BUFFER_POWER}. + * Lower values reduce the memory footprint. + */ + public static final String COLLISION_BUFFER_POWER_JVM_ARG = + "jersey.config.server.monitoring.collision.buffer.power"; + private ServerProperties() { // prevents instantiation } diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java index a161fdcf80..44eac14396 100644 --- a/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java +++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java @@ -1,5 +1,5 @@ /* - * Copyright 2015, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright 2015, 2021 Oracle and/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. @@ -16,6 +16,12 @@ package org.glassfish.jersey.server.internal.monitoring.core; +import java.security.PrivilegedAction; +import java.util.logging.Level; +import java.util.logging.Logger; + +import org.glassfish.jersey.server.ServerProperties; + /** * The constants that determine the behaviour of sliding windows and their trimmers. * @@ -23,21 +29,42 @@ */ public final class ReservoirConstants { + private static final int DEFAULT_COLLISION_BUFFER_POWER = 8; + /** * Allow for 2^that many duplicate ticks before throwing away measurements. + * This value is by default {@link DEFAULT_COLLISION_BUFFER_POWER}, but it can be configured + * with {@link COLLISION_BUFFER_POWER_JVM_ARG} JVM argument */ - public static final int COLLISION_BUFFER_POWER = 8; + public static final int COLLISION_BUFFER_POWER; /** * The size of the collision buffer derived from the collision buffer power. */ - public static final int COLLISION_BUFFER = 1 << COLLISION_BUFFER_POWER; // 256 + public static final int COLLISION_BUFFER; /** * Only trim on updating once every N. */ public static final int TRIM_THRESHOLD = 256; + static { + PrivilegedAction action = new PrivilegedAction() { + @Override + public Integer run() { + return Integer.getInteger(ServerProperties.COLLISION_BUFFER_POWER_JVM_ARG, DEFAULT_COLLISION_BUFFER_POWER); + } + }; + int collisionBuffePower = DEFAULT_COLLISION_BUFFER_POWER; + try { + collisionBuffePower = action.run(); + } catch (SecurityException e) { + Logger.getLogger(ReservoirConstants.class.getName()).log(Level.WARNING, e.getLocalizedMessage(), e); + } + COLLISION_BUFFER_POWER = collisionBuffePower; + COLLISION_BUFFER = 1 << COLLISION_BUFFER_POWER; // 256 + } + private ReservoirConstants() { throw new AssertionError("Instantiation not allowed."); } diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/AbstractNanosReservoirTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/AbstractNanosReservoirTest.java index 8feaf59089..abdc102588 100644 --- a/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/AbstractNanosReservoirTest.java +++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/AbstractNanosReservoirTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -16,11 +16,12 @@ package org.glassfish.jersey.server.internal.monitoring; +import java.util.concurrent.TimeUnit; + +import org.glassfish.jersey.server.internal.monitoring.core.ReservoirConstants; import org.glassfish.jersey.server.internal.monitoring.core.TimeReservoir; import org.glassfish.jersey.server.internal.monitoring.core.UniformTimeSnapshot; -import java.util.concurrent.TimeUnit; - import static org.junit.Assert.assertEquals; /** @@ -29,7 +30,7 @@ public class AbstractNanosReservoirTest { protected static final double DELTA = 0.0001; - protected static final int COLLISION_BUFFER = 256; + protected static final int COLLISION_BUFFER = ReservoirConstants.COLLISION_BUFFER; protected void reservoirUpdateInNanos(TimeReservoir reservoir, long value, long time) { reservoir.update(value, time, TimeUnit.NANOSECONDS); diff --git a/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java b/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java index b6ca7c41f0..d92393e347 100644 --- a/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java +++ b/core-server/src/test/java/org/glassfish/jersey/server/internal/monitoring/TimeWindowStatisticsImplTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -18,8 +18,12 @@ import java.util.concurrent.TimeUnit; +import org.glassfish.jersey.server.ServerProperties; +import org.glassfish.jersey.server.internal.monitoring.core.ReservoirConstants; import org.glassfish.jersey.server.internal.monitoring.core.UniformTimeReservoir; +import org.junit.BeforeClass; import org.junit.Test; + import static org.junit.Assert.assertEquals; /** @@ -30,8 +34,21 @@ */ public class TimeWindowStatisticsImplTest { + private static final int COLLISION_BUFFER_POWER = 3; private static final double DELTA = 0.0001; + @BeforeClass + public static void beforeClass() { + System.setProperty(ServerProperties.COLLISION_BUFFER_POWER_JVM_ARG, + Integer.toString(COLLISION_BUFFER_POWER)); + } + + @Test + public void jvmLoaded() { + assertEquals(COLLISION_BUFFER_POWER, ReservoirConstants.COLLISION_BUFFER_POWER); + assertEquals(8, ReservoirConstants.COLLISION_BUFFER); + } + @Test public void test() { final long now = System.currentTimeMillis(); @@ -173,30 +190,30 @@ public void testExhaustiveRequestsAtTheSameTime() { final TimeWindowStatisticsImpl.Builder builder = new TimeWindowStatisticsImpl.Builder<>( new SlidingWindowTimeReservoir(1, TimeUnit.SECONDS, now, TimeUnit.MILLISECONDS)); // put multiple requests at the beginning so that even the COLLISION_BUFFER bounds is tested - for (int i = 0; i < 256; ++i) { + for (int i = 0; i < ReservoirConstants.COLLISION_BUFFER; ++i) { builder.addRequest(now, 10L); } // add one more request which should be visible at 'now + 1001' builder.addRequest(now + 1, 10L); // put multiple requests in the middle of the window - for (int i = 0; i < 256; ++i) { + for (int i = 0; i < ReservoirConstants.COLLISION_BUFFER; ++i) { builder.addRequest(now + 500, 10L); } - check(builder, now + 500, 256 * 2 + 1, 10, 10, 10, 256 * 2 * 2 + 1 * 2); + check(builder, now + 500, ReservoirConstants.COLLISION_BUFFER * 2 + 1, 10, 10, 10, ReservoirConstants.COLLISION_BUFFER * 2 * 2 + 1 * 2); // put multiple requests at the end of the window - for (int i = 0; i < 256; ++i) { + for (int i = 0; i < ReservoirConstants.COLLISION_BUFFER; ++i) { builder.addRequest(now + 1000, 10L); } - check(builder, now + 1000, 256 * 3 + 1, 10, 10, 10, 256 * 3 + 1); + check(builder, now + 1000, ReservoirConstants.COLLISION_BUFFER * 3 + 1, 10, 10, 10, ReservoirConstants.COLLISION_BUFFER * 3 + 1); // at 'now + 1001' all the requests from 'now' should be gone - check(builder, now + 1001, 256 * 2 + 1, 10, 10, 10, 256 * 2 + 1); + check(builder, now + 1001, ReservoirConstants.COLLISION_BUFFER * 2 + 1, 10, 10, 10, ReservoirConstants.COLLISION_BUFFER * 2 + 1); // at 'now + 1002' the one additional request we added is gone - check(builder, now + 1002, 256 * 2, 10, 10, 10, 256 * 2); + check(builder, now + 1002, ReservoirConstants.COLLISION_BUFFER * 2, 10, 10, 10, ReservoirConstants.COLLISION_BUFFER * 2); } /** diff --git a/core-server/src/test/resources/server.policy b/core-server/src/test/resources/server.policy index e37eeda4dd..a8c8303dd5 100644 --- a/core-server/src/test/resources/server.policy +++ b/core-server/src/test/resources/server.policy @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -60,6 +60,9 @@ grant codebase "file:${project.build.directory}/test-classes/-" { permission java.lang.RuntimePermission "accessClassInPackage.sun.misc.*"; permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect"; permission java.lang.RuntimePermission "reflectionFactoryAccess"; + + // Needed by TimeWindowStatisticsImplTest + permission java.util.PropertyPermission "jersey.config.server.monitoring.collision.buffer.power", "read,write"; }; grant codebase "file:${project.build.directory}/classes/-" { From 7d603d20892742d0e9e86276bb61e2d90a921272 Mon Sep 17 00:00:00 2001 From: Jorge Bescos Gascon Date: Mon, 22 Feb 2021 15:34:46 +0100 Subject: [PATCH 2/2] Adding AccessController Signed-off-by: Jorge Bescos Gascon --- .../internal/monitoring/core/ReservoirConstants.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java b/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java index 44eac14396..fe0a7ada15 100644 --- a/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java +++ b/core-server/src/main/java/org/glassfish/jersey/server/internal/monitoring/core/ReservoirConstants.java @@ -16,6 +16,7 @@ package org.glassfish.jersey.server.internal.monitoring.core; +import java.security.AccessController; import java.security.PrivilegedAction; import java.util.logging.Level; import java.util.logging.Logger; @@ -55,13 +56,7 @@ public Integer run() { return Integer.getInteger(ServerProperties.COLLISION_BUFFER_POWER_JVM_ARG, DEFAULT_COLLISION_BUFFER_POWER); } }; - int collisionBuffePower = DEFAULT_COLLISION_BUFFER_POWER; - try { - collisionBuffePower = action.run(); - } catch (SecurityException e) { - Logger.getLogger(ReservoirConstants.class.getName()).log(Level.WARNING, e.getLocalizedMessage(), e); - } - COLLISION_BUFFER_POWER = collisionBuffePower; + COLLISION_BUFFER_POWER = AccessController.doPrivileged(action); COLLISION_BUFFER = 1 << COLLISION_BUFFER_POWER; // 256 }