@@ -39,51 +39,112 @@ function Receive-CippHttpTrigger {
3939 # Convert the request to a PSCustomObject because the httpContext is case sensitive since 7.3
4040 $Request = $Request | ConvertTo-Json - Depth 100 | ConvertFrom-Json
4141 Set-Location (Get-Item $PSScriptRoot ).Parent.Parent.FullName
42- $FunctionName = ' Invoke-{0}' -f $Request.Params.CIPPEndpoint
43- Write-Information " API: $ ( $Request.Params.CIPPEndpoint ) "
4442
45- $HttpTrigger = @ {
46- Request = [pscustomobject ]($Request )
47- TriggerMetadata = $TriggerMetadata
48- }
49-
50- if ((Get-Command - Name $FunctionName - ErrorAction SilentlyContinue) -or $FunctionName -eq ' Invoke-Me' ) {
43+ if ($Request.Params.CIPPEndpoint -eq ' $batch' ) {
44+ # Implement batch processing in the style of graph api $batch
5145 try {
52- $Access = Test-CIPPAccess - Request $Request
53- if ($FunctionName -eq ' Invoke-Me' ) {
54- Push-OutputBinding - Name Response - Value $Access
46+ $BatchRequests = $Request.Body.requests
47+ if (-not $BatchRequests -or $BatchRequests.Count -eq 0 ) {
48+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
49+ StatusCode = [HttpStatusCode ]::BadRequest
50+ Body = @ { error = @ { message = ' No requests found in batch body' } }
51+ })
5552 return
5653 }
57- } catch {
58- Write-Information " Access denied for $FunctionName : $ ( $_.Exception.Message ) "
59- Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
60- StatusCode = [HttpStatusCode ]::Forbidden
61- Body = $_.Exception.Message
62- })
63- return
64- }
6554
66- try {
67- Write-Information " Access: $Access "
68- Write-LogMessage - headers $Headers - API $Request.Params.CIPPEndpoint - message ' Accessed this API' - Sev ' Debug'
69- if ($Access ) {
70- $Response = & $FunctionName @HttpTrigger
71- if ($Response.StatusCode ) {
72- Push-OutputBinding - Name Response - Value ([HttpResponseContext ]$Response )
55+ # Validate batch request limit (this might need to be fine tuned for SWA timeouts)
56+ if ($BatchRequests.Count -gt 20 ) {
57+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
58+ StatusCode = [HttpStatusCode ]::BadRequest
59+ Body = @ { error = @ { message = ' Batch request limit exceeded. Maximum 20 requests allowed per batch.' } }
60+ })
61+ return
62+ }
63+
64+ # Process batch requests in parallel for better performance
65+ $BatchResponses = $BatchRequests | ForEach-Object - Parallel {
66+ $BatchRequest = $_
67+ $RequestHeaders = $using :Request.Headers
68+ $TriggerMeta = $using :TriggerMetadata
69+
70+ try {
71+ # Import required modules in the parallel thread
72+ Import-Module CIPPCore - Force
73+ Import-Module CippExtensions - Force - ErrorAction SilentlyContinue
74+ Import-Module DNSHealth - Force - ErrorAction SilentlyContinue
75+ Import-Module AzBobbyTables - Force - ErrorAction SilentlyContinue
76+
77+ # Create individual request object for each batch item
78+ $IndividualRequest = @ {
79+ Params = @ {
80+ CIPPEndpoint = $BatchRequest.url # Use batch request URL as endpoint
81+ }
82+ Body = $BatchRequest.body
83+ Headers = $RequestHeaders
84+ Query = $BatchRequest.query
85+ Method = $BatchRequest.method
86+ }
87+
88+ # Process individual request using New-CippCoreRequest
89+ $IndividualResponse = New-CippCoreRequest - Request $IndividualRequest - TriggerMetadata $TriggerMeta
90+
91+ # Format response in Graph API batch style
92+ $BatchResponse = @ {
93+ id = $BatchRequest.id
94+ status = [int ]$IndividualResponse.StatusCode
95+ body = $IndividualResponse.Body
96+ }
97+
98+ } catch {
99+ # Handle individual request errors
100+ $BatchResponse = @ {
101+ id = $BatchRequest.id
102+ status = 500
103+ body = @ {
104+ error = @ {
105+ code = ' InternalServerError'
106+ message = $_.Exception.Message
107+ }
108+ }
109+ }
73110 }
111+
112+ return $BatchResponse
113+ } - ThrottleLimit 10
114+
115+ $BodyObj = @ {
116+ responses = @ ($BatchResponses )
74117 }
118+
119+ $Body = ConvertTo-Json - InputObject $BodyObj - Depth 20 - Compress
120+
121+ # Return batch response in Graph API format
122+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
123+ StatusCode = [HttpStatusCode ]::OK
124+ Body = $Body
125+ })
126+
75127 } catch {
76- Write-Warning " Exception occurred on HTTP trigger ( $FunctionName ) : $ ( $_.Exception.Message ) "
128+ Write-Warning " Exception occurred during batch processing : $ ( $_.Exception.Message ) "
77129 Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
78130 StatusCode = [HttpStatusCode ]::InternalServerError
79- Body = $_.Exception.Message
131+ Body = @ {
132+ error = @ {
133+ code = ' InternalServerError'
134+ message = " Batch processing failed: $ ( $_.Exception.Message ) "
135+ }
136+ }
80137 })
81138 }
139+ return
82140 } else {
83- Push-OutputBinding - Name Response - Value ([HttpResponseContext ]@ {
84- StatusCode = [HttpStatusCode ]::NotFound
85- Body = ' Endpoint not found'
86- })
141+ $Response = New-CippCoreRequest - Request $Request - TriggerMetadata $TriggerMetadata
142+ if ($Response.StatusCode ) {
143+ if ($Response.Body -is [PSCustomObject ]) {
144+ $Response.Body = $Response.Body | ConvertTo-Json - Depth 20 - Compress
145+ }
146+ Push-OutputBinding - Name Response - Value ([HttpResponseContext ]$Response )
147+ }
87148 }
88149 return
89150}
0 commit comments