diff --git a/source/Stargate-API-Skeleton-Tests/StargateApplicationTest.class.st b/source/Stargate-API-Skeleton-Tests/StargateApplicationTest.class.st index 7807248..dfefba4 100644 --- a/source/Stargate-API-Skeleton-Tests/StargateApplicationTest.class.st +++ b/source/Stargate-API-Skeleton-Tests/StargateApplicationTest.class.st @@ -9,8 +9,8 @@ Class { 'application', 'port', 'baseUrl', - 'logServerEvents', - 'logClientEvents' + 'logIncomingHTTPRequests', + 'logOutgoingHTTPRequests' ], #category : #'Stargate-API-Skeleton-Tests' } @@ -68,8 +68,8 @@ StargateApplicationTest >> setUp [ port := self freeListeningTCPPort. StargateApplication logsDirectory ensureCreateDirectory. - logServerEvents := false. - logClientEvents := false. + logIncomingHTTPRequests := false. + logOutgoingHTTPRequests := false. ] { #category : #private } @@ -95,13 +95,16 @@ StargateApplicationTest >> start: aLaunchpadApplication withAll: arguments [ { #category : #private } StargateApplicationTest >> startPetStore [ - self start: PetStoreApplication withAll: { - '--pet-store.stargate.public-url=http://localhost:<1p>' expandMacrosWith: port. - '--pet-store.stargate.port=<1p>' expandMacrosWith: port. - '--pet-store.stargate.operations-secret=<1s>' expandMacrosWith: self secret. - '--pet-store.stargate.log-server-events=<1p>' expandMacrosWith: logServerEvents . - '--pet-store.stargate.log-client-events=<1p>' expandMacrosWith: logClientEvents - }. + self start: PetStoreApplication withAll: { + ('--pet-store.stargate.public-url=http://localhost:<1p>' + expandMacrosWith: port). + ('--pet-store.stargate.port=<1p>' expandMacrosWith: port). + ('--pet-store.stargate.operations-secret=<1s>' expandMacrosWith: + self secret). + ('--pet-store.stargate.log-incoming-http-requests=<1p>' + expandMacrosWith: logIncomingHTTPRequests). + ('--pet-store.stargate.log-outgoing-http-requests=<1p>' + expandMacrosWith: logOutgoingHTTPRequests) }. baseUrl := application configuration petStore stargate publicURL ] @@ -246,7 +249,7 @@ StargateApplicationTest >> testLogClientEventsDuringSucessfulGet [ | logRecord | logger runDuring: [ - logClientEvents := true. + logOutgoingHTTPRequests := true. self testGetPets]. logRecord := NeoJSONObject fromString: @@ -254,17 +257,13 @@ StargateApplicationTest >> testLogClientEventsDuringSucessfulGet [ self assert: logRecord level equals: 'DEBUG'; - assert: logRecord message equals: 'HTTP Client event received'; + assert: logRecord message equals: 'Outgoing HTTP request responded'; assert: #( 'Morphic UI Process' 'CommandLine handler process' ) includes: logRecord process; assert: ( logRecord summary includesSubstring: 'GET /pets 200 59B' ); assert: logRecord request method equals: 'GET'; assert: logRecord request uri equals: ( 'http://localhost:<1p>/pets' expandMacrosWith: port ); - assert: logRecord request headers size equals: 4; assert: logRecord response code equals: 200; - assert: logRecord response totalSize equals: 59; - assert: logRecord response content - equals: ( '{"items":[],"links":{"self":"http://localhost:<1p>/pets"}}' expandMacrosWith: port ); - assert: logRecord response headers size equals: 8 + assert: logRecord response totalSize equals: 59 ] @@ -274,7 +273,7 @@ StargateApplicationTest >> testLogClientEventsDuringUnsucessfulPost [ | logRecord | logger runDuring: [ - logClientEvents := true. + logOutgoingHTTPRequests := true. self testUnsupportedMediaType]. logRecord := NeoJSONObject fromString: @@ -282,17 +281,13 @@ StargateApplicationTest >> testLogClientEventsDuringUnsucessfulPost [ self assert: logRecord level equals: 'DEBUG'; - assert: logRecord message equals: 'HTTP Client event received'; + assert: logRecord message equals: 'Outgoing HTTP request responded'; assert: #( 'Morphic UI Process' 'CommandLine handler process' ) includes: logRecord process; assert: (logRecord summary includesSubstring: 'POST /pets 415 72B'); assert: logRecord request method equals: 'POST'; assert: logRecord request uri equals: ( 'http://localhost:<1p>/pets' expandMacrosWith: port ); - assert: logRecord request headers size equals: 6; assert: logRecord response code equals: 415; - assert: logRecord response totalSize equals: 72; - assert: (NeoJSONObject fromString: logRecord response content) - equals: (NeoJSONObject fromString:'{ "message" : "Decoder not found for given media type", "code" : 415 }'); - assert: logRecord response headers size equals: 6 + assert: logRecord response totalSize equals: 72 ] @@ -300,56 +295,52 @@ StargateApplicationTest >> testLogClientEventsDuringUnsucessfulPost [ StargateApplicationTest >> testLogServerEventsDuringSucessfulGet [ | logRecord | - - logger runDuring: [ - logServerEvents := true. + logger runDuring: [ + logIncomingHTTPRequests := true. self testGetPets ]. - - logRecord := NeoJSONObject fromString: - ( String streamContents: [:stream | logger recordings last printOneLineJsonOn: stream ] ). - + + logRecord := NeoJSONObject fromString: + (String streamContents: [ :stream | + (logger recordings at: logger recordings size - 1) + printOneLineJsonOn: stream ]). + self - assert: logRecord level equals: 'DEBUG'; - assert: logRecord message equals: 'HTTP Server event received'; - assert: logRecord process equals: 'ZnManagingMultiThreadedServer HTTP worker'; - assert: (logRecord summary includesSubstring: 'GET /pets 200 59B'); + assert: logRecord level equals: 'DEBUG'; + assert: logRecord message equals: 'Incoming HTTP request responded'; + assert: logRecord process + equals: 'ZnManagingMultiThreadedServer HTTP worker'; + assert: (logRecord summary includesSubstring: 'GET /pets'); assert: logRecord request method equals: 'GET'; - assert: logRecord request uri equals: ( 'http://localhost:<1p>/pets' expandMacrosWith: port ); - assert: logRecord request headers size equals: 6; + assert: logRecord request uri + equals: ('http://localhost:<1p>/pets' expandMacrosWith: port); assert: logRecord response code equals: 200; - assert: logRecord response totalSize equals: 59; - assert: logRecord response content - equals: ( '{"items":[],"links":{"self":"http://localhost:<1p>/pets"}}' expandMacrosWith: port ); - assert: logRecord response headers size equals: 8 - + assert: logRecord response totalSize equals: 59 ] { #category : #'tests - logs' } StargateApplicationTest >> testLogServerEventsDuringUnsucessfulPost [ | logRecord | - - logger runDuring: [ - logServerEvents := true. + logger runDuring: [ + logIncomingHTTPRequests := true. self testUnsupportedMediaType ]. - - logRecord := NeoJSONObject fromString: - ( String streamContents: [:stream | logger recordings last printOneLineJsonOn: stream ] ). - + + logRecord := NeoJSONObject fromString: + (String streamContents: [ :stream | + (logger recordings at: logger recordings size - 1) + printOneLineJsonOn: stream ]). + self - assert: logRecord level equals: 'DEBUG'; - assert: logRecord message equals: 'HTTP Server event received'; - assert: logRecord process equals: 'ZnManagingMultiThreadedServer HTTP worker'; - assert: (logRecord summary includesSubstring: 'POST /pets 415 72B'); + assert: logRecord level equals: 'DEBUG'; + assert: logRecord message equals: 'Incoming HTTP request responded'; + assert: logRecord process + equals: 'ZnManagingMultiThreadedServer HTTP worker'; + assert: (logRecord summary includesSubstring: 'POST /pets'); assert: logRecord request method equals: 'POST'; - assert: logRecord request uri equals: ( 'http://localhost:<1p>/pets' expandMacrosWith: port ); - assert: logRecord request headers size equals: 8; + assert: logRecord request uri + equals: ('http://localhost:<1p>/pets' expandMacrosWith: port); assert: logRecord response code equals: 415; - assert: logRecord response totalSize equals: 72; - assert: (NeoJSONObject fromString: logRecord response content) - equals: (NeoJSONObject fromString:'{ "message" : "Decoder not found for given media type", "code" : 415 }'); - assert: logRecord response headers size equals: 6 - + assert: logRecord response totalSize equals: 72 ] { #category : #'tests - api' } @@ -408,7 +399,7 @@ StargateApplicationTest >> testPrintHelpOn [ self assert: help equals: ('NAME pet-store [<1s>] - A RESTful API for Pet stores SYNOPSYS - pet-store --pet-store.stargate.public-url=% --pet-store.stargate.port=% --pet-store.stargate.operations-secret=% [--pet-store.stargate.log-server-events=%] [--pet-store.stargate.log-client-events=%] + pet-store --pet-store.stargate.public-url=% --pet-store.stargate.port=% --pet-store.stargate.operations-secret=% [--pet-store.stargate.log-incoming-http-requests=%] [--pet-store.stargate.log-outgoing-http-requests=%] PARAMETERS --pet-store.stargate.public-url=% Public URL where the API is deployed. Used to create hypermedia links. @@ -416,10 +407,10 @@ PARAMETERS Listening port. --pet-store.stargate.operations-secret=% Secret key for checking JWT signatures. - --pet-store.stargate.log-server-events=% - Boolean that indicates whether to log all the HTTP Server requests. Defaults to false. - --pet-store.stargate.log-client-events=% - Boolean that indicates whether to log all the HTTP Clients requests. Defaults to false. + --pet-store.stargate.log-incoming-http-requests=% + Boolean that indicates whether to log all the Incoming HTTP Requests. Defaults to false. + --pet-store.stargate.log-outgoing-http-requests=% + Boolean that indicates whether to log all the Outgoing HTTP Requests. Defaults to false. ENVIRONMENT PET_STORE__STARGATE__PUBLIC_URL Public URL where the API is deployed. Used to create hypermedia links. @@ -427,10 +418,10 @@ ENVIRONMENT Listening port. PET_STORE__STARGATE__OPERATIONS_SECRET Secret key for checking JWT signatures. - PET_STORE__STARGATE__LOG_SERVER_EVENTS - Boolean that indicates whether to log all the HTTP Server requests. Defaults to false. - PET_STORE__STARGATE__LOG_CLIENT_EVENTS - Boolean that indicates whether to log all the HTTP Clients requests. Defaults to false. + PET_STORE__STARGATE__LOG_INCOMING_HTTP_REQUESTS + Boolean that indicates whether to log all the Incoming HTTP Requests. Defaults to false. + PET_STORE__STARGATE__LOG_OUTGOING_HTTP_REQUESTS + Boolean that indicates whether to log all the Outgoing HTTP Requests. Defaults to false. ' expandMacrosWith: PetStoreApplication version) ] diff --git a/source/Stargate-API-Skeleton/StargateApplication.class.st b/source/Stargate-API-Skeleton/StargateApplication.class.st index 01d6f83..06e22ee 100644 --- a/source/Stargate-API-Skeleton/StargateApplication.class.st +++ b/source/Stargate-API-Skeleton/StargateApplication.class.st @@ -2,7 +2,8 @@ Class { #name : #StargateApplication, #superclass : #LaunchpadApplication, #instVars : [ - 'apiOptional' + 'apiOptional', + 'znEventToLogRecordAdapter' ], #classInstVars : [ 'Version' @@ -58,30 +59,36 @@ StargateApplication class >> sectionsForStargateConfiguration [ StargateApplication class >> stargateConfigurationParameters [ ^ OrderedCollection new - add: ( MandatoryConfigurationParameter named: 'Public URL' - describedBy: 'Public URL where the API is deployed. Used to create hypermedia links' - inside: self sectionsForStargateConfiguration - convertingWith: #asUrl ); - add: ( MandatoryConfigurationParameter named: 'Port' - describedBy: 'Listening port' - inside: self sectionsForStargateConfiguration - convertingWith: #asNumber ); - add: ( MandatoryConfigurationParameter named: 'Operations Secret' - describedBy: 'Secret key for checking JWT signatures' - inside: self sectionsForStargateConfiguration - convertingWith: #asByteArray ) asSensitive; - add: ( OptionalConfigurationParameter - named: 'Log server events' - describedBy: 'Boolean that indicates whether to log all the HTTP Server requests' - inside: self sectionsForStargateConfiguration - defaultingTo: false - convertingWith: [ :value | value = 'true' ] ); - add: ( OptionalConfigurationParameter - named: 'Log client events' - describedBy: 'Boolean that indicates whether to log all the HTTP Clients requests' - inside: self sectionsForStargateConfiguration - defaultingTo: false - convertingWith: [ :value | value = 'true' ] ); + add: (MandatoryConfigurationParameter + named: 'Public URL' + describedBy: + 'Public URL where the API is deployed. Used to create hypermedia links' + inside: self sectionsForStargateConfiguration + convertingWith: #asUrl); + add: (MandatoryConfigurationParameter + named: 'Port' + describedBy: 'Listening port' + inside: self sectionsForStargateConfiguration + convertingWith: #asNumber); + add: (MandatoryConfigurationParameter + named: 'Operations Secret' + describedBy: 'Secret key for checking JWT signatures' + inside: self sectionsForStargateConfiguration + convertingWith: #asByteArray) asSensitive; + add: (OptionalConfigurationParameter + named: 'Log Incoming HTTP Requests' + describedBy: + 'Boolean that indicates whether to log all the Incoming HTTP Requests' + inside: self sectionsForStargateConfiguration + defaultingTo: false + convertingWith: [ :value | value = 'true' ]); + add: (OptionalConfigurationParameter + named: 'Log Outgoing HTTP Requests' + describedBy: + 'Boolean that indicates whether to log all the Outgoing HTTP Requests' + inside: self sectionsForStargateConfiguration + defaultingTo: false + convertingWith: [ :value | value = 'true' ]); yourself ] @@ -147,9 +154,7 @@ StargateApplication >> basicStartWithin: context [ | api | self logAPIVersion. - self - configureHTTPClientLogging; - configureHTTPServerLogging. + self configureHTTPRequestsLogging. api := self createAPI. self configureGlobalErrorHandlerIn: api; @@ -162,6 +167,7 @@ StargateApplication >> basicStop [ apiOptional withContentDo: [ :api | api stop ]. ZnLogEvent announcer unsubscribe: self. + znEventToLogRecordAdapter stopListeners. super basicStop ] @@ -187,29 +193,20 @@ StargateApplication >> configureGlobalErrorHandlerIn: api [ ] { #category : #'private - activation/deactivation' } -StargateApplication >> configureHTTPClientLogging [ +StargateApplication >> configureHTTPRequestsLogging [ - self stargateConfiguration logClientEvents then: [ - ZnLogEvent announcer when: ZnClientTransactionEvent do: [ :event | - LaunchpadLogRecord - emitStructuredDebuggingInfo: 'HTTP Client event received' - with: [ :data | self dumpDataOf: event on: data ] ] ] -] + znEventToLogRecordAdapter logOutgoingRequests: + self stargateConfiguration logOutgoingHTTPRequests. -{ #category : #'private - activation/deactivation' } -StargateApplication >> configureHTTPServerLogging [ - - self stargateConfiguration logServerEvents then: [ - ZnLogEvent announcer - when: ZnServerTransactionEvent , ZnSimplifiedServerTransactionEvent - do: [ :event | - LaunchpadLogRecord - emitStructuredDebuggingInfo: 'HTTP Server event received' - with: [ :data | self dumpDataOf: event on: data ] ] ]. + znEventToLogRecordAdapter logIncomingRequests: + self stargateConfiguration logIncomingHTTPRequests. ZnLogEvent announcer when: ZnServerHandlerErrorEvent - do: [ :event | LaunchpadLogRecord emitError: event exception messageText ] + do: [ :event | + LaunchpadLogRecord emitError: event exception messageText ]. + + znEventToLogRecordAdapter startUpListeners ] { #category : #'private - accessing' } @@ -248,7 +245,8 @@ StargateApplication >> dumpDataOf: aZincEvent on: aLogRecordJson [ StargateApplication >> initialize [ super initialize. - apiOptional := Optional unused + apiOptional := Optional unused. + znEventToLogRecordAdapter := ZnEventToLogRecordAdapter new ] { #category : #'private - activation/deactivation' }