Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PAYARA-2721 MicroProfile Fault Tolerance 1.1.1 #3084

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,11 @@
<artifactId>microprofile-config-api</artifactId>
<version>${microprofile-config.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.metrics</groupId>
<artifactId>microprofile-metrics-api</artifactId>
<version>${microprofile-metrics.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.main.common</groupId>
<artifactId>internal-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
import javax.naming.NamingException;
import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.faulttolerance.CircuitBreaker;
import org.eclipse.microprofile.metrics.Gauge;
import org.eclipse.microprofile.metrics.MetricRegistry;
import org.glassfish.api.StartupRunLevel;
import org.glassfish.api.admin.ServerEnvironment;
import org.glassfish.api.event.EventListener;
Expand All @@ -67,6 +69,7 @@
import org.glassfish.hk2.api.ServiceLocator;
import org.glassfish.hk2.runlevel.RunLevel;
import org.glassfish.internal.data.ApplicationInfo;
import org.glassfish.internal.data.ApplicationRegistry;
import org.glassfish.internal.deployment.Deployment;
import org.jvnet.hk2.annotations.Optional;
import org.jvnet.hk2.annotations.Service;
Expand All @@ -81,6 +84,7 @@
public class FaultToleranceService implements EventListener {

public static final String FAULT_TOLERANCE_ENABLED_PROPERTY = "MP_Fault_Tolerance_NonFallback_Enabled";
public static final String METRICS_ENABLED_PROPERTY = "MP_Fault_Tolerance_Metrics_Enabled";
public static final String FALLBACK_HANDLER_METHOD_NAME = "handle";

private static final Logger logger = Logger.getLogger(FaultToleranceService.class.getName());
Expand All @@ -100,12 +104,14 @@ public class FaultToleranceService implements EventListener {
Events events;

private final Map<String, Boolean> enabledMap;
private final Map<String, Boolean> metricsEnabledMap;
private final Map<String, Map<String, Semaphore>> bulkheadExecutionSemaphores;
private final Map<String, Map<String, Semaphore>> bulkheadExecutionQueueSemaphores;
private final Map<String, Map<String, CircuitBreakerState>> circuitBreakerStates;

public FaultToleranceService() {
enabledMap = new ConcurrentHashMap<>();
metricsEnabledMap = new ConcurrentHashMap<>();
bulkheadExecutionSemaphores = new ConcurrentHashMap<>();
bulkheadExecutionQueueSemaphores = new ConcurrentHashMap<>();
circuitBreakerStates = new ConcurrentHashMap<>();
Expand Down Expand Up @@ -146,7 +152,20 @@ public Boolean isFaultToleranceEnabled(String applicationName, Config config) {
setFaultToleranceEnabled(applicationName, config);
return enabledMap.get(applicationName);
}

}

public Boolean isFaultToleranceMetricsEnabled(String applicationName, Config config) {
try {
if (metricsEnabledMap.containsKey(applicationName)) {
return metricsEnabledMap.get(applicationName);
} else {
setFaultToleranceMetricsEnabled(applicationName, config);
return metricsEnabledMap.get(applicationName);
}
} catch (NullPointerException npe) {
setFaultToleranceMetricsEnabled(applicationName, config);
return metricsEnabledMap.get(applicationName);
}
}

/**
Expand Down Expand Up @@ -183,6 +202,27 @@ private synchronized void setFaultToleranceEnabled(String applicationName, Confi
}
}

/**
* Helper method that sets the enabled status for a given application.
* @param applicationName The name of the application to register
* @param config The config to check for override values from
*/
private synchronized void setFaultToleranceMetricsEnabled(String applicationName, Config config) {
// Double lock as multiple methods can get inside the calling if at the same time
logger.log(Level.FINER, "Checking double lock to see if something else has added the application");
if (!metricsEnabledMap.containsKey(applicationName)) {
if (config != null) {
// Set the enabled value to the override value from the config, or true if it isn't configured
metricsEnabledMap.put(applicationName,
config.getOptionalValue(METRICS_ENABLED_PROPERTY, Boolean.class).orElse(Boolean.TRUE));
} else {
logger.log(Level.FINE, "No config found, so enabling fault tolerance metrics for application: {0}",
applicationName);
metricsEnabledMap.put(applicationName, Boolean.TRUE);
}
}
}

/**
* Gets the configured ManagedExecutorService.
* @return The configured ManagedExecutorService, or the default ManagedExecutorService if the configured one
Expand Down Expand Up @@ -452,6 +492,7 @@ private synchronized CircuitBreakerState registerCircuitBreaker(String applicati
*/
private void deregisterApplication(String applicationName) {
enabledMap.remove(applicationName);
metricsEnabledMap.remove(applicationName);
deregisterCircuitBreaker(applicationName);
deregisterBulkhead(applicationName);
}
Expand Down Expand Up @@ -488,6 +529,20 @@ public String getApplicationName(InvocationManager invocationManager, Invocation
if (appName == null) {
appName = invocationManager.getCurrentInvocation().getComponentId();

// If we've found a component name, check if there's an application registered with the same name
if (appName != null) {
ApplicationRegistry applicationRegistry = habitat.getService(ApplicationRegistry.class);

// If it's not directly in the registry, it's possible due to how the componentId is constructed
if (applicationRegistry.get(appName) == null) {
String[] componentIds = appName.split("_/");

// The application name should be the first component
appName = componentIds[0];
}
}

// If we still don't have a name - just construct it from the method signature
if (appName == null) {
appName = getFullMethodSignature(invocationContext.getMethod());
}
Expand Down Expand Up @@ -532,4 +587,25 @@ private void addGenericFaultToleranceRequestTracingDetails(RequestTraceSpan span
span.addSpanTag("Class Name", invocationContext.getMethod().getDeclaringClass().getName());
span.addSpanTag("Method Name", invocationContext.getMethod().getName());
}

public void incrementCounterMetric(MetricRegistry metricRegistry, String metricName, String applicationName,
Config config) {
if (isFaultToleranceMetricsEnabled(applicationName, config)) {
metricRegistry.counter(metricName).inc();
}
}

public void updateHistogramMetric(MetricRegistry metricRegistry, String metricName, int value,
String applicationName, Config config) {
if (isFaultToleranceMetricsEnabled(applicationName, config)) {
metricRegistry.histogram(metricName).update(value);
}
}

public void updateHistogramMetric(MetricRegistry metricRegistry, String metricName, long value,
String applicationName, Config config) {
if (isFaultToleranceMetricsEnabled(applicationName, config)) {
metricRegistry.histogram(metricName).update(value);
}
}
}
Loading