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 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.

1 Like

Here are some code snippets for accessing the Managed Object associated with an application (the Managed Object with type c8y_Application_<app_id>). 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.
  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 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.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());
}