Get Application ID or Managed Object ID of Cumulocity Microservice

What product/components do you use and which version/fix level are you on?

Cumulocity IoT; I guess the exact version is irrelevant here.

What are you trying to achieve? Please describe it in detail.

I’m implementing a Cumulocity microservice in Java. Is it possible to access the associated Application ID of a microservice (the ID <app_id> used in <URL>/application/applications/<app_id>) from within the microservice? Or is it possible to access the Managed Objects associated with the deployed microservice (stored in the inventory at <URL>/inventory/managedObjects/; esp. the Managed Object of type c8y_Application_<app_id> would be desired, but type c8y_microservice_manifest_<app_id> could be okay as well)? I’m trying to use the identity of the microservice itself for setting this as source of events etc. Currently, I’m hardcoding IDs, but I hope that a microservice can somehow retrieve it’s own ID programmatically.

Hi Christian,

a microservice can call this endpoint:
https://cumulocity.com/api/10.14.0/#tag/Current-application

to receive information about itself. Is the contained information sufficient for your purposes?

Harald

Dear Harald, that’s a perfect fit to what I sought. Thank you! Best regards, Christian

For those who want to address the “current application” REST endpoint via Java (like me), here is a lean implementation utilizing the Cumulocity Java SDK:

import org.springframework.beans.factory.annotation.Autowired;

import com.cumulocity.microservice.context.ContextService;
import com.cumulocity.microservice.context.credentials.MicroserviceCredentials;
import com.cumulocity.microservice.subscription.model.core.PlatformProperties;
import com.cumulocity.microservice.subscription.repository.application.ApplicationApi;
import com.cumulocity.rest.representation.application.ApplicationRepresentation;

@Autowired
private ContextService<MicroserviceCredentials> contextService;
@Autowired
private PlatformProperties platformProperties;
@Autowired
private ApplicationApi appApi;

public ApplicationRepresentation getCurrentApplication() {
	return contextService.callWithinContext((MicroserviceCredentials)platformProperties.getMicroserviceBoostrapUser(), () -> {
		return appApi.currentApplication().get();
	});
}

The ApplicationAPI class wraps the relevant REST interface. The other pieces of the code are used for accessing the endpoint with the right permissions.

2 Likes

Here are some code snippets for accessing the Managed Object associated with an application (the Managed Object with type c8y_Application_<app_id>) on top of the ApplicationRepresentation object as described in the previous post. But first two notes:

  1. A microservice only has such a Managed Object if it is deployed on Cumulocity. The object does not exist if the microservice is executed locally (test execution). You need to create a suitable dummy Managed Object in this case for using the code below. However, such dummy objects will be removed automatically from time to time (presumably, Cumulocity considers these objects to be inconsistent with the deployment status of the microservice).
  2. Be aware that the Managed Object is associated with a specific Cumulocity tenant. This is especially important for microservices running as multi-tenant service. Because of this, the Managed Object must be accessed only in tenant scope.

If you want to access the Managed Object just within a single procedure, you can do it for example as follows:

import java.util.Iterator;

import org.springframework.beans.factory.annotation.Autowired;

import com.cumulocity.microservice.subscription.service.MicroserviceSubscriptionsService;
import com.cumulocity.rest.representation.inventory.ManagedObjectRepresentation;
import com.cumulocity.sdk.client.Platform;
import com.cumulocity.sdk.client.inventory.InventoryFilter;

@Autowired
private Platform platform;
@Autowired
private MicroserviceSubscriptionsService msSubscriptions;

public void doWhatever() {
	msSubscriptions.subscribe();
	msSubscriptions.runForEachTenant(() -> {
		ManagedObjectRepresentation appMO = getAppMO(getCurrentApplication().getId());
		System.out.println(appMO);
		// do whatever with the appMO, e.g. use it as source for an event or alarm
	});
}

public ManagedObjectRepresentation getAppMO(String appId) {
	InventoryFilter filter = new InventoryFilter();
	filter.byType("c8y_Application_" + appId);
	Iterator<ManagedObjectRepresentation> i = platform.getInventoryApi().getManagedObjectsByFilter(filter).get().iterator();
	ManagedObjectRepresentation mo = i.hasNext() ? i.next() : null;
	if (i.hasNext())
		log.warn("Multiple Managed Objects for Application " + appId + " exist in the Inventory. Using the first one returned.");
	return mo;
}

If you want to access the Managed Object from multiple procedures, a Bean with tenant scope might be handy:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;

import com.cumulocity.microservice.context.inject.TenantScope;
import com.cumulocity.rest.representation.inventory.ManagedObjectRepresentation;

@Autowired
@Qualifier("currentAppMO")
private ManagedObjectRepresentation appMO;

@Bean
@TenantScope
public ManagedObjectRepresentation currentAppMO() {
	return getAppMO(getCurrentApplication().getId());
}
1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.