blob: b1c2acb00c6b5a696fa148437381b76e803da9d1 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2019 Ericsson Telecom AB //
// //
// All rights reserved. This program and the accompanying materials //
// are made available under the terms of the Eclipse Public License v2.0 //
// which accompanies this distribution, and is available at //
// https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html //
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Module: EPTF_CLL_DsRestAPI_DSServer_Functions
//
// Purpose:
// This module contains functions of EPTF_CLL_DsRestAPI_DSServer.
//
// Module depends on:
// <EPTF_CLL_Variable_Definitions>
// <EPTF_CLL_DataSource_Definitions>
// <EPTF_CLL_DataSource_Functions>
// <EPTF_CLL_Logging_Functions>
// <EPTF_CLL_Variable_Functions>
// <EPTF_CLL_Base_Functions>
// <EPTF_CLL_DsRestAPI_DSServer_Definitions>
// <TCCConversion_Functions>
// <EPTF_CLL_Common_Definitions>
//
// Current Owner:
// Tamas Kis (ekistam)
//
// Last Review Date:
// -
//
// Detailed Comments:
// This module contains the interface functions for the EPTF_CLL_DsRestAPI.
// Public functions:
// <f_EPTF_DsRestAPI_DSServer_init_CT>
// <f_EPTF_DsRestAPI_DSServer_processJSONRequest>
//
///////////////////////////////////////////////////////////////
module EPTF_CLL_DsRestAPI_DSServer_Functions
{
//=========================================================================
// Import Part
//=========================================================================
import from EPTF_CLL_Variable_Definitions all;
import from EPTF_CLL_DataSource_Definitions all;
import from EPTF_CLL_DataSource_Functions all;
import from EPTF_CLL_Variable_Functions all;
import from EPTF_CLL_Base_Functions all;
import from EPTF_CLL_DsRestAPI_DSServer_Definitions all;
import from EPTF_CLL_DsRestAPI_Timeline_Definitions all;
import from TCCConversion_Functions all;
import from EPTF_CLL_Common_Definitions all;
import from EPTF_CLL_FBQ_Functions all;
import from EPTF_CLL_DsRestAPI_Filter_Definitions all;
import from EPTF_CLL_DsRestAPI_Filter_Functions all;
import from EPTF_CLL_DsRestAPI_Storage_Definitions all;
import from EPTF_CLL_DsRestAPI_Storage_Functions all;
friend module EPTF_CLL_DsRestAPI_Timeline_Functions;
//=========================================================================
// Functions
//=========================================================================
private external function ef_DsRestAPI_dec_Requests(in octetstring pl_par) return EPTF_DsRestAPI_RqWrapper with { extension "prototype(convert) decode(JSON)" }
private external function ef_DsRestAPI_enc_ContentList(in EPTF_DsRestAPI_ContentAndChildrenListWrapper pl_par) return octetstring with { extension "prototype(convert) encode(JSON) errorbehavior(ALL:WARNING)" }
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_init_CT
//
// Purpose:
// Initialize the DataSource Server for DsRestAPI
//
// Parameters:
// pl_selfName - *in* *charstring* - the name of the component
//
// Return Value:
// -
/////////////////////////////////////////////////////////////////////////
public function f_EPTF_DsRestAPI_DSServer_init_CT(in charstring pl_selfName) runs on EPTF_DsRestAPI_DSServer_CT {
if (not v_DsRestAPI_DSServer_initialized) {
f_EPTF_Base_init_CT(pl_selfName);
f_EPTF_Var_init_CT(pl_selfName);
f_EPTF_DataSource_init_CT(pl_selfName);
f_EPTF_DsRestAPI_Filter_init_CT(pl_selfName);
f_EPTF_FBQ_init_CT(pl_selfName);
f_EPTF_FBQ_initFreeBusyQueue(v_DsRestAPI_DSServer_requestQueue);
f_EPTF_FBQ_initFreeBusyQueue(v_DsRestAPI_DSServer_responseQueue);
var EPTF_DataSource_ValueType vl_tmp := intType; v_DsRestAPI_DSServer_intType := enum2int(vl_tmp) + 1;
vl_tmp := floatType; v_DsRestAPI_DSServer_floatType := enum2int(vl_tmp) + 1;
vl_tmp := boolType; v_DsRestAPI_DSServer_boolType := enum2int(vl_tmp) + 1;
vl_tmp := charstringType; v_DsRestAPI_DSServer_charstringType := enum2int(vl_tmp) + 1;
vl_tmp := octetstringType; v_DsRestAPI_DSServer_octetstringType := enum2int(vl_tmp) + 1;
vl_tmp := hexstringType; v_DsRestAPI_DSServer_hexstringType := enum2int(vl_tmp) + 1;
vl_tmp := bitstringType; v_DsRestAPI_DSServer_bitstringType := enum2int(vl_tmp) + 1;
vl_tmp := integerlistType; v_DsRestAPI_DSServer_integerlistType := enum2int(vl_tmp) + 1;
vl_tmp := floatlistType; v_DsRestAPI_DSServer_floatlistType := enum2int(vl_tmp) + 1;
vl_tmp := charstringlistType; v_DsRestAPI_DSServer_charstringlistType := enum2int(vl_tmp) + 1;
vl_tmp := statusLEDType; v_DsRestAPI_DSServer_statusLEDType := enum2int(vl_tmp) + 1;
f_EPTF_Base_registerCleanup(refers(f_EPTF_DsRestAPI_DSServer_cleanup_CT));
v_DsRestAPI_DSServer_initialized := true;
}
}
private function f_EPTF_DsRestAPI_DSServer_cleanup_CT() runs on EPTF_DsRestAPI_DSServer_CT {
if (v_DsRestAPI_DSServer_initialized) {
f_EPTF_FBQ_deleteFreeBusyQueue(v_DsRestAPI_DSServer_requestQueue);
f_EPTF_FBQ_deleteFreeBusyQueue(v_DsRestAPI_DSServer_responseQueue);
v_DsRestAPI_DSServer_requestHandlerDB := {};
v_DsRestAPI_DSServer_responseHandlerDB := {};
v_DsRestAPI_DSServer_filterItemsDB := {};
v_DsRestAPI_DSServer_initialized := false;
}
}
private function f_EPTF_DsRestAPI_DSServer_getContentTypeInteger(in EPTF_Var_DirectContent pl_Content) runs on EPTF_DsRestAPI_DSServer_CT return integer {
var integer vl_Res := v_DsRestAPI_DSServer_charstringType;
if (ischosen(pl_Content.intVal)) {
vl_Res := v_DsRestAPI_DSServer_intType;
} else if (ischosen(pl_Content.floatVal)) {
vl_Res := v_DsRestAPI_DSServer_floatType;
} else if (ischosen(pl_Content.boolVal)) {
vl_Res := v_DsRestAPI_DSServer_boolType;
} else if (ischosen(pl_Content.charstringVal)) {
vl_Res := v_DsRestAPI_DSServer_charstringType;
} else if (ischosen(pl_Content.octetstringVal)) {
vl_Res := v_DsRestAPI_DSServer_octetstringType;
} else if (ischosen(pl_Content.hexstringVal)) {
vl_Res := v_DsRestAPI_DSServer_hexstringType;
} else if (ischosen(pl_Content.bitstringVal)) {
vl_Res := v_DsRestAPI_DSServer_bitstringType;
} else if (ischosen(pl_Content.integerlistVal)) {
vl_Res := v_DsRestAPI_DSServer_integerlistType;
} else if (ischosen(pl_Content.floatlistVal)) {
vl_Res := v_DsRestAPI_DSServer_floatlistType;
} else if (ischosen(pl_Content.charstringlistVal)) {
vl_Res := v_DsRestAPI_DSServer_charstringlistType;
} else if (ischosen(pl_Content.statusLEDVal)) {
vl_Res := v_DsRestAPI_DSServer_statusLEDType;
} else if (ischosen(pl_Content.unknownVal)) {
vl_Res := v_DsRestAPI_DSServer_noType;
}
return vl_Res;
}
private function f_EPTF_DsRestAPI_DSServer_processSetData(in EPTF_DsRestAPI_SetData pl_setData, out EPTF_Var_DirectContent pl_dataValue) runs on EPTF_DsRestAPI_DSServer_CT return integer {
var integer vl_Ret := 0;
var integer vl_dataType := pl_setData.tp;
@try {
if (vl_dataType == v_DsRestAPI_DSServer_intType) {
pl_dataValue := {intVal := str2int(pl_setData.content)};
}
else if (vl_dataType == v_DsRestAPI_DSServer_floatType) {
pl_dataValue := {floatVal := str2float(pl_setData.content)};
}
else if (vl_dataType == v_DsRestAPI_DSServer_boolType) {
pl_dataValue := {boolVal := pl_setData.content == "true"};
}
else if (vl_dataType == v_DsRestAPI_DSServer_charstringType) {
pl_dataValue := {charstringVal := pl_setData.content};
}
else if (vl_dataType == v_DsRestAPI_DSServer_octetstringType) {
pl_dataValue := {octetstringVal := char2oct(pl_setData.content)};
}
else if (vl_dataType == v_DsRestAPI_DSServer_hexstringType) {
pl_dataValue := {hexstringVal := str2hex(pl_setData.content)};
}
else if (vl_dataType == v_DsRestAPI_DSServer_bitstringType) {
pl_dataValue := {bitstringVal := str2bit(pl_setData.content)};
}
else if (vl_dataType == v_DsRestAPI_DSServer_integerlistType) {
pl_dataValue := {integerlistVal := {str2int(pl_setData.content)}};
}
else if (vl_dataType == v_DsRestAPI_DSServer_floatlistType) {
pl_dataValue := {floatlistVal := {str2float(pl_setData.content)}};
}
else if (vl_dataType == v_DsRestAPI_DSServer_charstringlistType) {
pl_dataValue := {charstringlistVal := {pl_setData.content}};
}
else if (vl_dataType == v_DsRestAPI_DSServer_statusLEDType) {
//TODO vl_dataValue := {statusLEDVal := {pl_setData.content}};
pl_dataValue := {statusLEDVal := {led_black,""}};
vl_Ret := f_EPTF_Var_str2directContent(pl_setData.content, pl_dataValue);
} else {
pl_dataValue := {charstringVal := "Invalid tp: " & int2str(vl_dataType)};
vl_dataType := v_DsRestAPI_DSServer_charstringType;
vl_Ret := 1;
}
} @catch(dte_str) {
var charstring vl_searchStr := "Dynamic test case error:";
var charstring vl_dteErrorMsg := "";
var integer vl_strPos := f_strstr(dte_str, vl_searchStr);
var integer vl_lenSearchStr := lengthof(vl_searchStr);
if (vl_strPos != -1) {
vl_dteErrorMsg := substr(dte_str, vl_strPos+vl_lenSearchStr+1, lengthof(dte_str)-vl_strPos-vl_lenSearchStr-1);
} else {
vl_dteErrorMsg := substr(dte_str, 0, lengthof(dte_str));
}
pl_dataValue := {charstringVal := "Cannot convert content: " & pl_setData.content & " to tp: " & int2str(vl_dataType) & ", Reason: " & vl_dteErrorMsg};
vl_dataType := v_DsRestAPI_DSServer_charstringType;
vl_Ret := 2;
}
return vl_Ret;
}
private function f_EPTF_DsRestAPI_DSServer_completeGetDataParams(inout EPTF_DsRestAPI_Request pl_request, in charstring pl_replaceTemplate, in charstring pl_replacement) {
if (ischosen(pl_request.getData)) {
if (not ispresent(pl_request.getData.ptcname)) {
pl_request.getData.ptcname := "";
}
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.source, pl_replaceTemplate, pl_replacement);
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.ptcname, pl_replaceTemplate, pl_replacement);
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.element, pl_replaceTemplate, pl_replacement);
if (ispresent(pl_request.getData.params)) {
var integer vl_getDataParamsSize := sizeof(pl_request.getData.params);
for (var integer vl_i := 0; vl_i < vl_getDataParamsSize; vl_i := vl_i + 1) {
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.params[vl_i].paramValue, pl_replaceTemplate, pl_replacement);
}
}
if (ispresent(pl_request.getData.filter) and ischosen(pl_request.getData.filter.dataValue)) {
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.getData.filter.dataValue, pl_replaceTemplate, pl_replacement);
}
} else if (ischosen(pl_request.setData)) {
if (not ispresent(pl_request.setData.ptcname)) {
pl_request.setData.ptcname := "";
}
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.source, pl_replaceTemplate, pl_replacement);
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.ptcname, pl_replaceTemplate, pl_replacement);
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.element, pl_replaceTemplate, pl_replacement);
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.content, pl_replaceTemplate, pl_replacement);
if (ispresent(pl_request.setData.params)) {
var integer vl_setDataParamsSize := sizeof(pl_request.setData.params);
for (var integer vl_i := 0; vl_i < vl_setDataParamsSize; vl_i := vl_i + 1) {
ef_EPTF_DsRestAPI_replaceAllIfMatches(pl_request.setData.params[vl_i].paramValue, pl_replaceTemplate, pl_replacement);
}
}
}
}
private function f_EPTF_DsRestAPI_DSServer_createIsWritableRequest(in EPTF_DsRestAPI_Request pl_request) return EPTF_DsRestAPI_Request {
var EPTF_DsRestAPI_Request vl_request := {
getData := {
source := c_EPTF_DataSource_sourceId,
ptcname := omit,
element := c_EPTF_DataSource_dataElement_isWritable,
params := {},
cookie := omit,
children := omit,
filter := omit,
rangeFilter := omit,
selection := omit,
selectionValues := omit,
writableInfo := omit,
timeline := omit
}
}
var integer vl_paramIndex := 0;
// source
vl_request.getData.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameSource,
paramValue := pl_request.getData.source
}
// element
vl_paramIndex := vl_paramIndex + 1;
vl_request.getData.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameElement,
paramValue := pl_request.getData.element
}
// ptcname
if (ispresent(pl_request.getData.ptcname)) {
vl_paramIndex := vl_paramIndex + 1;
vl_request.getData.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNamePTCName,
paramValue := pl_request.getData.ptcname
}
}
// params
if (ispresent(pl_request.getData.params)) {
var integer vl_paramsSize := sizeof(pl_request.getData.params);
for (var integer i := 0; i < vl_paramsSize; i := i + 1) {
vl_paramIndex := vl_paramIndex + 1;
vl_request.getData.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameParamName,
paramValue := pl_request.getData.params[i].paramName
}
vl_paramIndex := vl_paramIndex + 1;
vl_request.getData.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameParamValue,
paramValue := pl_request.getData.params[i].paramValue
}
}
}
return vl_request;
}
private function f_EPTF_DsRestAPI_DSServer_createITimelineRequest(inout EPTF_DsRestAPI_GetData pl_request) {
var EPTF_DsRestAPI_GetData vl_request := {
source := c_DsRestAPI_Timeline_DataSource_sourceId,
ptcname := omit,
element := c_DsRestAPI_Timeline_dataElementTimeline,
params := {},
cookie := omit,
children := omit,
filter := omit,
rangeFilter := omit,
selection := omit,
selectionValues := omit,
writableInfo := omit,
timeline := omit
}
var integer vl_paramIndex := 0;
if (ispresent(pl_request.timeline.period)) {
vl_request.params[vl_paramIndex] := {
paramName := c_DsRestAPI_Timeline_paramNamePeriod,
paramValue := float2str(pl_request.timeline.period)
}
vl_paramIndex := vl_paramIndex + 1;
}
if (ispresent(pl_request.timeline.maxpoints)) {
vl_request.params[vl_paramIndex] := {
paramName := c_DsRestAPI_Timeline_paramNameMaxpoints,
paramValue := int2str(pl_request.timeline.maxpoints)
}
vl_paramIndex := vl_paramIndex + 1;
}
if (ispresent(pl_request.timeline.since)) {
vl_request.params[vl_paramIndex] := {
paramName := c_DsRestAPI_Timeline_paramNameSince,
paramValue := int2str(pl_request.timeline.since)
}
vl_paramIndex := vl_paramIndex + 1;
}
// source
vl_request.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameSource,
paramValue := pl_request.source
}
// element
vl_paramIndex := vl_paramIndex + 1;
vl_request.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameElement,
paramValue := pl_request.element
}
// ptcname
if (ispresent(pl_request.ptcname)) {
vl_paramIndex := vl_paramIndex + 1;
vl_request.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNamePTCName,
paramValue := pl_request.ptcname
}
}
// params
if (ispresent(pl_request.params)) {
var integer vl_paramsSize := sizeof(pl_request.params);
for (var integer i := 0; i < vl_paramsSize; i := i + 1) {
vl_paramIndex := vl_paramIndex + 1;
vl_request.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameParamName,
paramValue := pl_request.params[i].paramName
}
vl_paramIndex := vl_paramIndex + 1;
vl_request.params[vl_paramIndex] := {
paramName := c_EPTF_DataSource_paramNameParamValue,
paramValue := pl_request.params[i].paramValue
}
}
}
pl_request := vl_request;
}
private function f_EPTF_DsRestAPI_DSServer_completeGetDataParameters(inout EPTF_DsRestAPI_Request pl_request, in EPTF_CharstringList pl_parentList, in EPTF_IntegerList pl_parentIndexList) {
var integer vl_parentListLength := sizeof(pl_parentList);
for (var integer i := 0; i < vl_parentListLength; i := i + 1) {
var charstring vl_parentN := "%Parent" & int2str(i) & "%";
var charstring vl_parentIdxN := "%Parent" & int2str(i) & "::idx%";
f_EPTF_DsRestAPI_DSServer_completeGetDataParams(pl_request, vl_parentIdxN, int2str(pl_parentIndexList[i]));
f_EPTF_DsRestAPI_DSServer_completeGetDataParams(pl_request, vl_parentN, pl_parentList[i]);
}
}
private function f_EPTF_DsRestAPI_DSServer_getListLength(in EPTF_Var_DirectContent pl_Content) return integer {
var integer vl_nrGetDataInList := -1;
if (ischosen(pl_Content.charstringlistVal)) {
vl_nrGetDataInList := sizeof(pl_Content.charstringlistVal);
} else if (ischosen(pl_Content.floatlistVal)) {
vl_nrGetDataInList := sizeof(pl_Content.floatlistVal);
} else if (ischosen(pl_Content.integerlistVal)) {
vl_nrGetDataInList := sizeof(pl_Content.integerlistVal);
}
return vl_nrGetDataInList;
}
friend function f_EPTF_DsRestAPI_DSServer_getContentFromDataValue(in EPTF_Var_DirectContent pl_dataValue) runs on EPTF_DsRestAPI_DSServer_CT return EPTF_DsRestAPI_Content {
var EPTF_DsRestAPI_Content vl_content;
var integer vl_listLen := f_EPTF_DsRestAPI_DSServer_getListLength(pl_dataValue);
if (vl_listLen != -1) {
vl_content.list := {};
for (var integer vl_i := 0; vl_i < vl_listLen; vl_i := vl_i + 1) {
if (ischosen(pl_dataValue.charstringlistVal)) {
vl_content.list[vl_i].node.val := pl_dataValue.charstringlistVal[vl_i];
vl_content.list[vl_i].node.tp := v_DsRestAPI_DSServer_charstringlistType;
} else if (ischosen(pl_dataValue.floatlistVal)) {
vl_content.list[vl_i].node.val := log2str(pl_dataValue.floatlistVal[vl_i]);
vl_content.list[vl_i].node.tp := v_DsRestAPI_DSServer_floatlistType;
} else if (ischosen(pl_dataValue.integerlistVal)) {
vl_content.list[vl_i].node.val := log2str(pl_dataValue.integerlistVal[vl_i]);
vl_content.list[vl_i].node.tp := v_DsRestAPI_DSServer_integerlistType;
}
vl_content.list[vl_i].node.childVals := omit;
}
} else {
vl_content.node.tp := f_EPTF_DsRestAPI_DSServer_getContentTypeInteger(pl_dataValue);
if (vl_content.node.tp == 0) {
vl_content.node.val := "";
} else {
vl_content.node.val := f_EPTF_Var_directContent2str(pl_dataValue);
}
vl_content.node.childVals := omit;
}
return vl_content;
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_sendChildRequests
//
// Purpose:
// Sends the child requests.
//
// Parameters:
// pl_id - *in* *integer* -
// Index into requestHandlerDB.
// pl_request - *in* *EPTF_DsRestAPI_Request* -
// The request whose writable info is needed.
// pl_parentList - *in* *EPTF_CharstringList* -
// The list of parent responses so we can fill out the %ParentX% parts of the filter.
// pl_parentIndexList - *in* *EPTF_IntegerList* -
// The list of parent indexes so we can fill out the %ParentX::idx% parts of the filter.
// pl_path - *in* *EPTF_IntegerList* -
// The request path so we can locate the request in the request tree.
// This is extended by the index of the sent child request.
// pl_indexesInList - *in* *EPTF_IntegerList* -
// The response list indexes which can be used together with pl_path in find the response.
//
// Return Value:
// -
//
// Detailed Comments:
// For every child of the request we fill in the %ParentX% and %ParentX:idx% parts and send it.
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_sendChildRequests(
in integer pl_id,
in EPTF_DsRestAPI_Request pl_request,
in EPTF_CharstringList pl_parentList,
in EPTF_IntegerList pl_parentIndexList,
in EPTF_IntegerList pl_path,
in EPTF_IntegerList pl_indexesInList
) runs on EPTF_DsRestAPI_DSServer_CT {
var EPTF_DsRestAPI_Requests vl_children := pl_request.getData.children;
var integer vl_pathIndex := sizeof(pl_path);
var integer vl_childrenLength := sizeof(vl_children);
for (var integer i := 0; i < vl_childrenLength; i := i + 1) {
var EPTF_DsRestAPI_Request vl_request := vl_children[i];
f_EPTF_DsRestAPI_DSServer_completeGetDataParameters(vl_request, pl_parentList, pl_parentIndexList);
pl_path[vl_pathIndex] := i;
var integer vl_transactionid := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_responseQueue);
f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_responseQueue);
v_DsRestAPI_DSServer_responseHandlerDB[vl_transactionid] := {
requestId := pl_id,
path := pl_path,
indexesInList := pl_indexesInList,
writableInfo := false,
checkPostFilter := true,
parentList := pl_parentList,
parentIndexList := pl_parentIndexList,
storageKey := ""
}
f_EPTF_DsRestAPI_DSServer_handleRequest(vl_request, {vl_transactionid});
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_sendIsWriteableRequest
//
// Purpose:
// Prepares and sends child requests.
//
// Parameters:
// pl_id - *in* *integer* -
// Index into requestHandlerDB.
// pl_request - *in* *EPTF_DsRestAPI_Request* -
// The request whose writable info is needed.
// pl_content - *in* *EPTF_DsRestAPI_Content* -
// The response that was inserted and whose childVals we now try to obtain.
// pl_parentList - *in* *EPTF_CharstringList* -
// The list of parent responses so we can fill out the %ParentX% parts of the filter.
// pl_parentIndexList - *in* *EPTF_IntegerList* -
// The list of parent indexes so we can fill out the %ParentX::idx% parts of the filter.
// pl_path - *in* *EPTF_IntegerList* -
// The request path so we can locate the request in the request tree.
// pl_indexesInList - *in* *EPTF_IntegerList* -
// The response list indexes which can be used together with pl_path in find the response.
// If pl_content is a list, a new index will be added to this.
//
// Return Value:
// -
//
// Detailed Comments:
// We send the child requests for the node or every element of a list taking into account the selection and selectionValues if either of them is present.
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_prepareAndSendChildRequests(
in integer pl_id,
in EPTF_DsRestAPI_Request pl_request,
in EPTF_DsRestAPI_Content pl_content,
in EPTF_CharstringList pl_parentList,
in EPTF_IntegerList pl_parentIndexList,
in EPTF_IntegerList pl_path,
in EPTF_IntegerList pl_indexesInList
) runs on EPTF_DsRestAPI_DSServer_CT {
var integer vl_parentListIndex := sizeof(pl_parentList);
var integer vl_indexesInListIndex := sizeof(pl_indexesInList);
if (ischosen(pl_content.node)) {
pl_parentList[vl_parentListIndex] := pl_content.node.val;
pl_parentIndexList[vl_parentListIndex] := 0;
f_EPTF_DsRestAPI_DSServer_sendChildRequests(pl_id, pl_request, pl_parentList, pl_parentIndexList, pl_path, pl_indexesInList);
} else if (ischosen(pl_content.list)) {
var integer vl_listLength := sizeof(pl_content.list);
if (ispresent(pl_request.getData.selection)) {
if (ispresent(pl_request.getData.selectionValues)) {
pl_request.getData.selection := {0};
}
var integer vl_selectionlength := sizeof(pl_request.getData.selection);
for (var integer i := 0; i < vl_selectionlength; i := i + 1) {
var integer vl_index := pl_request.getData.selection[i];
if (vl_index < vl_listLength) {
pl_parentList[vl_parentListIndex] := pl_content.list[vl_index].node.val;
pl_parentIndexList[vl_parentListIndex] := vl_index;
pl_indexesInList[vl_indexesInListIndex] := vl_index;
f_EPTF_DsRestAPI_DSServer_sendChildRequests(pl_id, pl_request, pl_parentList, pl_parentIndexList, pl_path, pl_indexesInList);
}
}
} else {
for (var integer i := 0; i < vl_listLength; i := i + 1) {
pl_parentList[vl_parentListIndex] := pl_content.list[i].node.val;
pl_parentIndexList[vl_parentListIndex] := i;
pl_indexesInList[vl_indexesInListIndex] := i;
f_EPTF_DsRestAPI_DSServer_sendChildRequests(pl_id, pl_request, pl_parentList, pl_parentIndexList, pl_path, pl_indexesInList);
}
}
}
}
private function f_EPTF_DsRestAPI_DSServer_sendIsWriteableRequest(
in integer pl_id,
in EPTF_DsRestAPI_Request pl_request,
in EPTF_CharstringList pl_parentList,
in EPTF_IntegerList pl_parentIndexList,
in EPTF_IntegerList pl_path,
in EPTF_IntegerList pl_indexesInList
) runs on EPTF_DsRestAPI_DSServer_CT {
var EPTF_DsRestAPI_Request vl_request := pl_request;
f_EPTF_DsRestAPI_DSServer_completeGetDataParameters(vl_request, pl_parentList, pl_parentIndexList);
vl_request := f_EPTF_DsRestAPI_DSServer_createIsWritableRequest(vl_request);
var integer vl_transactionid := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_responseQueue);
f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_responseQueue);
v_DsRestAPI_DSServer_responseHandlerDB[vl_transactionid] := {
requestId := pl_id,
path := pl_path,
indexesInList := pl_indexesInList,
writableInfo := true,
checkPostFilter := false,
parentList := pl_parentList,
parentIndexList := pl_parentIndexList,
storageKey := ""
}
f_EPTF_DsRestAPI_DSServer_handleRequest(vl_request, {vl_transactionid});
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_sendPostFilter
//
// Purpose:
// Sends the post filter to be evaluated.
//
// Parameters:
// pl_transactionid - *in* *integer* -
// Index into responseHandlerDB
// pl_errorCode - *in* *integer* -
// The error code
// pl_parentList - *in* *EPTF_CharstringList* -
// The list of parent responses so we can fill out the %ParentX% parts of the filter.
// pl_parentIndexList - *in* *EPTF_IntegerList* -
// The list of parent indexes so we can fill out the %ParentX::idx% parts of the filter.
// pl_contentToInsert - *in* *EPTF_DsRestAPI_Content* -
// The response to filter and isert later.
// pl_filter - *in* *EPTF_DsRestAPI_Filter* -
// The filter to be evaluated
//
// Return Value:
// -
//
// Detailed Comments:
// We create an entry in filterItemsDB with pl_transactionid index that contains a counter of how many elements are in the response and the response to filter and insert.
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_sendPostFilter(in integer pl_transactionid, in integer pl_errorCode, in EPTF_CharstringList pl_parentList, in EPTF_IntegerList pl_parentIndexList, in EPTF_DsRestAPI_Content pl_contentToInsert, in EPTF_DsRestAPI_Filter pl_filter) runs on EPTF_DsRestAPI_DSServer_CT {
var integer vl_counter;
if (ischosen(pl_contentToInsert.node)) {
vl_counter := 1
} else /*if (ischosen(pl_contentToInsert.list))*/ {
vl_counter := sizeof(pl_contentToInsert.list);
}
v_DsRestAPI_DSServer_filterItemsDB[pl_transactionid] := {postFilterItem := {
errorCode := pl_errorCode,
contentToInsert := pl_contentToInsert,
counter := vl_counter
}};
var integer vl_nextParent := sizeof(pl_parentList);
if (ischosen(pl_contentToInsert.node)) {
pl_parentList[vl_nextParent] := pl_contentToInsert.node.val;
pl_parentIndexList[vl_nextParent] := 0;
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests + 1;
f_EPTF_DsRestAPI_Filter_evaluateFilter({{pl_transactionid}, pl_filter, refers(f_EPTF_DsRestAPI_DSServer_postFilterEvaluated), v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId}, pl_parentList, pl_parentIndexList);
} else /*if (ischosen(pl_contentToInsert.list))*/ {
for (var integer i := 0; i < vl_counter; i := i + 1) {
pl_parentList[vl_nextParent] := pl_contentToInsert.list[i].node.val;
pl_parentIndexList[vl_nextParent] := i;
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId].outstandingRequests + 1;
f_EPTF_DsRestAPI_Filter_evaluateFilter({{pl_transactionid, i}, pl_filter, refers(f_EPTF_DsRestAPI_DSServer_postFilterEvaluated), v_DsRestAPI_DSServer_responseHandlerDB[pl_transactionid].requestId}, pl_parentList, pl_parentIndexList);
}
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests
//
// Purpose:
// Inserts the response into the response tree and sends the child requests.
//
// Parameters:
// pl_transactionid - *in* *integer* -
// Index into responseHandlerDB
// pl_errorCode - *in* *integer* -
// The error code
// pl_requests - *in* *EPTF_DsRestAPI_Requests* -
// The list of requests which will contain the sent request.
// pl_contentList - *inout* *EPTF_DsRestAPI_ContentList* -
// The content list of responses into which the response will be inserted.
// pl_contentToInsert - *in* *EPTF_DsRestAPI_Content* -
// The response to insert.
// pl_responseData - *in* *EPTF_DsRestAPI_ResponseHandlerItem* -
// responseHandlerDB[pl_transactionid]
// pl_nextPathIndex - *in* *integer* -
// The next index into pl_responseData.path for the recursion
// pl_nextIndexesInListIndex - *in* *integer* -
// The next index into a response list for the recursion
//
// Return Value:
// -
//
// Detailed Comments:
// We first recursively find the request and the response list where it should be inserted.
// During the recursion we fill up the parentList and parentIndexList which are later used to complate %ParentX% and %ParentX::idx% parts of child requests.
// Then we handle the insertion:
// - It might be a writable info response, in which case we modify the tp of an already existing response.
// - If we have to apply a postfilter we do so here without inserting the response (it will be inserted after the postfitler is evaluated)
// - Or we insert the response and
// - If we need writable request we send it.
// - Send the child requests
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
in integer pl_transactionid,
in integer pl_errorCode,
in EPTF_DsRestAPI_Requests pl_requests,
inout EPTF_DsRestAPI_ContentList pl_contentList,
in EPTF_DsRestAPI_Content pl_contentToInsert,
in EPTF_DsRestAPI_ResponseHandlerItem pl_responseData,
in integer pl_nextPathIndex,
in integer pl_nextIndexesInListIndex
) runs on EPTF_DsRestAPI_DSServer_CT {
if (pl_nextPathIndex < sizeof(pl_responseData.path) - 1) {
// we must still go down in the tree
if (ischosen(pl_contentList[pl_responseData.path[pl_nextPathIndex]].node)) {
pl_responseData.parentList[sizeof(pl_responseData.parentList)] := pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.val;
pl_responseData.parentIndexList[sizeof(pl_responseData.parentIndexList)] := 0;
if (not ispresent(pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.childVals)) {
pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.childVals := {};
}
f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
pl_transactionid,
pl_errorCode,
pl_requests[pl_responseData.path[pl_nextPathIndex]].getData.children,
pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.childVals,
pl_contentToInsert,
pl_responseData,
pl_nextPathIndex + 1,
pl_nextIndexesInListIndex
);
} else if (ischosen(pl_contentList[pl_responseData.path[pl_nextPathIndex]].list)) {
pl_responseData.parentList[sizeof(pl_responseData.parentList)] := pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.val;
pl_responseData.parentIndexList[sizeof(pl_responseData.parentIndexList)] := pl_responseData.indexesInList[pl_nextIndexesInListIndex];
if (not ispresent(pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.childVals)) {
pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.childVals := {};
}
f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
pl_transactionid,
pl_errorCode,
pl_requests[pl_responseData.path[pl_nextPathIndex]].getData.children,
pl_contentList[pl_responseData.path[pl_nextPathIndex]].list[pl_responseData.indexesInList[pl_nextIndexesInListIndex]].node.childVals,
pl_contentToInsert,
pl_responseData,
pl_nextPathIndex + 1,
pl_nextIndexesInListIndex + 1
);
}
} else {
// we are at the bottom of the tree, we can insert the response
if (pl_responseData.writableInfo and isbound(pl_contentList[pl_responseData.path[pl_nextPathIndex]])) {
// if it was a writeable request we modify the tp if necessary
if (pl_contentToInsert.node.val == "false") {
pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.tp := -1 * pl_contentList[pl_responseData.path[pl_nextPathIndex]].node.tp;
}
f_EPTF_FBQ_moveFromBusyToFreeTail(pl_transactionid, v_DsRestAPI_DSServer_responseQueue);
} else {
// else we insert the response and send its child requests if we do not filter it
if (pl_responseData.path[pl_nextPathIndex] < sizeof(pl_requests)) {
var EPTF_DsRestAPI_Request vl_request := pl_requests[pl_responseData.path[pl_nextPathIndex]];
if (ischosen(vl_request.getData) and ispresent(vl_request.getData.filter) and pl_responseData.checkPostFilter and not ispresent(vl_request.getData.selectionValues) and (ischosen(pl_contentToInsert.node) or (ischosen(pl_contentToInsert.list) and sizeof(pl_contentToInsert.list) > 0))) {
f_EPTF_DsRestAPI_DSServer_sendPostFilter(pl_transactionid, pl_errorCode, pl_responseData.parentList, pl_responseData.parentIndexList, pl_contentToInsert, vl_request.getData.filter);
} else {
pl_contentList[pl_responseData.path[pl_nextPathIndex]] := pl_contentToInsert;
f_EPTF_FBQ_moveFromBusyToFreeTail(pl_transactionid, v_DsRestAPI_DSServer_responseQueue);
// TODO cookie can be inserted here
if (ischosen(pl_contentToInsert.list) or pl_contentToInsert.node.tp != 0) {
if (ischosen(vl_request.getData) and ispresent(vl_request.getData.writableInfo)) {
f_EPTF_DsRestAPI_DSServer_sendIsWriteableRequest(pl_responseData.requestId, vl_request, pl_responseData.parentList, pl_responseData.parentIndexList, pl_responseData.path, pl_responseData.indexesInList);
}
if (ischosen(vl_request.getData) and ispresent(vl_request.getData.children) and pl_errorCode == 0) {
f_EPTF_DsRestAPI_DSServer_prepareAndSendChildRequests(pl_responseData.requestId, vl_request, pl_contentToInsert, pl_responseData.parentList, pl_responseData.parentIndexList, pl_responseData.path, pl_responseData.indexesInList);
}
}
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_responseArrived
//
// Purpose:
// Handle the arrival of a response.
//
// Parameters:
// pl_errorCode - *in* *integer* -
// The error code
// pl_dataValue - *in* *EPTF_Var_DirectContent* -
// The response obtained from DataSource.
// pl_userData - *in* *EPTF_IntegerList* -
// The userdata with the following elements:
// - 0: index into responseHandlerDB
//
// Return Value:
// -
//
// Detailed Comments:
// We store the response in the storage and try to insert the response into the response tree.
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_responseArrived(in integer pl_errorCode, in EPTF_Var_DirectContent pl_dataValue, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
if (f_EPTF_DsRestAPI_DSServer_isOldResponse(pl_userData[0])) {
return;
}
var EPTF_DsRestAPI_Content vl_contentToInsert := f_EPTF_DsRestAPI_DSServer_getContentFromDataValue(pl_dataValue);
if (v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].storageKey != "") {
f_EPTF_DsRestAPI_Storage_storeItem(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].storageKey, pl_dataValue);
}
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList := {};
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentIndexList := {};
f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
pl_userData[0],
pl_errorCode,
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].requests,
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].responses,
vl_contentToInsert,
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]],
0,
0);
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests -1;
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_handleGetDataRequest
//
// Purpose:
// Handle a getData request whose %ParentX% parts are filled in.
//
// Parameters:
// pl_request - *in* *EPTF_DsRestAPI_Request* -
// The request
// pl_userData - *in* *EPTF_IntegerList* -
// The userdata with the following elements:
// - 0: index into responseHandlerDB
//
// Return Value:
// -
//
// Detailed Comments:
// This function handles two things:
// - Handle prefilters:
// - Evaluate simple filters or send filter requests.
// - If filtering was handled and the request is not filterd, handle the request.
// - Handle the request:
// - If selectionValues is present, insert it into the response.
// - Else we handle the request by first checking if it is present in the storage or sending the request to the DataSource
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_handleGetDataRequest(in EPTF_DsRestAPI_GetData pl_getData, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
if (ispresent(pl_getData.filter) and f_EPTF_DsRestAPI_Filter_isPreFilterAllowed(pl_getData.filter, sizeof(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList))) {
if (ischosen(pl_getData.filter.dataValue)) {
if (pl_getData.filter.dataValue != "true" and pl_getData.filter.dataValue != "false") {
f_EPTF_DsRestAPI_Filter_warning("Root filter dataValue should be true or false, it is: " & pl_getData.filter.dataValue);
}
if (pl_getData.filter.dataValue != "true") {
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
f_EPTF_DsRestAPI_DSServer_responseArrived(0, {unknownVal := {omit}}, pl_userData);
return;
}
} else /*if (ischosen(pl_getData.filter.request))*/ {
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]] := {preFilterItem := {requestToSend := pl_getData}};
f_EPTF_DsRestAPI_Filter_evaluateFilter({pl_userData, pl_getData.filter, refers(f_EPTF_DsRestAPI_DSServer_preFilterEvaluated), v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId}, v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList, v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentIndexList);
return;
}
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
}
var integer vl_retVal := 0;
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
if (not ispresent(pl_getData.selectionValues)) {
if (ispresent(pl_getData.timeline)) {
f_EPTF_DsRestAPI_DSServer_createITimelineRequest(pl_getData);
}
if (not ispresent(pl_getData.params)) {
pl_getData.params := {};
}
if (not ispresent(pl_getData.ptcname)) {
pl_getData.ptcname := "";
}
var EPTF_DataSource_Filter vl_filter := {
rangeFilter := pl_getData.rangeFilter
};
var charstring vl_keyOfStorage := f_EPTF_DsRestAPI_Storage_getKey(pl_getData.source, pl_getData.ptcname, pl_getData.element, pl_getData.params, vl_filter);
var EPTF_CLL_DsRestAPI_Storage_Item vl_itemInStorage;
if (f_EPTF_DsRestAPI_Storage_getStoredItem(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, vl_keyOfStorage, vl_itemInStorage)) {
if (ischosen(vl_itemInStorage.content)) {
f_EPTF_DsRestAPI_DSServer_responseArrived(vl_retVal, vl_itemInStorage.content, pl_userData);
} else /*if (ischosen(vl_itemInStorage.preStoredItems))*/ {
f_EPTF_DsRestAPI_Storage_addContentArrivedHandler(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, vl_keyOfStorage, {refers(f_EPTF_DsRestAPI_DSServer_responseArrived), pl_userData});
}
} else {
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].storageKey := vl_keyOfStorage;
f_EPTF_DsRestAPI_Storage_preStoreItem(v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId, vl_keyOfStorage);
vl_retVal := f_EPTF_DataSource_getDataValue_nonblocking(pl_getData.source, pl_getData.ptcname, pl_getData.element, pl_getData.params, vl_filter, {refers(f_EPTF_DsRestAPI_DSServer_responseArrived), pl_userData});
}
} else {
var EPTF_Var_DirectContent vl_content;
vl_content.charstringlistVal := pl_getData.selectionValues;
pl_getData.selection := omit;
f_EPTF_DsRestAPI_DSServer_responseArrived(vl_retVal, vl_content, pl_userData);
}
}
private function f_EPTF_DsRestAPI_DSServer_handleSetDataRequest(in EPTF_DsRestAPI_SetData pl_setData, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
var EPTF_Var_DirectContent vl_dataValue;
if (not ispresent(pl_setData.ptcname)) {
pl_setData.ptcname := "";
}
if (not ispresent(pl_setData.params)) {
pl_setData.params := {};
}
if (not ispresent(pl_setData.indxsInList)) {
pl_setData.indxsInList := {};
}
var integer vl_retVal := f_EPTF_DsRestAPI_DSServer_processSetData(pl_setData, vl_dataValue);
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests + 1;
if (vl_retVal == 0) {
vl_retVal := f_EPTF_DataSource_setDataValue_nonblocking(vl_dataValue, pl_setData.source, pl_setData.ptcname, pl_setData.element, pl_setData.params, pl_setData.indxsInList, {refers(f_EPTF_DsRestAPI_DSServer_responseArrived), pl_userData});
} else {
f_EPTF_DsRestAPI_DSServer_responseArrived(vl_retVal, vl_dataValue, pl_userData);
}
}
private function f_EPTF_DsRestAPI_DSServer_handleRequest(in EPTF_DsRestAPI_Request pl_request, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
if (v_DsRestAPI_DSServer_initialized) {
if (ischosen(pl_request.getData)) {
f_EPTF_DsRestAPI_DSServer_handleGetDataRequest(pl_request.getData, pl_userData);
} else if (ischosen(pl_request.setData)) {
f_EPTF_DsRestAPI_DSServer_handleSetDataRequest(pl_request.setData, pl_userData);
}
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_preFilterEvaluated
//
// Purpose:
// Evaluate request after prefilter was evaluated.
//
// Parameters:
// pl_isFilterTrue - *in* *boolean* -
// The result of the filter
// pl_userData - *in* *EPTF_IntegerList* -
// The userdata with the following elements:
// - 0: index into responseHandlerDB
//
// Return Value:
// -
//
// Detailed Comments:
// This function is called when a filter is evaluated without getting the response to the request which contains the filter (there is no reference to it in the filter; this is called a pre filter).
// The requestToSend is stored in v_DsRestAPI_DSServer_filterItemsDB.
// We reduce the filter of the request to a simple dataValue which will be evaluated by f_EPTF_DsRestAPI_DSServer_handleGetDataRequest.
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_preFilterEvaluated(in boolean pl_isFilterTrue, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
if (f_EPTF_DsRestAPI_DSServer_isOldResponse(pl_userData[0])) {
return;
}
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests - 1;
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].preFilterItem.requestToSend.filter.dataValue := ttcn2string(pl_isFilterTrue);
f_EPTF_DsRestAPI_DSServer_handleGetDataRequest(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].preFilterItem.requestToSend, pl_userData);
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_postFilterEvaluated
//
// Purpose:
// Insert the response once the postfilter was evaluated for the node or every element in a response list.
//
// Parameters:
// pl_isFilterTrue - *in* *boolean* -
// The result of the filter
// pl_userData - *in* *EPTF_IntegerList* -
// The userdata with the following elements:
// - 0: index into responseHandlerDB
// - 1: index into the response list if it is a list
//
// Return Value:
// -
//
// Detailed Comments:
// We keep a count of how many elements in the list was the filter evaluated for, and mark those which were filtered out.
// Once the counter reaches 0, we create a new list from the unfiltered items and insert it into the response tree.
// We use filterItemsDB to store the counter and the contentToInsert which is filtered.
// The same index is used in filterItemsDB and responseHandlerDB
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_postFilterEvaluated(in boolean pl_isFilterTrue, in EPTF_IntegerList pl_userData) runs on EPTF_DsRestAPI_DSServer_CT {
if (f_EPTF_DsRestAPI_DSServer_isOldResponse(pl_userData[0])) {
return;
}
if (not ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem)) {
return;
}
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].outstandingRequests - 1;
v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.counter := v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.counter - 1;
if (not pl_isFilterTrue) {
if (ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list)) {
v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list[pl_userData[1]].node.tp := cg_EPTF_DsRestAPI_DSServer_ConetentToBeDiscardedWhenFiltered;
} else if (ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.node)) {
v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.node := {val := "", tp := 0};
}
}
if (v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.counter <= 0) {
var EPTF_DsRestAPI_Content vl_content;
if (ischosen(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list)) {
vl_content.list := {};
var integer contentListSize := sizeof(v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list);
for (var integer i := 0; i < contentListSize; i := i + 1) {
if (v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list[i].node.tp != cg_EPTF_DsRestAPI_DSServer_ConetentToBeDiscardedWhenFiltered) {
vl_content.list[sizeof(vl_content.list)] := v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert.list[i];
}
}
} else {
vl_content := v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.contentToInsert;
}
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].checkPostFilter := false;
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentList := {};
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].parentIndexList := {};
f_EPTF_DsRestAPI_DSServer_insertResponseIntoTreeAndSendChildRequests(
pl_userData[0],
v_DsRestAPI_DSServer_filterItemsDB[pl_userData[0]].postFilterItem.errorCode,
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].requests,
v_DsRestAPI_DSServer_requestHandlerDB[v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]].requestId].responses,
vl_content,
v_DsRestAPI_DSServer_responseHandlerDB[pl_userData[0]],
0,
0);
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_isOldResponse
//
// Purpose:
// Check if an id is outdated because of a timeout.
//
// Parameters:
// pl_id - *in* *integer* -
// The request id used with requestHandlerDB
//
// Return Value:
// boolean -
// Whether the id is outdated and no more processing should be done in connection with it.
//
// Detailed Comments:
// When timeout occurs, the number of outstanding requests is multiplied by -1. If it is negative, we know it is outdated.
// When a request is outdated we free up its entry in v_DsRestAPI_DSServer_responseHandlerDB.
// In addition, the number of outstanding requests counter is incremented here if it is negative, so when all outstanding requests arrive, we can free up the entry in requestHandlerDB and the storage.
/////////////////////////////////////////////////////////////////////////
private function f_EPTF_DsRestAPI_DSServer_isOldResponse(in integer pl_id) runs on EPTF_DsRestAPI_DSServer_CT return boolean {
var integer vl_requestId := v_DsRestAPI_DSServer_responseHandlerDB[pl_id].requestId;
if (v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests < 0) {
f_EPTF_DsRestAPI_Filter_warning("Dropped response because of timeout for the request: " & v_DsRestAPI_DSServer_responseHandlerDB[pl_id].storageKey);
f_EPTF_FBQ_moveFromBusyToFreeTail(pl_id, v_DsRestAPI_DSServer_responseQueue);
v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests := v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests + 1;
if (v_DsRestAPI_DSServer_requestHandlerDB[vl_requestId].outstandingRequests == 0) {
f_EPTF_FBQ_moveFromBusyToFreeTail(vl_requestId, v_DsRestAPI_DSServer_requestQueue);
f_EPTF_DsRestAPI_Storage_deleteStorage(vl_requestId);
}
return true;
} else {
return false;
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_processRequest
//
// Purpose:
// TTCN API function of DsRestAPI, it can be used to process a request. The function is synchronous.
//
// Parameters:
// pl_request - *in* *EPTF_DsRestAPI_Requests* -
// Accepts a request set organized in a tree.
// This request tree is built out of atomic getData or setData request elements, and their children,
// which are also getData or setData request elements.
// The child request's parameters could depend on the result of its parent requests.
//
// Return Value:
// EPTF_DsRestAPI_ContentList -
// The result is an object, representing the response values, organized also in a tree.
// The structure of the result tree matches the structure of the request tree.
// The elements in the response tree are the resulted values of the getData and setData request elements
// located on the corresponding places of the request tree.
//
// Detailed Comments:
// TTCN requests arrive here.
// We create an entry in requestHandlerDB which will store the request, the response and the number of outstanding requets towards the DataSource.
// For every request in the first level of the request tree, we create an entry in responseHandlerDB, which includes some important members:
// - requestId: the id of the large request used to insert responses and count outstanding requests
// - path: the index of the small request in the large request
// - indexesInList: this together with path helps to create an index into the response tree
// - writableInfo: whether we also check if the element is writable
// - checkPostFilter: this is set to false if the filter gets evaluated
// - parentList: the responses to the parent requests of this request used to fill in %ParentX%
// - parentIndexList: used to fill in %ParentX::idx%
// - storageKey: the hashmap key used for the storage
// Further entries are created when sending child requests or writable info requests.
/////////////////////////////////////////////////////////////////////////
public function f_EPTF_DsRestAPI_DSServer_processRequest(in EPTF_DsRestAPI_Requests pl_requests, in float pl_timeOut := 0.0) runs on EPTF_DsRestAPI_DSServer_CT return EPTF_DsRestAPI_ContentList {
if (v_DsRestAPI_DSServer_initialized) {
var integer vl_id := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_requestQueue);
f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_requestQueue);
f_EPTF_DsRestAPI_Storage_newStorage(vl_id);
v_DsRestAPI_DSServer_requestHandlerDB[vl_id] := {
requests := pl_requests,
responses := {},
outstandingRequests := 0
}
var integer vl_requestsLength := sizeof(pl_requests);
for (var integer i := 0; i < vl_requestsLength; i := i + 1) {
var integer vl_transactionid := f_EPTF_FBQ_getOrCreateFreeSlot(v_DsRestAPI_DSServer_responseQueue);
f_EPTF_FBQ_moveFromFreeHeadToBusyTail(v_DsRestAPI_DSServer_responseQueue);
v_DsRestAPI_DSServer_responseHandlerDB[vl_transactionid] := {
requestId := vl_id,
path := {i},
indexesInList := {},
writableInfo := false,
checkPostFilter := true,
parentList := {},
parentIndexList := {},
storageKey := ""
}
f_EPTF_DsRestAPI_DSServer_handleRequest(pl_requests[i], {vl_transactionid});
}
timer T_dummy;
timer T_max;
T_dummy.start(0.0);
if (pl_timeOut != 0.0) {
T_max.start(pl_timeOut);
}
alt{
[v_DsRestAPI_DSServer_requestHandlerDB[vl_id].outstandingRequests == 0] T_dummy.timeout {
f_EPTF_FBQ_moveFromBusyToFreeTail(vl_id, v_DsRestAPI_DSServer_requestQueue);
f_EPTF_DsRestAPI_Storage_deleteStorage(vl_id);
}
[] T_max.timeout {
v_DsRestAPI_DSServer_requestHandlerDB[vl_id].responses := {
{
node := {
val := "timeout",
tp := 4
}
}
};
v_DsRestAPI_DSServer_requestHandlerDB[vl_id].requests := {};
v_DsRestAPI_DSServer_requestHandlerDB[vl_id].outstandingRequests := -v_DsRestAPI_DSServer_requestHandlerDB[vl_id].outstandingRequests;
}
};
return v_DsRestAPI_DSServer_requestHandlerDB[vl_id].responses;
} else {
return {};
}
}
/////////////////////////////////////////////////////////////////////////
// Function: f_EPTF_DsRestAPI_DSServer_processJSONRequest
//
// Purpose:
// TTCN API function of DsRestAPI, it can be used to process a JSON request. The function is synchronous.
// See *f_EPTF_DsRestAPI_DSServer_processRequest*
//
// Parameters:
// pl_request - *in* *octetstring* - JSON encoded request. Octetstrings can be converted from chastrings via char2oct.
//
// Return Value:
// octetstring - the result is also a JSON encoded object, representing the response values. Resulted octetstring can be converted to charstring via oct2char.
//
// Detailed Comments:
// Encoded json requests arrive here from http server.
// We simply decode it and call f_EPTF_DsRestAPI_DSServer_processRequest.
/////////////////////////////////////////////////////////////////////////
public function f_EPTF_DsRestAPI_DSServer_processJSONRequest(in octetstring pl_request) runs on EPTF_DsRestAPI_DSServer_CT return octetstring {
if (v_DsRestAPI_DSServer_initialized) {
var octetstring vl_result := ''O;
if (lengthof(pl_request) > 0) {
@try {
var EPTF_DsRestAPI_RqWrapper vl_requesWrapper := ef_DsRestAPI_dec_Requests(pl_request);
var float vl_timeOut := 0.0;
if (ispresent(vl_requesWrapper.timeOut)) {
vl_timeOut := vl_requesWrapper.timeOut;
}
var EPTF_DsRestAPI_ContentList vl_response := f_EPTF_DsRestAPI_DSServer_processRequest(vl_requesWrapper.requests, vl_timeOut);
vl_result := ef_DsRestAPI_enc_ContentList({vl_response});
} @catch(dte_str) {
var charstring vl_searchStr := "Dynamic test case error:";
var charstring vl_dteErrorMsg := "";
var integer vl_strPos := f_strstr(dte_str, vl_searchStr);
var integer vl_lenSearchStr := lengthof(vl_searchStr);
if (vl_strPos != -1) {
vl_dteErrorMsg := substr(dte_str, vl_strPos+vl_lenSearchStr+1, lengthof(dte_str)-vl_strPos-vl_lenSearchStr-1);
} else {
vl_dteErrorMsg := substr(dte_str, 0, lengthof(dte_str)-1);
}
var EPTF_DsRestAPI_ContentAndChildrenListWrapper vl_InvalidRequest := cg_EPTF_DsRestAPI_DSServer_Error_InvalidRequest;
vl_InvalidRequest.contentList[0].node.val := vl_InvalidRequest.contentList[0].node.val & ", Reason: " & vl_dteErrorMsg;
vl_result := ef_DsRestAPI_enc_ContentList(vl_InvalidRequest);
action("DTE", vl_dteErrorMsg);
}
}
return vl_result;
} else {
return ef_DsRestAPI_enc_ContentList(cg_EPTF_DsRestAPI_DSServer_Error_Uninitialized);
}
}
} // ~ module EPTF_CLL_DsRestAPI_DSServer_Functions