on 02-25-2015 9:40 AM
Hello,
after spending some time on google i didn't find a helping thread.. so i'll give it a try at the SCN
We've developed a gateway service to create leaverequests.
The included check returns warning messages as "leave request is in workfree time" - for example for a weekend.
The LR will still be persisted - so no exceptions.
But i want to return these messages to the gatewayservice/frontend.
I found a thread that helped me a little, but i'm not quite satisfied yet.
The message will only be returned if i raise an exception.
But i don't want a 400 Bad Request.
The GW Component is updated to SP8 as suggested by Ralf Handl.
Did i do something wrong? Is it even possible to include messages in the return-body?
I tried the example code from the thread linked above.
Thanks for advice!
Greetings,
Pascal
Hello Pascal,
I assume that Create LeaveRequest would be a POST/Create operation through GW.
I would suggest the below way ->
Assume you already have LeaveRequest entity in GW Model.
In your GW model add another entity say ReturnError and add the fields say MessageType and MessageText.
Now create association and navigation between LeaveRequest entity and ReturnError entity with cardinality 1 to N.
In DPC_EXT class implement Create_Deep_Entity.
Here you will create deep structure which can hold Leave related data and also Error messages as well.
After processing request in backend, Use this deep structure to add messages ( message type E or S or W and corresponding messages ) and leave request data and send it back as GW response.
In the UI level check the Message Type and perform the operation accordingly in front end.
This way you can handle.
Technical help can be found here ->
Step by Step development for CREATE_DEEP_ENTITY operation
Regards,
Ashwin
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
it is possible to return some message to the front end, without raising exception. The code is available in Success/Error/Info Message in return of Odata Service response from ECC.
Here is a working sample for you.
Code in Some Dummy DPC
------------------------------------------------------
Output in the Gateway Client
--------------------------------------------
Here you can see that I am also sending some message along with the feed. However the message appears only in the response header highlighted above. The full message is not displayed here due to restriction in the length of header values.
another option would be to pass custom header as I mentioned in the post Success/Error/Info Message in return of Odata Service response from ECC.
Hi Ashwin,
i have created a new entity Errormessages and also created the association/navigation.
In the method create_deep_entity i included the errormessages into the request-structure.
But the errormessages are not in the response.
Do i have to call another method ?
I don't have to create a serviceimplementation, right?
Regards,
Pascal
Hello Ashwin,
this is my PayLoad-Trace:
{
"d" : {
"StartDate" : "2015-02-28T00:00:00.000",
"EndDate" : "2015-02-28T00:00:00.000",
"RequestID" : "000C291A23A21ED49F92F9AE5A3CACD0",
"LeaveRequestTypeCode" : "0210",
"IllnessReason" : "B12002",
"Approvers" : [
{
"ApproverID" : "00001100",
"SeqNo" : "000"
},
{
"ApproverID" : "00001246",
"SeqNo" : "001"
},
{
"ApproverID" : "00001206",
"SeqNo" : "002"
},
{
"ApproverID" : "00001200",
"SeqNo" : "003"
}
]
}
}
The navgiation property is called Errormessages, the Relationship name ErrorMessagesOfLeaveRequest which has the association between LeaveRequest(1) and Errormessages (N).
So i also have to post the Errormessages-Element in my Request to the Gateway?
Regards,
Pascal
Hello Pascal,
Use the below payload and check if you are able to see all the error messages which are sent as response.
{
"StartDate" : "2015-02-28T00:00:00.000",
"EndDate" : "2015-02-28T00:00:00.000",
"RequestID" : "000C291A23A21ED49F92F9AE5A3CACD0",
"LeaveRequestTypeCode" : "0210",
"IllnessReason" : "B12002",
"Approvers" : [
{
"ApproverID" : "00001100",
"SeqNo" : "000"
},
{
"ApproverID" : "00001246",
"SeqNo" : "001"
},
{
"ApproverID" : "00001206",
"SeqNo" : "002"
},
{
"ApproverID" : "00001200",
"SeqNo" : "003"
}
],
"Errormessages":[ ]
}
Regards,
Ashwin
Here you go:
types: begin of type_request_err.
include type /XXX/tt_req_crea_struc.
types: approvers type /XXX/tt_approvers,
errormessages type bapiret2_tab,
end of type_request_err.
It includes the request_create_structure, the Approvers-Table and Table of bapiret2 which is also defined in the gateway-entity/model.
When i delete the Errormessages-Tag in your testrequest, the approvers will be returned.
Did i miss something?
Structure is fine.
Ok Can you try with this please?
{
"d" : {
"StartDate" : "2015-02-28T00:00:00.000",
"EndDate" : "2015-02-28T00:00:00.000",
"RequestID" : "000C291A23A21ED49F92F9AE5A3CACD0",
"LeaveRequestTypeCode" : "0210",
"IllnessReason" : "B12002",
"Approvers" : [
{
"ApproverID" : "00001100",
"SeqNo" : "000"
},
{
"ApproverID" : "00001246",
"SeqNo" : "001"
},
{
"ApproverID" : "00001206",
"SeqNo" : "002"
},
{
"ApproverID" : "00001200",
"SeqNo" : "003"
}
],
"Errormessages":[{ }]
}
}
Still no return
This is my testcoding. I cut out some parts which are unnecessary and absolutely random
* declaration
types: begin of type_request_err.
include type /XXX/tt_req_crea_struc.
types: approvers type /XXX/tt_approver_tab,
errormessages type bapiret2_tab,
end of type_request_err.
* body
* CASE WHICH ENTITY_SET!
case iv_entity_set_name.
when 'LeaveRequestCollection'.
lv_compare = io_expand->compare_to( 'Approvers' ).
* check if results compare
if lv_compare eq /iwbep/if_mgw_odata_expand=>gcs_compare_result-match_equals.
io_data_provider->read_entry_data( importing es_data = ls_request_err ).
endif.
* create request
call method me->leaverequestcoll_create_entity
exporting
iv_entity_name = iv_entity_name
iv_entity_set_name = iv_entity_set_name
iv_source_name = iv_source_name
it_key_tab = it_key_tab
io_tech_request_context = io_tech_request_context
it_navigation_path = it_navigation_path
io_data_provider = io_data_provider
importing
er_entity = ls_entity.
* if request is valid, insert/update approvers
if ls_entity is not initial.
class ca_pt_req_actor definition load.
lr_actor_agent = ca_pt_req_actor=>agent.
loop at ls_request-approvers into ls_items.
* insert approvers
else.
* rollback
endif.
call method mo_context->get_message_container
receiving
ro_message_container = lr_message_cont.
lt_messages = lr_message_cont->get_messages( ).
if lt_messages is not initial.
* move-corresponding ls_entity to ls_response_err.
loop at lt_messages into ls_messages.
move-corresponding ls_messages to ls_bapiret2.
append ls_bapiret2 to ls_response_err-errormessages.
endloop.
ls_approvers-pernr = '00001120'.
ls_approvers-seqnr = '003'.
append ls_approvers to ls_response_err-approvers.
move-corresponding ls_entity to ls_response_err.
copy_data_to_ref(
exporting
is_data = ls_response_err
changing
cr_data = er_deep_entity ).
else.
* create response
if ls_entity is not initial.
copy_data_to_ref(
exporting
is_data = ls_entity
changing
cr_data = er_deep_entity
).
endif.
endif.
This testcoding only includes the important parts.
The original coding worked for the approvers part, so i thought it should also fit for the errormessages.
Thanks!
Please share what is the difference between structures ' ls_response_err ' and ' ls_entity ' in the below ?
copy_data_to_ref(
exporting
is_data = ls_response_err
changing
cr_data = er_deep_entity ).
copy_data_to_ref(
exporting
is_data = ls_entity
changing
cr_data = er_deep_entity
).
You can have only one structure as part of gateway response.
Ideally the response structure will be a single deep structure which will have details of request and corresponding error as well ( i assume ls_request_err is the structure which you would like to send back as response )
You need to call copy_data_to_ref method only once at the end sending ls_request_err and this deep structure would be a structure which is of type type_request_err ( Which is defined at the beginning and i assume ls_request_err is the type of type_request_err ).
Please check the above points and call copy_data_to_ref method at the last by populating ls_request_err with all the error details corresponding to each leave request.
Regards,
Ashwin
As i said, this is just test coding.
ls_entity is type type_request which does not include the errormessages.
It will be called if no messages are available.
Yes, ls_request_err is the structure i want to return.
This is the last copy_data_to_ref:
copy_data_to_ref(
exporting
is_data = ls_response_err
changing
cr_data = er_deep_entity ).
So the messages are included.
Regards,
Pascal
Not sure, If I got it correctly. I think it can be used to return multiple messages as well.
You can write Code in DPC to create multiple messages as returned by your RFC in BAPIRETURN table
DATA: lo_container TYPE REF TO /iwbep/if_message_container.
lo_container = me->mo_context->get_message_container( ).
lo_container->add_message( iv_msg_type = 'S'
iv_msg_id = 'ZZZ
iv_msg_number = 45
iv_msg_text = 'List of Messages'
iv_is_leading_message = abap_false
iv_add_to_response_header = abap_true
).
lo_container->add_message( iv_msg_type = 'S'
iv_msg_id = 'ZZZ’
iv_msg_number = 45
iv_msg_text = 'Test Msg 2'
iv_is_leading_message = abap_false
iv_add_to_response_header = abap_true
).
lo_container->add_message( iv_msg_type = 'S'
iv_msg_id = 'ZZZ’
iv_msg_number = 45
iv_msg_text = 'Test Msg 3'
iv_is_leading_message = abap_false
iv_add_to_response_header = abap_true
).
The message in ZZZ/45 is '&1 &2 &3 &4' i.e just a place holder.
If you run the service you will get the response headers with all the messages. you need to test it in REST client as the GATEWAY CLIENT would truncate the result for header length limitations. In my case the sap-message response header looks like '
<notification xmlns:sap="http://www.sap.com/Protocols/SAPData"><code>/ZZZ/045</code><message>List of Messages</message><severity>info</severity><target></target><details><detail><code>/ZZZ/045</code><message>Test Msg 2</message><target></target><severity>info</severity></detail><detail><code>/IWBEP/ZZZ/045</code><message>Test Msg 3</message><target></target><severity>info</severity></detail></details></notification>'. If I format the value in some XML parser I get the nice response like
<?xml version="1.0" encoding="UTF-8"?>
<notification xmlns:sap="http://www.sap.com/Protocols/SAPData">
<code>/ZZZ/045</code>
<message>List of Messages</message>
<severity>info</severity>
<target />
<details>
<detail>
<code>/ZZZ/045</code>
<message>Test Msg 2</message>
<target />
<severity>info</severity>
</detail>
<detail>
<code>/ZZZ/045</code>
<message>Test Msg 3</message>
<target />
<severity>info</severity>
</detail>
</details>
</notification>
also you can get the same message response in JSON format by specifying $format=json in the URL.
{"code":"/IZZZ/045","message":"List of Messages","severity":"info","target":"","details":[{"code":"/ZZZ/045","message":"Test Msg 2","target":"","severity":"info"},
{"code":"/ZZZ/045","message":"Test Msg 3","target":"","severity":"info"}]
}
Hi Atanu,
i tried the following coding:
lr_message_cont->add_message(
exporting
iv_msg_type = 'S'
iv_msg_id = 'ZZZ'
iv_msg_number = '45'
iv_msg_text = 'List of Messages'
iv_is_leading_message = abap_false
iv_add_to_response_header = abap_true
).
But i don't get the message in the response.
With URL/LeaveRequestCollection?$format=json i get the following error:
"The Data Services Request contains SystemQueryOptions that are not allowed for this Request Type"
Any ideas?
Is there a customizing for such things as headers? or deep structure ?
Thanks!
This is the Request:
{
"d" : {
"StartDate" : "2015-02-28T00:00:00.000",
"EndDate" : "2015-02-28T00:00:00.000",
"RequestID" : "000C291A23A21ED49F92F9AE5A3CACD0",
"LeaveRequestTypeCode" : "0210",
"IllnessReason" : "B12002",
"Approvers" : [
{
"ApproverID" : "00001100",
"SeqNo" : "000"
},
{
"ApproverID" : "00001246",
"SeqNo" : "001"
},
{
"ApproverID" : "00001206",
"SeqNo" : "002"
},
{
"ApproverID" : "00001200",
"SeqNo" : "003"
}
],
"Errormessages":[{ }]
}
}
This is the header:
content-encoding: gzip
content-length: 860
server: SAP NetWeaver Application Server / ABAP 731
This is the response:
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xml:base="URL">
<title type="text">
<updated>
<category term="HCM_LEAVEMANAGEMENT_SRV.LeaveRequest" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<link href="LeaveRequestCollection(RequestID='000C291A23A21ED4B09B09FE4E388CD0',VersionNumber=0)" rel="self" title="LeaveRequest" />
<link href="LeaveRequestCollection(RequestID='000C291A23A21ED4B09B09FE4E388CD0',VersionNumber=0)/Approvers" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Approvers" type="application/atom+xml;type=feed" title="Approvers">
<link href="LeaveRequestCollection(RequestID='000C291A23A21ED4B09B09FE4E388CD0',VersionNumber=0)/Errormessages" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/related/Errormessages" type="application/atom+xml;type=feed" title="Errormessages">
<link href="LeaveRequestCollection(RequestID='000C291A23A21ED4B09B09FE4E388CD0',VersionNumber=0)/$links/Approvers" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Approvers" type="application/xml" title="Approvers" />
<link href="LeaveRequestCollection(RequestID='000C291A23A21ED4B09B09FE4E388CD0',VersionNumber=0)/$links/Errormessages" rel="http://schemas.microsoft.com/ado/2007/08/dataservices/relatedlinks/Errormessages" type="application/xml" title="Errormessages" />
<content type="application/xml">
<d:VersionNumber>
<d:Status />
<d:StatusDescr />
<d:LeaveRequestTypeCode>
<d:LeaveRequestTypeDescription />
<d:StartDate>
<d:StartTime>
<d:EndDate>
<d:EndTime>
<d:Duration />
<d:FullWorkingDayIndicator>
<d:SubmDate m:null="true" />
<d:RequesterID>
<d:RequesterUser />
<d:RequesterName />
<d:ApproverID>
<d:ApproverUser />
<d:ApproverName />
<d:AdditionalInformation01 />
<d:AdditionalInformation02 />
<d:AdditionalInformation03 />
<d:AdditionalInformation04 />
<d:AdditionalInformation05 />
<d:AdditionalInformation06 />
<d:AdditionalInformation07 />
<d:AdditionalInformation08 />
<d:AdditionalInformation09 />
<d:AdditionalInformation10 />
<d:IsUpdatable>
<d:IsDeletable>
<d:CurrentNotice />
<d:PastNotice />
<d:IsDataReadOnly>
<d:IsNoticeReadOnly>
<d:IllnessReason>
<d:IllnessReasonDescr />
</entry>
Hi Ashwin,
i took your coding as a template, designed mine like yours .. still not working
I'll create a test-project and do it like you did .. to find out if its the gateway itself that's not working the way it should...
To be sure: The GW_CORE component should at least be Relase 200 SP 0008, right?
Also it is a 7.31 SP11 EHP6 System.
By the way:
In Transaction /IWFND/GW_CLIENT i get the following message : HTTP Receive failed: ICM_HTTP_CONNECTION_FAILED
I did the same as you did, just with the other URI, Token and Body.
Are there any limitations for the length of the response?
I don't get why this isn't working.
When there's only the Approvers-Table in the PayLoad, i get a 201 and my testdata are returned.
If i include the errormessage in the PayLoad, i don't even receive the Approvers anymore .. debugging didn't get me any further
Any ideas left?
Hello Pascal,
I don't think there is something like this will work only with the higher releases.
This has worked for lower releases as well for me.
It should work in yours as well as this kind of scenarios are always encountered.
However the below are my SP levels for the reference:
GW 7.31 ->
GW_CORE : Release 200 SP 06
IW_FND : Release 250 SP 06
ECC 6.0 ->
IW_BEP : Release 200 SP 08
I would suggest to create a new project and just model the GW service exactly the same way i have done. Check if this is working.
Once it works then now create a new project and create entities newly as per your use case and check again.
Regarding error In Transaction /IWFND/GW_CLIENT with message : HTTP Receive failed: ICM_HTTP_CONNECTION_FAILED, your basis folks can help you in resolving this.
Regards,
Ashwin
Hello Pascal,
In which format you are getting the response ? XML ?
Can you just try to get the response in JSON and check if you are able to see desired response ?
Just add one more header ' Accept ' with value as ' application/json ' and fire the service.
However details of Entities with Edm Types are below ->
1. PostData
Property Name - RequestID
Edm Type - Edm.String
2. AppData
Property Name - AppID , Edm Type - Edm.String
Property Name - SeqID , Edm Type - Edm.String
3. ErrorRet
Property Name - MessTyp, Edm Type - Edm.String
Property Name - MessText, Edm Type - Edm.String
Structures which are created by GW Service Builder in Model Class :
types:
begin of TS_POSTDATA,
REQUESTID type C length 30,
end of TS_POSTDATA. .
types:
TT_POSTDATA type standard table of TS_POSTDATA. .
types:
begin of TS_APPDATA,
APPID type C length 5,
SEQID type C length 2,
end of TS_APPDATA. .
types:
TT_APPDATA type standard table of TS_APPDATA. .
types:
begin of TS_ERRORRET,
MESSTYP type C length 1,
MESSTEXT type C length 50,
end of TS_ERRORRET. .
types:
TT_ERRORRET type standard table of TS_ERRORRET. .
If this is not working then we can try with other options.
Regards,
Ashwin
User | Count |
---|---|
87 | |
10 | |
10 | |
9 | |
7 | |
6 | |
6 | |
5 | |
4 | |
3 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.