Added timer data collection using SRP_Stopwatch to each verb method. Logging all time metrics
381 lines
17 KiB
Plaintext
381 lines
17 KiB
Plaintext
Function Scan_API(@API)
|
|
/***********************************************************************************************************************
|
|
|
|
This program is proprietary and is not to be used by or disclosed to others, nor is it to be copied without written
|
|
permission from SRP Computer Solutions, Inc.
|
|
|
|
Name : Scan_API
|
|
|
|
Description : API logic for the Scan resource.
|
|
|
|
Notes : All web APIs should include the API_SETUP insert. This will provide several useful variables:
|
|
|
|
HTTPMethod - The HTTP Method (Verb) submitted by the client (e.g., GET, POST, etc.)
|
|
APIURL - The URL for the API entry point (e.g., api.mysite.com/v1).
|
|
FullEndpointURL - The URL submitted by the client, including query params.
|
|
FullEndpointURLNoQuery - The URL submitted by the client, excluding query params.
|
|
ParentURL - The URL path preceeding the current endpoint.
|
|
CurrentAPI - The name of this stored procedure.
|
|
|
|
Parameters :
|
|
API [in] -- Web API to process. Format is [APIPattern].[HTTPMethod]:
|
|
- APIPattern must follow this structure Scan[.ID.[<Property>]]
|
|
- HTTPMethod can be any valid HTTP method, e.g., GET, POST, PUT, DELETE, etc.
|
|
Examples:
|
|
- Scan.POST
|
|
- Scan.ID.PUT
|
|
- Scan.ID.firstName.GET
|
|
Response [out] -- Response to be sent back to the Controller (HTTP_MCP) or requesting procedure. Web API
|
|
services do not rely upon anything being returned in the response. This is what the
|
|
various services like SetResponseBody and SetResponseStatus services are for. A response
|
|
value is only helpful if the developers want to use it for debug purposes.
|
|
|
|
History : (Date, Initials, Notes)
|
|
07/30/19 xxx Original programmer.
|
|
|
|
***********************************************************************************************************************/
|
|
|
|
#pragma precomp SRP_PreCompiler
|
|
|
|
$insert APP_INSERTS
|
|
$insert API_SETUP
|
|
$insert HTTP_INSERTS
|
|
$insert SCANS_EQUATES
|
|
$insert RDS_EQUATES
|
|
$insert SCAN_SETUP
|
|
|
|
Declare Function Scan_Services, Database_Services, QA_Services, Datetime, RDS_Services, SRP_Array, SRP_Stopwatch
|
|
Declare function Logging_Services, Environment_Services
|
|
Declare Subroutine Scan_Services, Database_Services, QA_Services, obj_WO_Mat_Log, SRP_Stopwatch
|
|
Declare Subroutine Logging_Services
|
|
|
|
LogPath = Environment_Services('GetApplicationRootPath') : '\LogFiles\ScanAPI\APIResponseTime'; //Define the directory where the log will be saved to. This happens the first time of the day that the log is written to.
|
|
LogDate = Oconv(Date(), 'D4/')
|
|
LogTime = Oconv(Time(), 'MTS')
|
|
LoggingDTM = LogDate : ' ' : LogTime ; // Logging DTM
|
|
|
|
LogFileName = LogDate[7, 4] : '-' : LogDate[1, 2] : '-' : LogDate[4, 2] : ' ScanAPIResponseTimes.csv'; //Define the file name that will get created.
|
|
Headers = 'Logging DTM' : @FM : 'API' : @FM : 'ResponseTime' : @FM : 'ScanID' : @FM : 'ScanData' : @VM : 'StatusCode' ; //Define the column names in the log file, delimited by a Field Mark.
|
|
objLog = Logging_Services('NewLog', LogPath, LogFileName, CRLF$, ',', Headers, '', False$, False$); //Actually creates the log.
|
|
|
|
GoToAPI else
|
|
// The specific resource endpoint doesn't have a API handler yet.
|
|
HTTP_Services('SetResponseStatus', 200, 'This is a valid endpoint but a web API handler has not yet been created.')
|
|
end
|
|
|
|
Return Response OR ''
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Endpoint Handlers
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
API scan.POST
|
|
SRP_Stopwatch('Reset')
|
|
SRP_Stopwatch('Start', 'SCAN_POST_RESPONSE_TIME')
|
|
ScanID = Scan_Services('CreateScansRow')
|
|
If Error_Services('NoError') then
|
|
StatusCode = 201
|
|
GoSub CreateHALItem
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 500, Message)
|
|
end
|
|
SRP_Stopwatch('Stop', 'SCAN_POST_RESPONSE_TIME')
|
|
TotalPostResponseTime = SRP_Stopwatch('GetData', 'SCAN_POST_RESPONSE_TIME')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM;//Defined at entry of subroutine
|
|
LogData<2> = 'SCAN.POST'
|
|
LogData<3> = TotalPostResponseTime
|
|
LogData<4> = ScanID
|
|
LogData<5> = ''
|
|
ResponseStatusCode = ''
|
|
If Assigned(StatusCode) then
|
|
ResponseStatusCode = StatusCode
|
|
end
|
|
LogData<6> = ResponseStatusCode
|
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
|
end api
|
|
|
|
|
|
API scan.ID.POST
|
|
SRP_Stopwatch('Reset')
|
|
SRP_Stopwatch('Start', 'SCAN_ID_POST_RESPONSE_TIME')
|
|
ScanID = EndpointSegment
|
|
// The resource will have been put into the POST string.
|
|
Body = HTTP_Services('GetHTTPPostString')
|
|
If Body NE '' then
|
|
// The POST string will have been encoded so use percent (URL) decoding.
|
|
ScanJSON = HTTP_Services('DecodePercentString', Body)
|
|
Scan_Services('ProcessScanData', ScanID, ScanJSON)
|
|
If Error_Services('NoError') then
|
|
StatusCode = 200
|
|
GoSub CreateHALItem
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 400, Message)
|
|
end
|
|
end else
|
|
HTTP_Services('SetResponseStatus', 400, 'JSON object is missing from the request.')
|
|
end
|
|
SRP_Stopwatch('Stop', 'SCAN_ID_POST_RESPONSE_TIME')
|
|
TotalPostResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_POST_RESPONSE_TIME')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM;//Defined at entry of subroutine
|
|
LogData<2> = 'SCAN.ID.POST'
|
|
LogData<3> = TotalPostResponseTime
|
|
LogData<4> = ScanID
|
|
If Assigned(ScanJson) then
|
|
ThisScanDataToLog = ScanJson
|
|
end else
|
|
ThisScanDataToLog = Body
|
|
end
|
|
LogData<5> = ThisScanDataToLog
|
|
ResponseStatusCode = ''
|
|
If Assigned(StatusCode) then
|
|
ResponseStatusCode = StatusCode
|
|
end
|
|
LogData<6> = ResponseStatusCode
|
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
|
end api
|
|
|
|
|
|
API scan.ID.HEAD
|
|
API scan.ID.GET
|
|
SRP_Stopwatch('Reset')
|
|
SRP_Stopwatch('Start', 'SCAN_ID_GET_RESPONSE_TIME')
|
|
ScanID = EndpointSegment
|
|
StatusCode = 200
|
|
GoSub CreateHALItem
|
|
SRP_Stopwatch('Stop', 'SCAN_ID_POST_RESPONSE_TIME')
|
|
TotalGetResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_GET_RESPONSE_TIME')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM;//Defined at entry of subroutine
|
|
LogData<2> = 'SCAN.ID.GET'
|
|
LogData<3> = TotalGetResponseTime
|
|
LogData<4> = ScanID
|
|
LogData<5> = ''
|
|
ResponseStatusCode = ''
|
|
If Assigned(StatusCode) then
|
|
ResponseStatusCode = StatusCode
|
|
end
|
|
LogData<6> = ResponseStatusCode
|
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
|
end api
|
|
|
|
|
|
API scan.ID.DELETE
|
|
SRP_Stopwatch('Reset')
|
|
SRP_Stopwatch('Start', 'SCAN_ID_DELETE_RESPONSE_TIME')
|
|
ScanID = EndpointSegment
|
|
|
|
ScanRow = Database_Services('ReadDataRow', 'SCANS', ScanID)
|
|
If Error_Services('NoError') then
|
|
If ScanRow<SCANS.ACCEPTED$> NE True$ then
|
|
Database_Services('DeleteDataRow', 'SCANS', ScanID, True$, False$)
|
|
If Error_Services('NoError') then
|
|
HTTP_Services('SetResponseStatus', 200)
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 500, Message)
|
|
end
|
|
end else
|
|
HTTP_Services('SetResponseStatus', 403, 'This scan is already accepted and cannot be deleted.')
|
|
end
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 404, Message)
|
|
end
|
|
SRP_Stopwatch('Stop', 'SCAN_ID_DELETE_RESPONSE_TIME')
|
|
TotalDeleteResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_DELETE_RESPONSE_TIME')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM;//Defined at entry of subroutine
|
|
LogData<2> = 'SCAN.ID.DELETE'
|
|
LogData<3> = TotalDeleteResponseTime
|
|
LogData<4> = ScanID
|
|
LogData<5> = ''
|
|
ResponseStatusCode = ''
|
|
If Assigned(StatusCode) then
|
|
ResponseStatusCode = StatusCode
|
|
end
|
|
LogData<6> = ResponseStatusCode
|
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
|
end api
|
|
|
|
|
|
API scan.ID.PATCH
|
|
|
|
// This is where scans are ultimately accepted for final processing. We will need to determine which type
|
|
// of scan this is (i.e. Location, Pre-Epi + Load, or Unload). This will be determined by the data coming in and the
|
|
// current status of the lot. For example a Location scan would only have an RDS, location code, and username.
|
|
SRP_Stopwatch('Reset')
|
|
SRP_Stopwatch('Start', 'SCAN_ID_PATCH_RESPONSE_TIME')
|
|
|
|
ScanID = EndpointSegment
|
|
SRP_Stopwatch('Start', 'IDPatchResponseTime')
|
|
// First confirm that this is a valid Scan ID.
|
|
jsonScan = Scan_Services('GetScansRow', ScanID, True$)
|
|
If Error_Services('NoError') then
|
|
// Confirm that all required data has been scanned before allowing the "accept" field to be updated.
|
|
ParseResponse = SRP_JSON(objResource, 'Parse', jsonScan)
|
|
If ParseResponse EQ '' then
|
|
ScanAcceptable = SRP_JSON(objResource, 'GetValue', 'scan.acceptable', False$)
|
|
If ScanAcceptable EQ True$ then
|
|
// The resource will have been put into the POST string.
|
|
Body = HTTP_Services('GetHTTPPostString')
|
|
If Body NE '' then
|
|
// The POST string will have been encoded so use percent (URL) decoding.
|
|
ScanJSON = HTTP_Services('DecodePercentString', Body)
|
|
Scan_Services('AcceptScan', ScanID, ScanJSON)
|
|
|
|
If Error_Services('NoError') then
|
|
StatusCode = 200
|
|
GoSub CreateHALItem
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 500, Message)
|
|
end
|
|
|
|
SRP_JSON(hBody, 'Release')
|
|
end else
|
|
HTTP_Services('SetResponseStatus', 400, 'JSON object is missing from the request.')
|
|
end
|
|
end else
|
|
ScanNotAcceptableReason = SRP_JSON(objResource, 'GetValue', 'scan.notAcceptableReason')
|
|
Error_Services('Add', ScanNotAcceptableReason)
|
|
end
|
|
SRP_JSON(objResource, 'Release')
|
|
end else
|
|
Message = 'Unable to parse the JSON scan resource.'
|
|
HTTP_Services('SetResponseStatus', 400, Message)
|
|
end
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 404, Message)
|
|
end
|
|
SRP_Stopwatch('Stop', 'SCAN_ID_PATCH_RESPONSE_TIME')
|
|
TotalPatchResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_PATCH_RESPONSE_TIME')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM;//Defined at entry of subroutine
|
|
LogData<2> = 'SCAN.ID.PATCH'
|
|
LogData<3> = TotalPatchResponseTime
|
|
LogData<4> = ScanID
|
|
LogData<5> = ''
|
|
ResponseStatusCode = ''
|
|
If Assigned(StatusCode) then
|
|
ResponseStatusCode = StatusCode
|
|
end
|
|
LogData<6> = ResponseStatusCode
|
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
|
end api
|
|
|
|
|
|
API scan.ID.PUT
|
|
|
|
SRP_Stopwatch('Reset')
|
|
SRP_Stopwatch('Start', 'SCAN_ID_PUT_RESPONSE_TIME')
|
|
ScanID = EndpointSegment
|
|
|
|
// The resource will have been put into the POST string.
|
|
Body = HTTP_Services('GetHTTPPostString')
|
|
If Body NE '' then
|
|
// The POST string will have been encoded so use percent (URL) decoding.
|
|
Body = HTTP_Services('DecodePercentString', Body)
|
|
ParseResponse = SRP_JSON(hBody, 'PARSE', Body)
|
|
If (ParseResponse EQ '') then
|
|
ScanRow = Database_Services('ReadDataRow', 'SCANS', ScanID)
|
|
If Error_Services('NoError') then
|
|
// Existing scan resource is being replaced.
|
|
StatusCode = 200
|
|
end else
|
|
// Scan resource is being created for the first time.
|
|
StatusCode = 201
|
|
end
|
|
If ScanRow<SCANS.CREATED_DATE$> EQ '' then ScanRow<SCANS.CREATED_DATE$> = Date()
|
|
If ScanRow<SCANS.CREATED_TIME$> EQ '' then ScanRow<SCANS.CREATED_TIME$> = Time()
|
|
ScanRow<SCANS.EMPLOYEE_ID$> = SRP_JSON(hBody, 'GetValue', 'employeeID', '')
|
|
ScanRow<SCANS.TOOL_ID$> = SRP_JSON(hBody, 'GetValue', 'toolID', '')
|
|
ScanRow<SCANS.CASSETTE_IDS$> = SRP_JSON(hBody, 'GetValue', 'cassetteID', '')
|
|
Accept = SRP_JSON(hBody, 'GetValue', 'accept', False$)
|
|
If Accept EQ True$ then
|
|
// Before allowing the accept field to be set to True, verify that all required data has been populated.
|
|
Begin Case
|
|
Case ScanRow<SCANS.EMPLOYEE_ID$> EQ '' ; Accept = False$
|
|
Case ScanRow<SCANS.TOOL_ID$> EQ '' ; Accept = False$
|
|
Case ScanRow<SCANS.CASSETTE_IDS$> EQ '' ; Accept = False$
|
|
End Case
|
|
end
|
|
ScanRow<SCANS.ACCEPTED$> = Accept
|
|
If ScanRow<SCANS.ACCEPTED$> EQ True$ then
|
|
ScanRow<SCANS.ACCEPTED_DATE$> = Date()
|
|
ScanRow<SCANS.ACCEPTED_TIME$> = Time()
|
|
end
|
|
Database_Services('WriteDataRow', 'SCANS', ScanID, ScanRow, True$, False$, True$)
|
|
If Error_Services('NoError') then
|
|
GoSub CreateHALItem
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 500, Message)
|
|
end
|
|
SRP_JSON(hBody, 'Release')
|
|
end else
|
|
HTTP_Services('SetResponseStatus', 400, 'Unable to parse the scanData JSON.')
|
|
end
|
|
end else
|
|
HTTP_Services('SetResponseStatus', 400, 'JSON object is missing from the request.')
|
|
end
|
|
SRP_Stopwatch('Stop', 'SCAN_ID_PUT_RESPONSE_TIME')
|
|
TotalPutResponseTime = SRP_Stopwatch('GetData', 'SCAN_ID_PUT_RESPONSE_TIME')
|
|
LogData = ''
|
|
LogData<1> = LoggingDTM;//Defined at entry of subroutine
|
|
LogData<2> = 'SCAN.ID.PUT'
|
|
LogData<3> = TotalPutResponseTime
|
|
LogData<4> = ScanID
|
|
LogData<5> = ''
|
|
ResponseStatusCode = ''
|
|
If Assigned(StatusCode) then
|
|
ResponseStatusCode = StatusCode
|
|
end
|
|
LogData<6> = ResponseStatusCode
|
|
Logging_Services('AppendLog', objLog, LogData, @RM, @FM, False$)
|
|
|
|
end api
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Internal GoSubs
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
// CreateHALItem
|
|
//
|
|
// Creates a HAL+JSON object based on the OpenInsight data row representation of the scan.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
CreateHALItem:
|
|
|
|
jsonScan = Scan_Services('ConvertMVScanToJSON', ScanID, '', FullEndpointURL)
|
|
|
|
If Error_Services('NoError') then
|
|
If SRP_JSON(objResource, 'Parse', jsonScan) EQ '' then
|
|
lastModified = SRP_JSON(objResource, 'GetValue', 'lastModified')
|
|
end else
|
|
lastModified = ''
|
|
end
|
|
SRP_JSON(objResource, 'Release')
|
|
HTTP_Services('SetResponseHeaderField', 'Content-Location', FullEndpointURL)
|
|
HTTP_Services('SetResponseHeaderField', 'Last-Modified', lastModified)
|
|
HTTP_Services('SetResponseBody', jsonScan, False$, 'application/hal+json')
|
|
If Assigned(Message) then
|
|
HTTP_Services('SetResponseStatus', StatusCode, Message)
|
|
end else
|
|
HTTP_Services('SetResponseStatus', StatusCode)
|
|
end
|
|
end else
|
|
Message = Error_Services('GetMessage')
|
|
HTTP_Services('SetResponseStatus', 500, 'Error in the ' : CurrentAPI : ' API. Message: ': Message)
|
|
end
|
|
|
|
return
|