richard-scott opened a new issue, #217:
URL: https://github.com/apache/bifromq/issues/217
### **Describe the bug**
BifroMQ is not instantiating our `CustomResourceThrottler` plugin, even
though:
- It's correctly configured via `resourceThrottlerFQN` in the configuration
file
- It's registered in `META-INF/extensions.idx`
- The plugin JAR is present in BifroMQ's plugin directory
- The plugin implements both `IResourceThrottler` and `IEventCollector`
interfaces
**Expected behavior**: When `resourceThrottlerFQN` is configured with a
custom plugin class name, BifroMQ should instantiate and use that plugin for
resource throttling operations. The plugin constructor should be called, and
the plugin should receive events via `report()` method and be called for
`hasResource()` checks when connections are attempted.
**Actual behavior**: The plugin constructor is never called (no "Plugin
loaded" message appears in logs), the plugin's `report()` method is never
called (no events are received), and the plugin's `hasResource()` method is
never called (resource checks don't happen). Other plugins (AuthProvider,
EventCollector, SettingProvider, ClientBalancer) load successfully using the
same configuration pattern.
#### **Environment**
- **Version**: `4.0.0-incubating-RC3`
- **JVM Version**: OpenJDK 17.0.17
- **Hardware Spec**: Docker containers (single node cluster)
- **OS**: Linux (containerized deployment)
- **Testing Tools**: Custom Java plugin implementation, MQTT clients
- **Deployment**: Docker Compose cluster (1 BifroMQ node + HAProxy load
balancer)
#### **Reproducible Steps**
**1. Setup Cluster Configuration**
Create a BifroMQ configuration file (`standalone.yml` or cluster config)
with FQN configuration:
```yaml
resourceThrottlerFQN:
"com.bifromq.plugin.resourcethrottler.CustomResourceThrottler"
```
**2. Build Custom ResourceThrottler Plugin**
Create a custom ResourceThrottler plugin implementing `IResourceThrottler`
and `IEventCollector`:
```java
package com.bifromq.plugin.resourcethrottler;
import org.apache.bifromq.plugin.resourcethrottler.IResourceThrottler;
import org.apache.bifromq.plugin.resourcethrottler.TenantResourceType;
import org.apache.bifromq.plugin.eventcollector.IEventCollector;
import org.apache.bifromq.plugin.eventcollector.Event;
import org.pf4j.Extension;
@Extension
public class CustomResourceThrottler implements IResourceThrottler,
IEventCollector {
public CustomResourceThrottler() {
System.err.println("[CustomResourceThrottler] Plugin loaded");
System.out.println("[CustomResourceThrottler] Plugin loaded");
}
@Override
public boolean hasResource(String tenantId, TenantResourceType
resourceType) {
// This method is never called
return true;
}
@Override
public void report(Event event) {
// This method is never called
}
// ... other required methods ...
}
```
**Plugin Registration**: Create `src/main/resources/META-INF/extensions.idx`:
```
com.bifromq.plugin.resourcethrottler.CustomResourceThrottler
```
**3. Deploy Plugin**
- Build plugin JAR: `mvn clean package`
- Deploy plugin JAR to BifroMQ's plugin directory
- Verify JAR exists in plugin directory
- Verify configuration contains `resourceThrottlerFQN` setting
Should show:
```yaml
resourceThrottlerFQN:
"com.bifromq.plugin.resourcethrottler.CustomResourceThrottler"
```
**4. Start BifroMQ Cluster**
Start the BifroMQ cluster with the custom plugin deployed.
**5. Verify Plugin Loading**
Check BifroMQ startup logs for plugin constructor output.
**Expected Result**: Log entries showing "Plugin loaded" message from
CustomResourceThrottler constructor.
**Actual Result**: No log entries - plugin constructor never called.
**6. Verify Plugin Methods Are Called**
Attempt MQTT connection and check BifroMQ logs for `hasResource()` method
calls.
**Expected**: Log entries showing `hasResource()` method calls.
**Actual**: No output - plugin methods never called.
**7. Verify Event Reception**
Check BifroMQ logs for `report()` method calls when events occur.
**Expected**: Log entries showing event reception.
**Actual**: No output - `report()` never called.
#### **Additional Evidence**
**Plugin JAR Present**: Verified that plugin JAR exists in BifroMQ's
plugin/lib directory.
**Plugin Not in Load Log**: Checked plugin load logs - no entries for
CustomResourceThrottler, confirming plugin constructor never called.
**Other Plugins Load Successfully**: Other plugins (CustomSettingProvider,
CustomEventCollector, CustomAuthProvider, CustomClientBalancer) all load
successfully using the same configuration pattern.
**extensions.idx Verified in JAR**: Verified that `META-INF/extensions.idx`
file exists in the plugin JAR and contains the correct class name.
**Comparison with Working Plugins**:
- **AuthProvider** (Works): Configured via `authProviderFQN`, registered in
`META-INF/extensions.idx` → ✅ Loads successfully
- **EventCollector** (Works): Auto-discovered via PF4J, registered in
`META-INF/extensions.idx` → ✅ Loads successfully
- **SettingProvider** (Works): Configured via `settingProviderFQN`,
registered in `META-INF/extensions.idx` → ✅ Loads successfully
- **ResourceThrottler** (Doesn't Work): Configured via
`resourceThrottlerFQN`, registered in `META-INF/extensions.idx` → ❌ Never loads
**What We've Verified**:
1. ✅ Configuration file has `resourceThrottlerFQN` set correctly
2. ✅ Configuration file contains the FQN after rendering/processing
3. ✅ Plugin JAR is present in BifroMQ's plugin directory
4. ✅ `extensions.idx` file exists in source and is included in JAR
5. ✅ Plugin class implements `IResourceThrottler` interface correctly
6. ✅ Plugin class implements `IEventCollector` interface correctly
7. ✅ Plugin class has `@Extension` annotation
8. ✅ Plugin constructor logs to both `System.err` and `System.out`
9. ✅ No class loading errors in logs
10. ✅ No exceptions during plugin discovery
11. ✅ Plugin JAR contains `META-INF/extensions.idx` with correct class name
#### **Questions**
1. **Does BifroMQ support ResourceThrottler plugins in version
4.0.0-incubating-RC3?**
- Documentation mentions "(if supported by BifroMQ version)" - is this
version supported?
2. **Is there a different loading mechanism for ResourceThrottler plugins?**
- Other singleton plugins (SettingProvider, AuthProvider) load
successfully via FQN
- Is ResourceThrottler handled differently?
3. **Does implementing both `IResourceThrottler` and `IEventCollector` cause
issues?**
- The plugin needs to track connections via events, so it implements both
interfaces
- Could this cause a conflict in plugin loading?
4. **Is there a feature flag or additional configuration required?**
- Do we need to enable ResourceThrottler functionality somewhere else?
5. **Is ResourceThrottler loaded lazily?**
- Maybe it's only loaded when `hasResource()` is first called?
- But we're not seeing any `hasResource()` calls either
#### **Additional Context**
We're trying to implement connection limiting per tenant. The plugin needs
to:
1. Track active connections via `ClientConnected`/`ByClient` events
(implements `IEventCollector`)
2. Enforce connection limits via `hasResource(TotalConnections)` (implements
`IResourceThrottler`)
Since the plugin doesn't load, we cannot implement this functionality.
**Impact**:
- Connection limiting cannot be enforced - `hasResource(TotalConnections)`
is never called
- Resource throttling is disabled - no rate limits, bandwidth limits, or
connection limits work
- Plugin architecture appears broken - plugin is configured but never loaded
**Request**: Please investigate why ResourceThrottler plugins are not being
loaded despite correct configuration. We need to understand if this is a bug,
missing configuration, version incompatibility, or if there's a workaround.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]