This is an automated email from the ASF dual-hosted git repository.
heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git
The following commit(s) were added to refs/heads/master by this push:
new 3b60d40f6b better handling of some errors
3b60d40f6b is described below
commit 3b60d40f6b43b0fc04717b8511bb08f682a51224
Author: Alex Heneveld <[email protected]>
AuthorDate: Thu Jul 27 12:08:14 2023 +0100
better handling of some errors
---
.../brooklyn/core/mgmt/rebind/RebindIteration.java | 5 +++-
.../proxy/AbstractBrooklynObjectProxyImpl.java | 3 ++-
.../core/workflow/WorkflowErrorHandling.java | 4 +++-
.../core/json/ConfigurableSerializerProvider.java | 13 +++++++++-
.../workflow/WorkflowPersistReplayErrorsTest.java | 2 +-
.../brooklyn/rest/resources/SensorResource.java | 28 ++++++++++++++--------
6 files changed, 40 insertions(+), 15 deletions(-)
diff --git
a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
index a7675af57d..a7c06cd2e4 100644
---
a/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
+++
b/core/src/main/java/org/apache/brooklyn/core/mgmt/rebind/RebindIteration.java
@@ -31,6 +31,7 @@ import java.io.InputStream;
import java.util.concurrent.Semaphore;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
import com.google.common.annotations.Beta;
import org.apache.brooklyn.api.catalog.BrooklynCatalog;
@@ -591,6 +592,7 @@ public abstract class RebindIteration {
adjunctProxies.entrySet().forEach(entry -> {
if (entry.getValue() instanceof Policy)
exceptionHandler.onDanglingPolicyRef(entry.getKey());
else if (entry.getValue() instanceof Enricher)
exceptionHandler.onDanglingEnricherRef(entry.getKey());
+ else if (entry.getValue() instanceof Feed)
exceptionHandler.onDanglingFeedRef(entry.getKey());
else {
LOG.warn("Adjunct proxy for "+entry.getKey()+" is of
unexpected type; "+entry.getValue()+"; reporting as dangling of unknown type");
exceptionHandler.onDanglingUntypedItemRef(entry.getKey());
@@ -1451,7 +1453,8 @@ public abstract class RebindIteration {
}
}
throw new IllegalStateException("Cannot instantiate instance of
type " + clazz +
- "; expected constructor signature not found (" + args +
")");
+ "; expected constructor signature not found (" + args + "
/ " +
+ Arrays.asList(args).stream().map(a ->
a.getClass()).collect(Collectors.toList()) + ")");
}
protected ManagedBundle newManagedBundle(ManagedBundleMemento
bundleMemento) {
diff --git
a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/AbstractBrooklynObjectProxyImpl.java
b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/AbstractBrooklynObjectProxyImpl.java
index 77af212352..d0779be29d 100644
---
a/core/src/main/java/org/apache/brooklyn/core/objs/proxy/AbstractBrooklynObjectProxyImpl.java
+++
b/core/src/main/java/org/apache/brooklyn/core/objs/proxy/AbstractBrooklynObjectProxyImpl.java
@@ -153,7 +153,8 @@ public abstract class AbstractBrooklynObjectProxyImpl<T
extends BrooklynObject>
if ("getId".equals(sig.name)) return getId();
if ("hashCode".equals(sig.name)) return hashCode();
if ("equals".equals(sig.name) && args.length==1) return
equals(args[0]);
- throw new NullPointerException("Access to proxy before
initialized, method "+m);
+ throw new NullPointerException("Access to proxy on "+toString()+"
before initialized, method "+m+"; " +
+ "likely the target either is still being initialized or
the target had an error when being created/rebinded");
} else if (OBJECT_METHODS.contains(sig)) {
result = m.invoke(delegate, args);
} else if (isPermittedReadOnlyMethod(sig)) {
diff --git
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowErrorHandling.java
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowErrorHandling.java
index 2961e2353e..e12bc0062f 100644
---
a/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowErrorHandling.java
+++
b/core/src/main/java/org/apache/brooklyn/core/workflow/WorkflowErrorHandling.java
@@ -256,7 +256,9 @@ public class WorkflowErrorHandling implements
Callable<WorkflowErrorHandling.Wor
// don't consider replaying automatically here; only done at workflow
level
- logWarnOnExceptionOrDebugIfKnown(entity, error, "Error in step '" +
stepTaskThrowingError.getDisplayName() + "'; " + problemHere + "rethrowing: " +
Exceptions.collapseText(error));
+ logWarnOnExceptionOrDebugIfKnown(entity, error,
+ currentStepInstance.getWorkflowExectionContext().getName() +
": " +
+ "Error in step '" + stepTaskThrowingError.getDisplayName() +
"'; " + problemHere + "rethrowing: " + Exceptions.collapseText(error));
throw Exceptions.propagate(error);
}
diff --git
a/core/src/main/java/org/apache/brooklyn/util/core/json/ConfigurableSerializerProvider.java
b/core/src/main/java/org/apache/brooklyn/util/core/json/ConfigurableSerializerProvider.java
index 055f289e43..f2b45831c3 100644
---
a/core/src/main/java/org/apache/brooklyn/util/core/json/ConfigurableSerializerProvider.java
+++
b/core/src/main/java/org/apache/brooklyn/util/core/json/ConfigurableSerializerProvider.java
@@ -29,10 +29,14 @@ import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializationConfig;
import com.fasterxml.jackson.databind.ser.DefaultSerializerProvider;
import com.fasterxml.jackson.databind.ser.SerializerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
/** allows the serializer-of-last-resort to be customized, ie used for
unknown-types */
final class ConfigurableSerializerProvider extends DefaultSerializerProvider {
+ private static final Logger log =
LoggerFactory.getLogger(ConfigurableSerializerProvider.class);
+
private static final long serialVersionUID = 6094990395562170217L;
protected JsonSerializer<Object> unknownTypeSerializer;
@@ -83,7 +87,14 @@ final class ConfigurableSerializerProvider extends
DefaultSerializerProvider {
JsonSerializer<Object> unknownTypeSerializer =
getUnknownTypeSerializer(value.getClass());
if (unknownTypeSerializer instanceof
ErrorAndToStringUnknownTypeSerializer) {
-
((ErrorAndToStringUnknownTypeSerializer)unknownTypeSerializer).serializeFromError(ctxt,
e, value, jgen, this);
+ try {
+ ((ErrorAndToStringUnknownTypeSerializer)
unknownTypeSerializer).serializeFromError(ctxt, e, value, jgen, this);
+ } catch (Exception e2) {
+ Exceptions.propagateIfFatal(e2);
+ log.warn("Unable to nicely recover from original error during
serialization "+e+"; got "+e2+"; rethrowing original");
+ log.trace("Secondary error", e2);
+ throw Exceptions.propagate(e);
+ }
} else {
unknownTypeSerializer.serialize(value, jgen, this);
}
diff --git
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
index 7f3843b79c..e85f5af11c 100644
---
a/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
+++
b/core/src/test/java/org/apache/brooklyn/core/workflow/WorkflowPersistReplayErrorsTest.java
@@ -632,7 +632,7 @@ public class WorkflowPersistReplayErrorsTest extends
RebindTestFixture<BasicAppl
Asserts.assertEntriesSatisfy(msgs, MutableList.of(
m -> m.matches("Starting workflow 'myWorkflow .workflow
effector.', moving to first step .*-1"),
m -> m.matches("Starting step .*-1 in task .*"),
- m -> m.matches("Error in step '1 - invoke-effector
does-not-exist'; rethrowing: No effector matching 'does-not-exist'"),
+ m -> m.matches("myWorkflow .*: Error in step '1 -
invoke-effector does-not-exist'; rethrowing: No effector matching
'does-not-exist'"),
m -> m.matches("Error in workflow 'myWorkflow .workflow
effector.' around step .*-1, running error handler"),
m -> m.matches("Encountered error in workflow .*/.*
'myWorkflow' .handler present.: No effector matching 'does-not-exist'"),
m -> m.matches("Starting .*-error-handler with 1 step in
task .*"),
diff --git
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
index cecde9a850..e79d037301 100644
---
a/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
+++
b/rest/rest-resources/src/main/java/org/apache/brooklyn/rest/resources/SensorResource.java
@@ -36,6 +36,8 @@ import org.apache.brooklyn.rest.filter.HaHotStateRequired;
import org.apache.brooklyn.rest.transform.SensorTransformer;
import org.apache.brooklyn.rest.util.EntityAttributesUtils;
import org.apache.brooklyn.rest.util.WebResourceUtils;
+import org.apache.brooklyn.util.collections.MutableMap;
+import org.apache.brooklyn.util.exceptions.Exceptions;
import org.apache.brooklyn.util.text.Strings;
import org.apache.brooklyn.util.time.Duration;
import org.slf4j.Logger;
@@ -85,17 +87,23 @@ public class SensorResource extends
AbstractBrooklynRestResource implements Sens
Iterable<AttributeSensor> sensors =
filter(entity.getEntityType().getSensors(), AttributeSensor.class);
for (AttributeSensor<?> sensor : sensors) {
- // Exclude sensors that user is not allowed to see
- if (!Entitlements.isEntitled(mgmt().getEntitlementManager(),
Entitlements.SEE_SENSOR, new EntityAndItem<String>(entity, sensor.getName()))) {
- log.trace("User {} not authorized to see sensor {} of entity
{}; excluding from current-state results",
- new Object[]
{Entitlements.getEntitlementContext().user(), sensor.getName(), entity});
- continue;
+ try {
+ // Exclude sensors that user is not allowed to see
+ if (!Entitlements.isEntitled(mgmt().getEntitlementManager(),
Entitlements.SEE_SENSOR, new EntityAndItem<String>(entity, sensor.getName()))) {
+ log.trace("User {} not authorized to see sensor {} of
entity {}; excluding from current-state results",
+ new
Object[]{Entitlements.getEntitlementContext().user(), sensor.getName(),
entity});
+ continue;
+ }
+
+ Object value = EntityAttributesUtils.tryGetAttribute(entity,
findSensor(entity, sensor.getName()));
+ sensorMap.put(sensor.getName(),
+
resolving(value).preferJson(true).asJerseyOutermostReturnValue(false).useDisplayHints(useDisplayHints).raw(raw).context(entity).timeout(Duration.ZERO).renderAs(sensor)
+ .suppressIfSecret(sensor.getName(),
suppressSecrets).filterOutputFields(sensor.getName().startsWith("internal")).resolve());
+ } catch (Exception e) {
+ Exceptions.propagateIfFatal(e);
+ log.error(""+sensor+" on "+entity+" cannot be serialized for
REST output; ignoring: "+e, e);
+ sensorMap.put(sensor.getName(), MutableMap.of("type", "error",
"message", "Value not available. See logs."));
}
-
- Object value = EntityAttributesUtils.tryGetAttribute(entity,
findSensor(entity, sensor.getName()));
- sensorMap.put(sensor.getName(),
-
resolving(value).preferJson(true).asJerseyOutermostReturnValue(false).useDisplayHints(useDisplayHints).raw(raw).context(entity).timeout(Duration.ZERO).renderAs(sensor)
- .suppressIfSecret(sensor.getName(),
suppressSecrets).filterOutputFields(sensor.getName().startsWith("internal")).resolve());
}
return sensorMap;
}