| /////////////////////////////////////////////////////////////////////////////// |
| // // |
| // 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 |