Return safe fallback from BrokerView read-only getters instead of throwing when broker not yet started - #2553
Conversation
… of throwing when the broker isn't started yet A slave broker running with startAsync=true can be reached over JMX/Jolokia long before ManagedRegionBroker is set. Read-only attribute getters such as getBrokerId(), getBrokerName(), and the destination/statistics counters called safeGetBroker(), which throws IllegalStateException while the slave waits on the lock. Jolokia reads all MBean attributes in a single batch, so that one exception aborted the whole response, hiding attributes that would have succeeded on their own (e.g. Slave). These getters now return a safe fallback (name from BrokerService, null id, 0 counts, empty lists) instead. Getters that mutate broker state still throw via safeGetBroker(), since they genuinely can't run yet. Fixes apache#2551
|
Instead of the null check here, it might make more sense to check the state of the broker and see if it's the active broker or the standby. If it's the active broker, and the broker object is null, that would mean a real error and the exception should be thrown. |
|
@cshannon on slave the broker bean is null. I can do an indirect accessor but I think null check is good enough for the slave case (the purpose here). |
|
I have a concern that changing the exception handling would be breaking for JMX clients that already handle the exception being thrown. I’ll do a couple of checks I prefer this clean/empty data approach over throwing exceptions, but it may need to wait to go into a major version. |
|
@mattrpav nothing is break, it just bypass the exception when broker is not there, the exceptions are still thrown as before on "active" broker. |
|
@cshannon the exceptions are still thrown when broker is not null (so on an active broker). |
I was thinking you could do something like this: @Override
public long getTotalConsumerCount() {
if (isStandBy()) {
return 0;
}
return safeGetBroker().getDestinationStatistics().getConsumers().getCount();
}
private boolean isStandBy() {
return broker == null && brokerService.isSlave();
}BrokerService should never be null (even if broker is) |
|
@cshannon I'm fine to do that but not sure it changes anything. I've tested the
So within a single It means: is correct but So:
I'm fine to add |
|
@mattrpav that makes totally sense. Maybe we should target just 6.4.0 for this change (not 7)? |
+1 for 6.4.0 I think this change is probably fine for something like 6.4.0. It also depends on if we want to use the empty data approach instead of error if broker is null no matter what (like the existing PR) or limit it to only if in slave mode. (the broker object is not set until start is called so i'm not sure if it's possible for the broker to be null briefly during initialization). I suggested to do that extra check but maybe we just leave things as is, not sure. |
Alright, based on that it's probably no point to add the check. As you stated it doesn't really buy us anything. |
|
So after looking it over and thinking about it, I think the current version is fine for 6.4.0, but not a backport due to the change to empty vs throwing an exception. We can make a note in the release notes because I think this is overall a better way to handle it. |
Summary
IllegalStateExceptionreported in Jolokia/JMX queries fail with IllegalStateException on slave broker when startAsync=true #2551: on a slave broker running withstartAsync=true, querying the Broker MBean over Jolokia failed even though attributes likeSlavewere perfectly readable, because Jolokia reads all attributes in one batch and a single throwing getter aborted the whole response.BrokerView's read-only attribute getters (getBrokerId(),getBrokerName(), destination/subscriber/producer lists, and the destination statistics counters) now return a safe fallback (null/0/empty array, broker name falls back to the configured name onBrokerService) instead of throwing viasafeGetBroker()whenManagedRegionBrokerhasn't been set yet.resetStatistics(),enableStatistics(),disableStatistics(), destination add/remove, durable subscriber create/destroy) are unchanged and still throwIllegalStateExceptionthroughsafeGetBroker(), since they genuinely can't run before the broker is up.Test plan
mvn -pl activemq-broker -am compilesucceedsstartAsync=trueand confirm a Jolokia bulk attribute read on the Broker MBean succeeds (includingSlave=true) while the broker is still waiting on the lockFixes #2551