SAP / cloud-sdk

The SAP Cloud SDK documentation and support repository.
https://sap.github.io/cloud-sdk/
Apache License 2.0
45 stars 42 forks source link

SAP OData client - Access MessageProcessingLogs in BTP Integration Suite- How to get (link to) attachment #1766

Closed JHopmann closed 7 months ago

JHopmann commented 7 months ago

Dear Community, dear SUpport.

I have generated an OData V2 client with the maven-approach, in Eclipse.

Connecting the API in Integration Suite is running so far, the objects are available as one can see the details from the "Monitor Message Processing".

Here is a code-snippet:

var destination = DefaultHttpDestination.builder("https://<somename>****.it-cpi024.cfapps.eu10-002.hana.ondemand.com")
        .authenticationType(AuthenticationType.BASIC_AUTHENTICATION)
        .basicCredentials(new BasicCredentials("joerg.hopmann@<mycustomer_in_fra.com", "****"))
        .build();

// perform actual test
final MessageProcessingLogsService service = new DefaultMessageProcessingLogsService().withServicePath("/api/v1/");

//first get the total number
long l = service.getAllMessageProcessingLogs()
        .count()
        .executeRequest(destination);

final List<MessageProcessingLog> mpl = service.getAllMessageProcessingLogs()
        .executeRequest(destination);

String loggerString = null;
for (MessageProcessingLog mpl_iter : mpl)   {
    loggerString = mpl_iter.getIntegrationFlowName() + " : ";
    List<MessageProcessingLogAttachment> mplAttachments = mpl_iter.fetchAttachments();
    if (mplAttachments.size() > 0)  {
        loggerString += " Attachment : Type : ";
        loggerString += mplAttachments.get(0).getContentType() + " Content : ";
        for (MessageProcessingLogAttachment mpla : mplAttachments)  {
            loggerString += mpla.toString() + ".";
        }
        logger.info(loggerString);
    }
}

One example output from ...Attachment.tostring() is as following:

2024-04-01T06:24:30.471+02:00  INFO 10396 --- [           main] c.s.c.s.d.c.HelloWorldController         : CDCContactConsent :  
Attachment : Type : text/plain 
Content : MessageProcessingLogAttachment(super=VdmObject(customFields={}, changedOriginalFields={}), id=636f(...)326638, messageGuid=AGX4Hj1qvhfsv3oEWm_lMo5d9UBy, timeStamp=2024-03-18T10:58:06, name=Message, contentType=text/plain, payloadSize=339).

I was expecting / hoping to see "the attachment" here, but - similar to the Monitoring - there are only properties of the log-entries, NOT the content.

Accessing an attachment via Postman is possible with the following URL:

https://.cfapps.eu10-002.hana.ondemand.com/api/v1/MessageProcessingLogs(%27AGX4Hj1qvhfsv3oEWm_lMo5d9UBy%27)/Attachments

By calling service.MessageProcessingLogAttachmentByKey I get a 404 from BTP. Anyway, I assume the resulting object would not contain the content (but only the properties).

The way the GUID is given in the URL in the mid of the URL "/MessageProcessingLogs"GUID"/Attachments" is - let's say - a little bit uncommon. and especially the payload is given as an octet-stream. How can I handle this? This seems not the way I want...

So I was searching for a way to get this in the OData-client. So far I found some classes which may (or may not) help my, e.g.:

package com.sap.cloud.sdk.datamodel.namespaces.messageprocessinglogs.link;

import javax.annotation.Nonnull;
import com.sap.cloud.sdk.datamodel.namespaces.messageprocessinglogs.MessageProcessingLogAttachment;
import com.sap.cloud.sdk.datamodel.namespaces.messageprocessinglogs.selectable.MessageProcessingLogAttachmentSelectable;
import com.sap.cloud.sdk.datamodel.odata.helper.EntityLink;
import com.sap.cloud.sdk.datamodel.odata.helper.VdmObject;

/**
 * Template class to represent entity navigation links of {@link com.sap.cloud.sdk.datamodel.namespaces.messageprocessinglogs.MessageProcessingLogAttachment MessageProcessingLogAttachment} to other entities. Instances of this object are used in query modifier methods of the entity
 * fluent helpers. Contains methods to compare a field's value with a provided value.
 * 
 * Use the constants declared in each entity inner class. Instantiating directly requires knowing the underlying OData
 * field names, so use the constructor with caution.
 * 
 * @param <ObjectT>
 * Entity type of subclasses from {@link com.sap.cloud.sdk.datamodel.odata.helper.VdmObject VdmObject}.
 * 
 */
public class MessageProcessingLogAttachmentLink<ObjectT extends VdmObject<?> >
    extends EntityLink<MessageProcessingLogAttachmentLink<ObjectT> , MessageProcessingLogAttachment, ObjectT>
    implements MessageProcessingLogAttachmentSelectable
{

This matches with the Monitoring frontend in BTP, there is also a link to download the attachment (as text/plain).

My question(s):

Is it possible to download the attachment and if so, is this the way to go? How do I use this class? Is there an example somewhere? Documentation? Knowledge? Any help appreciated and thanks in advance. Kindest regards Jörg Hopmann

MatKuhr commented 7 months ago

Hi Jörg,

I'm not familiar with the specific OData service you are trying to use. In case the service metadata available on api.sap.com, could you please share the link? If not, can you otherwise somehow share the metadata? Without the metadata and without knowing more about the service it's hard to know how the service is intended to be used...

The way the GUID is given in the URL in the mid of the URL "/MessageProcessingLogs"GUID"/Attachments" is - let's say - a little bit uncommon

You can check this article on how accessing entities in OData works and how it is (slightly) different from the standard REST /resource/{id}/nestedResource format.

In particular, consider reading about the meaning of $expand and how you can use it with the SAP Cloud SDK. Depending on how the OData service is defined, selecting the relevant fields may solve your requirements.

MatKuhr commented 7 months ago

@JHopmann I deleted your comments because they contained some personal/private information/messages. Please remember that when responding here or via email you are posting to a public GitHub issue 😉

I'm glad that you eventually were able to find the correct fields and API endpoints.

In general, the OData generator provided by the Cloud SDK is meant to make using OData APIs easier. With the generated code you can explore the API in your IDE (like in this gif) and don't have to read through the EDMX XML files. Still, you have to know the semantics and structure of the specific API and thus have to consult the relevant documentation for the specific service you want to use.

In case you have any other questions on how to use the Cloud SDK feel free to open another issue.