Récupération de fichier d'une api REST et envoie sur un FTP
Bonjour,
Je cherche a créer un flux qui doit appeler une API qui me permet de récupérer le contenu d'un fichier.
pour se faire j'ai créer une classe qui hérite de Ens.BusinessService pour l'appel api
Method OnProcessInput(pInput As%RegisteredObject, Output pOutput As%RegisteredObject) As%Status
{
Set sc = $$$OKset res = ##class(Ens.StringResponse).%New()
set request = ##class(%Net.HttpRequest).%New()
set response = ##class(%Net.HttpResponse).%New()
set request.Https = 1set request.Server = ..ServerAddressset request.Port = ..Portset request.SSLConfiguration = ..SSLConfigurationTry {
set url = ..Path _ "/exportArticles_"_$ZDATE($HOROLOG,8)_".csv"set status = request.Get(url)
$$$TRACE("request.HttpResponse.Data :"_request.HttpResponse.Data)
set content = ##class(Ens.StreamContainer).%New()
set stream = ##class(%Stream.GlobalCharacter).%New()
do stream.Write(request.HttpResponse.Data)
$$$TRACE("sc : " _ request.HttpResponse.StatusCode)
$$$TRACE("stream size:"_stream.Size)
set content.Stream = stream
$$$TRACE("stream :"_stream.Read(1000))
set sc = ..SendRequestSync(..TargetConfigNames, content)
}
Catch ex {
set status= ex.AsStatus()
$$$TRACE("erreur : "_status)
}
set result = request.HttpResponse.StatusCode
if (result '= 200) {
$$$TRACE("status: "_ result)
}
return$$$OK
}et une de type Ens.BusinessOperation pour l'envoie en ftp
Class SupplyChain.exportArticleHaby Extends Ens.BusinessOperation
{
Property Adapter As EnsLib.FTP.OutboundAdapter;Parameter ADAPTER = "EnsLib.FTP.OutboundAdapter";Parameter INVOCATION = "Queue";
Method putFileStream(pRequest As Ens.StreamContainer, Output pResponse As Ens.Response) As%Status
{
$$$TRACE("pRequest : "_ pRequest)
Try {
set fileName = "exportArticles_"_$ZDATE($HOROLOG,8)_".csv"set esc = ..Adapter.PutStream(fileName, pRequest.Stream())
}
Catch ex {
$$$TRACE("statusCode: " _ esc)
Set tSC=ex.AsStatus()
}
return$$$OK
}
XData MessageMap
{
<MapItems>
<MapItem MessageType="Ens.StreamContainer">
<Method>putFileStream</Method>
</MapItem>
</MapItems>
}
}Cependant dans ma production, j'ai l'impression que ma business opération n'est pas appelé, je ne vois pas la trace que j'ai dans ma classe,
Le service est bien lié a l'opération dans ma production, j'ai bien les trace de mon service, je reçoi bien un statut 200 de l'api.
.png)
Comments
Bonjour @Jean-Charles.Cano,
Stream n'est pas une méthode mais une propriété ; aussi, tout devrait aller mieux après avoir remplacé cette ligne :
set esc = ..Adapter.PutStream(fileName, pRequest.Stream())par celle-ci :
set esc = ..Adapter.PutStream(fileName, pRequest.Stream)Bonjour Sylvain,
merci pour ta réponse, cela fonctionne.
update,
en fait cela fonctionne mais dans mon fichier CSV déposé sur le serveur FTP, j'ai comme contenu :
9@%Stream.GlobalBinary
Et non le contenu des fichiers que je dois récupérer de l'API
Bonjour @Jean-Charles.Cano ,
Pour le passage d'un stream à un autre, j'éviterai d'utiliser la fonction Write si vous ne bouclez pas sur le stream d'entrée.
En effet, la fonction Write fonctionne par chunks, donc si vous n'avez pas lu tout le stream d'entrée, vous risquez de ne pas avoir tout écrit dans le stream de sortie.
Comme vous utilisez la classe Ens.StreamContainer, vous pouvez utiliser le constructeur qui prend en paramètre un stream d'entrée et qui copie le contenu complet du stream d'entrée dans la variable de Stream du StreamContainer.
Method OnProcessInput(pInput As %RegisteredObject, Output pOutput As %RegisteredObject) As %Status
{
Set sc = $$$OK
set res = ##class(Ens.StringResponse).%New()
set request = ##class(%Net.HttpRequest).%New()
set response = ##class(%Net.HttpResponse).%New()
set request.Https = 1
set request.Server = ..ServerAddress
set request.Port = ..Port
set request.SSLConfiguration = ..SSLConfiguration
Try {
set url = ..Path _ "/exportArticles_"_$ZDATE($HOROLOG,8)_".csv"
set status = request.Get(url)
$$$TRACE("request.HttpResponse.Data :"_request.HttpResponse.Data)
#; Commented code to show the difference between the two methods
#; set content = ##class(Ens.StreamContainer).%New()
#; set stream = ##class(%Stream.GlobalCharacter).%New()
#; do stream.Write(request.HttpResponse.Data)
#; Recommended method
set content = ##class(Ens.StreamContainer).%New(request.HttpResponse.Data)
#; Other methods by looping on the stream
#; set content = ##class(Ens.StreamContainer).%New()
#; set stream = ##class(%Stream.GlobalCharacter).%New()
#; while 'request.HttpResponse.Data.AtEnd {
#; set stream.Write(request.HttpResponse.Data.Read())
#; }
#; set content.Stream = stream
$$$TRACE("sc : " _ request.HttpResponse.StatusCode)
#; Old code
#; $$$TRACE("stream size:"_stream.Size)
#; set content.Stream = stream
#; $$$TRACE("stream :"_stream.Read(1000))
#; New code
$$$TRACE("content.Stream.Size :"_content.Stream.Size)
$$$TRACE("content.Stream :"_content.Stream.Read(1000))
set sc = ..SendRequestSync(..TargetConfigNames, content)
}
Catch ex {
set status= ex.AsStatus()
$$$TRACE("erreur : "_status)
}
set result = request.HttpResponse.StatusCode
if (result '= 200) {
$$$TRACE("status: "_ result)
}
return $$$OK
}
Ensuite pour la partie écriture avec l'adapter FTP,vous pouvez utiliser la methode PutStream de l'adapter FTP.
Class SupplyChain.exportArticleHaby Extends Ens.BusinessOperation
{
Property Adapter As EnsLib.FTP.OutboundAdapter;
Parameter ADAPTER = "EnsLib.FTP.OutboundAdapter";
Parameter INVOCATION = "Queue";
Method putFileStream(pRequest As Ens.StreamContainer, Output pResponse As Ens.Response) As %Status
{
$$$TRACE("pRequest : "_ pRequest)
Try {
set fileName = "exportArticles_"_$ZDATE($HOROLOG,8)_".csv"
set esc = ..Adapter.PutStream(fileName, pRequest.Stream)
}
Catch ex {
$$$TRACE("statusCode: " _ esc)
Set tSC=ex.AsStatus()
}
return $$$OK
}
XData MessageMap
{
<MapItems>
<MapItem MessageType="Ens.StreamContainer">
<Method>putFileStream</Method>
</MapItem>
</MapItems>
}
}
Bonjour,
merci pour vos explications, c'est plus clair maintenant et ça fonctionne.