Why are my tenant subscriptions working locally but not in cloud

Product/components used and version/fix level: Cumulocity IoT Hosted, BE v 1017.0.289, JavaSDK v 1017.0.375

Detailed explanation of the problem: We have a Microservice that is on Multitenant context. When using the JavaSDK and run a HTTP GET command, there is a difference:

When run locally: MicroserviceSubscriptionsService.getAll() returns all subtenants

When run in the cloud: MicroserviceSubscriptionsService.getAll() returns an empty list

An example would be that in the following code, when i run locally (e.G. via Debugger) the part subscriptionsService.getAll() is returning the subtenants as needed. After deployment when I run the exact same command, this part returns an empty list.
Also, the scheduled jobs, do not have any issue with using this command. Inside of a scheduled job this part returns the correct list with subtenants, locally and in the cloud.

Error messages / full error message screenshot / log file:

/**
subscriptionsService is typeof MicroserviceSubscriptionsService
ctxService is typeof ContextService<MicroserviceCredentials>
**/
subscriptionsService.subscribe();
var tenants = subscriptionsService.getAll(); //This part is where the difference is
var result = new Result();
tenants.forEach(tenant -> {
    ctxService.callWithinContext(tenant, () -> {
        //Do smth and set result
    });
});

return ResponseEntity.ok(result);

Does anybody know why this issue is happening?
Thanks in advance for the Support.

Could it be that you’re calling it too early in your code? There is a onSubscriptionsInitialized method you coud utilize here:

@EventListener
public void onSubscriptionsInitialized(MicroserviceSubscriptionsInitializedEvent event) {
    log.info("All tenant subscriptions initialized.");
    subscriptionsService.subscribe();
    Collection<MicroserviceCredentials> allActiveSubscriptions = subscriptionsService.getAll();
    log.info(allActiveSubscriptions);
    subscriptionService.runForEachTenant(...);
}

Why not using the subscriptionService.runForTenant or subscriptionService.runForEachTenant or subscriptionService.callForTenant
Within that methods you can also call subscriptionService.getTenant() to retrieve the current Tenant.

They work out of the box and will also waiting until all subscriptions are initialized basically meaning all service users are retrieved.

Btw. you can also use this to get the current tenant scope:

@EventListener
public void initialize(MicroserviceSubscriptionAddedEvent event) {
   String tenant = event.getCredentials().getTenant();
   MicroserviceCredentials credentials = event.getCredentials();
   ....
}

This is called on microservice startup for each subscribed tenant or when a new tenant is subscribed to the microservice

Thank you a lot!

The subscriptionService.runForEachTenant was the solution. I don’t know why there is a difference when trying to fetch all tenants via getAll() but runForEachTenant actually solved this.

1 Like