Microservice SDK (java) best way to call unsupperted but available REST endpoints

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

Java Microservice SDK 1016.0.117

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

I want to use functionality to upload and download binaries to events with my Microservice, see Cumulocity IoT - OpenAPI Specification

I suppose i have to inject com.cumulocity.sdk.client.RestConnector; and call methods:

//upload
restConnector.postFile(url, null, attachment, EventRepresentation.class);

//download
restConnector.get(url, MediaType.APPLICATION_OCTET_STREAM_TYPE);

My Questions:

  1. Where is the best way to get the different parts of the url?
??platformUrl??+"/event/events/{{eventId}}/binaries";

If this method would be public: cumulocity-clients-java/EventApiImpl.java at 3b199d143918dea1d7c21f24c4031db5b4e0940a · SoftwareAG/cumulocity-clients-java · GitHub
I had no problem to consturct the URL for it. I could directly use EventApiImpl. However it is private, how could i construct that with new version?

  1. What is the second parameter of method postFile i have set to null. It must be from type EventRepresentation, i don’t have a request body for uploading the file? I don’t understand how to initialize this parameter.

Can only comment on your first question…

Where is the best way to get the different parts of the url?

The platform URL should be available as environment variable C8Y_BASEURL.

See here: “[…]The Cumulocity IoT exposes the REST endpoint /user/currentUser. The microservice retrieves the Cumulocity IoT address from the C8Y_BASEURL operating system environment variable.”

Be aware that C8Y_BASEURL will not work correctly in a multi-tenant microservice. In that case you can extract the platform url from the response to the /tenant/currentTenant endpoint.

Update: I might be wrong, will test and follow up.

It seems to be the object:
https://cumulocity.com/api/core/10.15.0/#operation/postEventBinaryResource
and must contain something like this

{ "name": "hello.txt", "type": "text/plain" }

see here: https://github.com/SoftwareAG/cumulocity-clients-java/blob/3b199d143918dea1d7c21f24c4031db5b4e0940a/java-client/src/main/java/com/cumulocity/sdk/client/RestConnector.java#L209
Not sure why this has to be something like a Representation.

1 Like

With new SDK and not allowing directly PlatformImpl and PlatformParameter, as i understand the output we don’t need that anymore:

Output:
Use relative URL’s starting with ‘/’ with RestConnector bean to have them resolved automatically against the host defined in PlatformParameters#getHost().

Which sounds good! I don’t need to care about the absolute url anymore.

Just to add a little note here: I played around with the RestConnector and even if you provide a full URL (incl the host like “https://something.com/…”) it will always connect to the host defined in PlatformParameters#getHost(): cumulocity-clients-java/CumulocityHttpClient.java at f188384ef58ba2a743226e1d338862fb9981b49a · SoftwareAG/cumulocity-clients-java · GitHub

The reason I looked into this is: I want to change the behavior of the RestConnector for some calls when running in my local development environment (Eclipse). Those calls that target a REST endpoint within my own microservice should execute against http://localhost:80/… so I can debug them accordingly. Anybody ever achieved this?

I have implemented it using restTemplates:

Created two pojos EventBinary and BinaryInfo:

@Data
public class BinaryInfo {
	/**
	 * Name of the binary object.
	 */
	private String name;

	/**
	 * Media type of the file.
	 */
	private String type;
}

@Data
public class EventBinary {
	/**
	 * Name of the attachment. If it is not provided in the request, it will be set as the event ID.
	 */
	private String name;

	/**
	 * A URL linking to this resource.
	 */
	private String self;

	/**
	 * Unique identifier of the event.
	 */
	private String source;

	/**
	 * Media type of the attachment.
	 */
	private String type;
}

And Api:

@Slf4j
@Service
public class EventAttachmentApi {
		
	private ContextService<MicroserviceCredentials> contextService;
	
	private EventApi eventApi;
	
	@Autowired
	public EventAttachmentApi(ContextService<MicroserviceCredentials> contextService, EventApi eventApi) {
		super();
		this.contextService = contextService;
		this.eventApi = eventApi;
	}
	

	public EventBinary uploadEventAttachment(final BinaryInfo binaryInfo, Resource resource, final String eventId) {
		EventRepresentation event = eventApi.getEvent(GId.asGId(eventId));
		if(event == null) {
			return null;
		}
		
		HttpHeaders headers = new HttpHeaders();
		headers.set("Authorization", contextService.getContext().toCumulocityCredentials().getAuthenticationString());
		headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
		headers.setContentType(MediaType.MULTIPART_FORM_DATA);
		
		MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
		multipartBodyBuilder.part("object", binaryInfo, MediaType.APPLICATION_JSON);
		multipartBodyBuilder.part("file", resource, MediaType.TEXT_PLAIN);
		
		MultiValueMap<String,HttpEntity<?>> body = multipartBodyBuilder.build();
		HttpEntity<MultiValueMap<String, HttpEntity<?>>> requestEntity = new HttpEntity<>(body, headers);

		String serverUrl = event.getSelf() + "/binaries";
		RestTemplate restTemplate = new RestTemplate();
		ResponseEntity<EventBinary> response = restTemplate.postForEntity(serverUrl, requestEntity, EventBinary.class);
		if(response.getStatusCodeValue() >= 300) {
			log.error("Upload event binary failed with http code {}", response.getStatusCode().toString());;
			return null;
		}
		return response.getBody();
	}
	
}

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