Hello,
I have recently updated my OpenEMS instance to a recent version from a version that was >1 year old.
Previously when I looked at the EdgeConfig
JSON (either over backend websocket or fetched via REST-API, it contained entries under factories for every factory - i.e
- Factories corresponding to my actual components (the ESS, controllers etc that I was actually using)
AND - Factories corresponding to bundles that I had not instantiated into components (e.g components such as controllers that are available for creation).
Since the version update, I am only receiving the factories in category 1 in the EdgeConfig
JSON.
This is problematic as our custom backend was using the JSON to understand which components were available on the Edge to be created - e.g which controllers, devices etc are available.
The issue appears to be related to the factoryPid
.
EdgeConfigWorker has the following function for getting the factories:
/**
* Read Factories.
*
* @param builder the {@link EdgeConfig} builder
*/
private void readFactories(EdgeConfig.ActualEdgeConfig.Builder builder) {
var bundleContext = this.parent.bundleContext;
if (bundleContext == null) {
// Can be null in JUnit tests
return;
}
final var bundles = bundleContext.getBundles();
for (Bundle bundle : bundles) {
final var mti = this.parent.metaTypeService.getMetaTypeInformation(bundle);
if (mti == null) {
continue;
}
// read Bundle Manifest
var manifestUrl = bundle.getResource("META-INF/MANIFEST.MF");
Manifest manifest;
try {
manifest = new Manifest(manifestUrl.openStream());
} catch (IOException e) {
// unable to read manifest
continue;
}
// get Factory-PIDs in this Bundle
var factoryPids = mti.getFactoryPids();
for (String factoryPid : factoryPids) {
switch (factoryPid) {
case "osgi.executor.provider":
// ignore these Factory-PIDs
break;
default:
// Get ObjectClassDefinition (i.e. the main annotation on the Config class)
var objectClassDefinition = mti.getObjectClassDefinition(factoryPid, null);
// Get Natures implemented by this Factory-PID
var natures = this.getNatures(bundle, manifest, factoryPid);
// Add Factory to config
builder.addFactory(factoryPid,
EdgeConfig.Factory.create(factoryPid, objectClassDefinition, natures));
}
}
// get Singleton PIDs in this Bundle
for (String pid : mti.getPids()) {
switch (pid) {
default:
// Get ObjectClassDefinition (i.e. the main annotation on the Config class)
var objectClassDefinition = mti.getObjectClassDefinition(pid, null);
// Get Natures implemented by this Factory-PID
var natures = this.getNatures(bundle, manifest, pid);
// Add Factory to config
builder.addFactory(pid, EdgeConfig.Factory.create(pid, objectClassDefinition, natures));
}
}
}
}
When I look in the Felix console under hostname:8080/system/console/bundles
- I only see a factoryPid for the bundles that have actually been instantiated into components - i.e there is no factoryPid for the other devices and controllers.
Therefore these would be missed by the EdgeConfigWorker.
Strangely I can see a factoryPid for each of these when I look on the OSGi configuration page hostname:8080/system/console/configMgr
.
Very confused by this issue! All help appreciated!
Thanks
Thomas