Intercettare il token di accesso ad un servizio

Può capitare nello sviluppo di un iFlow, di dover utilizzare servizi REST dei quali non si dispone direttamente del token che invece viene reso disponibile tramite un altro servizio.

Questo rappresenta un problema laddove si volesse provare il servizio da tool esterni a CPI, leggi Postman o affini.

Per bypassare il problema è possibile catturare il token generato mediante un semplice script Groovy, da inserire provvisoriamente nell’artifact, ed utilizzarlo nell’ambito del suo periodo di validità.

import com.sap.gateway.ip.core.customdev.util.Message;

import java.util.HashMap;

def Message processData(Message message) {

def messageLog = messageLogFactory.getMessageLog(message);

def map = message.getHeaders()

    String token = map.get("Authorization")

if(messageLog != null){

messageLog.setStringProperty("Logging#1", "SP_Token")

messageLog.addAttachmentAsString("Authorization: ", token, "text/plain");

}

return message;

}

Lo scenario descritto prevede in 1 il servizio che rilascia il token e in 2 il servizio che lo utilizza.

Impostando prima di quest’ultimo il groovy Trace SP Auth, questo lo intercetta e lo scrive in un attachment.

Analizzando il servizio 2 è possibile vederlo in Trace


IDocConversionException

Scenario

Qualcosa-IDoc_AAE

Contesto

Si sta inviando un IDoc custom ad un canale receiver di tipo IDoc_AAE.

Effetto

L’invio del messaggio fallisce nel channel monitor con il seguente errore:

Error before sending due to IDoc parsing error: (7) IDOC_ERROR_PARSE_FAILURE: An IDocConversionException occurred while parsing IDocXML for type <IDoc_type>: state=READING_FIELD_VALUE_TAG, charPosition=…, lineNumber=…, columnNumber=…

Soluzione

Applicare la nota 2036878 – IDoc_AAE: Disable field datatype validation during IDoc-XML parsing che suggerisce di inserire il parametro FieldValidationEnabled fra gli Additional Parameters del canale e attribuirgli il valore false.

Il parametro disabilita il controllo del DataType dell’idoc, generato in maniera non conforme dall’adapter Idoc-AAE.


Errore “element IDOC has no non-whitespace child elements”

Scenario

Qualcosa-IDoc

Contesto

In un mapping già configurato in repository e directory, si cambia la cardinalità del messaggio da 1:1 a 1:n.

Effetto

L’esecuzione del messaggio fallisce nel channel monitor con l’errore

Adding control record to payload failed due to IDoc structure of incoming message is not correct – element IDOC has no non-whitespace child elements

Soluzione

Oltre a cambiare la cardinalità del message mapping e nell’operation mapping occorre reimportare l’operation mapping nella Interface Determination dello scenario.


Manutenzione tabella

Obiettivo

Modificare i dati direttamente in tabella di dictionary.

Modalità

TCODE se16n

Impostare tabella e filtri

TCODE &sap_edit

TCODE /h

F8

Modificare le seguenti variabili attribuendo il valore X:

GD-SAPEDIT = X

GD-EDIT = X

F8

Modificare i dati e salvare.


Ottenere indirizzo email default del cliente

Obiettivo

Ricavare l’indirizzo email di default, SMTP_ADDR, del cliente, KUNNR.

Modalità

*&---------------------------------------------------------------------*
*&      Form  get_email_address
*&---------------------------------------------------------------------*
*       text Returns in SMTP_ADDR the customer, KUNNR, default email address.
*       (by N4N)
*----------------------------------------------------------------------*
*      -->KUNNR      text
*      -->SMTP_ADDR  text
*----------------------------------------------------------------------*
FORM get_email_address USING kunnr smtp_addr.

  DATA: t_adrnr TYPE adrnr,
        t_smtp_addr TYPE ad_smtpadr.

  SELECT SINGLE adrnr FROM kna1 INTO t_adrnr
                         WHERE kunnr = kunnr.

  IF sy-subrc EQ 0.
    SELECT SINGLE smtp_addr FROM adr6 INTO t_smtp_addr
      WHERE addrnumber = t_adrnr and flgdefault = 'X'.
    IF sy-subrc EQ 0.
      smtp_addr =  t_smtp_addr.
    ENDIF.
  ENDIF.

*  IF sy-subrc EQ 0.
*    SELECT SINGLE flagcomm6 FROM adrc INTO t_flagcomm6
*      WHERE addrnumber = t_adrnr.
*    IF sy-subrc EQ 0 AND t_flagcomm6 IS NOT INITIAL.
*      SELECT SINGLE prsnr FROM knvk INTO t_pernr
*        WHERE kunnr = kunnr.
*      IF sy-subrc EQ 0 AND t_pernr IS NOT INITIAL.
*        SELECT SINGLE smtp_addr FROM adr6 INTO t_smtp_addr
*          WHERE persnumber = t_pernr.
*        IF sy-subrc EQ 0.
*          smtp_addr =  t_smtp_addr.
*        ENDIF.
*      ENDIF.
*    ENDIF.
*  ENDIF.

ENDFORM.                    "get_email_address

 


Invocare un URL

Obiettivo

Invocare un URL da codice ABAP.

Modalità

FUNCTION zn4n_call_url.
 *"---------------------------------------------------------------------- 
 *"*"Interfaccia locale: 
 *" IMPORTING 
 *" REFERENCE(URL) TYPE CHAR255 
 *"---------------------------------------------------------------------- 
 CALL FUNCTION 'WS_EXECUTE' 
 EXPORTING 
 program = '%programfiles%\Internet Explorer\IEXPLORE.EXE' 
 commandline = url 
 inform = '' 
 EXCEPTIONS 
 prog_not_found = 1. 
ENDFUNCTION.

Invocando IEXPLORE.EXE, la function funziona solo su client Windows based.


Invio email con file di testo allegato

Scenario

File-to-Mail

Requisito

Allegare file di testo a una mail.

Enterprise Service Builder

Il seguente mapping converte il contesto in un’unica stringa in cui ogni elemento di context diventa una riga.

La stringa viene mossa in Content.

L’UDF concatRows converte l’array in una stringa in cui gli elementi dell’array sono separati tramite new line.

public void concatRows(String[] rows, ResultList result, Container container) throws StreamTransformationException{
	String t = "";

	for (int i = 0; i < rows.length; i++) {
		if (i > 0) {
			t += System.getProperty("line.separator") + rows[i];
		} else {
			t += rows[i];
		}
	}
	result.addValue(t);
}

Integration Builder

Il canale sender file

Nel caso in cui l’Adapter sender non preveda il tab Content Convertion (per esempio l’SFTP) si può adottare il modulo AF_Modules/MessageTransformBean

In questo caso, il file letto

Num. Mensaje;Fecha;Error
W0051326G J20150721;20150721;Muy Sres. nuestros:
W0051326G J20150721;20150721;Nos referimos a su/s factura/s abajo relacionada/s.
W0051326G J20150721;20150721;Al objeto de verificar su conformidad, y como quiera que no

assume il seguente payload

Il canale receiver mail

I parametri della mail devono essere assunti dal mapping e quini impostare Using Mail Package.

Prerequisito perché il file in attach abbia il nome del file di turno

La Receiver Interface

Il test

Limitazioni

Se il canale sender è configurato per leggere più file, questi verranno inviati come attach in mail separate.

La presente soluzione gestisce solo file di testo e non anche file binary.

 


Communication Channel File: Determinare filename receiver da mapping

Scenario

File receiver.

Requisito

Il nome del file dev’essere generato dinamicamente secondo un algoritmo definito nel

Mapping

Il mapping su rset scrive nella Dynamic Configuration il filename ricevuto dal cc sender.

Implementando anche i legami su row  e su FIELD si replica il file da sender a receiver (opzionale).

In particolare,

In blu: lettura da Dynamic Configuration del channel sender

In rosso: regola arbitraria per determinare il nome file receiver

In verde: scrittura su Dynamic Configuration del nome file receiver

Communication channel sender

Content Conversion opzionale

Communication channel receiver

Content Conversion opzionale

Monitor: Dynamic Configuration

Dynamic Configuration dal communication channel receiver


splitForLength(): UDF per splitting dei testi

Scenario

Mapping grafico.

Requisito

In un contesto di generazione IDoc verso ECC, occorre generare i segmenti di testo E1EDT01/E1EDT02 e/o E1EDP01/E1EDP02 partendo da una stringa in ingresso.


l’UDF splitForLength() è utile nella generazione dei segmenti di testo negli idoc sia nella sezione testata E1EDKT1/E1EDKT2 che in quella di posizione E1EDPT1/E1EDPT2

In particolare, l’UDF consente di generare tanti contesti E1ED*T2 quante sono le sottostringhe di src che si ottengono dividendola per la lunghezza ln.

public void splitForLength(String[] mst, String[] src, String[] ln, ResultList result, Container container) throws StreamTransformationException{
/*
@Author: Nicola Martella | www.nick4name.eu
Genera un context (ResultList) sulla base dello splitting della stringa src in tante sottostringhe quante ne occorrono dividendola per la 
lunghezza indicata in ln.
La funzione gestisce i contesti multipli su mst e src.
*/
 
	 AbstractTrace _trc =  container.getTrace();
	 // _trc.addWarning(source.substring(s, s + len)); //*******************
	 
	int len = Integer.parseInt(ln[0]);
	result.clear();
 
	int isrc = -1;
	for (int imst=0; imst < mst.length; imst++){
		if (mst[imst].equals(ResultList.SUPPRESS)){
			result.addSuppress();
		} else if (mst[imst].equals(ResultList.CC)) {
			//
		} else {
			isrc++;
			String source = src[isrc];

			if (!source.equals("")){    
				if (len >= source.length()){
					result.addValue(source);
				} else {

				int e = source.length() / len;
				e = ((source.length() % len) > 0 ? e + 1 : e); 

				int s = 0;
				for (int i = 0; i < e; i++){
					if (source.length() - s > len){
					result.addValue(source.substring(s, s + len));
					} else {
						result.addValue(source.substring(s));
					}
					s += len;
				}
			} 
				result.addContextChange();
			} 
		}
	}
 	return;
}

Implementazione per testi di testata

Questo genera le occorrenze di E1EDKT2 sulla base del numero di sottostringhe di TDLINE

Questo, per ciascun contesto, effettua lo splitting di TDLINE in ingresso e scrive le sottostringhe prodotte nei campi TDLINE in uscita.

Implementazione per testi di posizione

Questo genera le occorrenze di E1EDPT2 sulla base del numero di sottostringhe di TDLINE

Questo, per ciascun contesto, effettua lo splitting di TDLINE in ingresso e scrive le sottostringhe prodotte nei campi TDLINE in uscita.

Nel seguente esempio, il contesto in entrata all’UDF – 1mo param, è così configurato:

E1EDP01 con testo (true)

E1EDP01 senza testo (false) -> SUPPRESS

E1EDP01 con testo (true)