sdk-powershell/src/CloudEventsPowerShell/CloudEvents.Sdk.psm1

790 lines
26 KiB
PowerShell

# **************************************************************************
# Copyright (c) Cloud Native Foundation.
# SPDX-License-Identifier: Apache-2.0
# **************************************************************************
$xmlDataSerilizationLibPath = Join-Path (Join-Path $PSScriptRoot 'dataserialization') 'xml.ps1'
. $xmlDataSerilizationLibPath
function New-CloudEvent {
<#
.SYNOPSIS
This function creates a new cloud event.
.DESCRIPTION
This function creates a new cloud event object with the provided parameters.
The result cloud event object has no data. Use Add-CloudEvent* functions to
add data to the cloud event object.
.PARAMETER Type
Specifies the 'type' attribute of the cloud event.
.PARAMETER Source
Specifies the 'source' attribute of the cloud event.
.PARAMETER Id
Specifies the 'id' attribute of the cloud event.
.PARAMETER Time
Specifies the 'time' attribute of the cloud event.
.EXAMPLE
New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date)
Creates a cloud event with Type, Source, Id, and Time
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]
$Type,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.Uri]
$Source,
[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[string]
$Id,
[Parameter(Mandatory = $false)]
[ValidateNotNullOrEmpty()]
[DateTime]
$Time
)
PROCESS {
$cloudEvent = New-Object `
-TypeName 'CloudNative.CloudEvents.CloudEvent' `
-ArgumentList @(
$Type,
$Source,
$Id,
$Time,
@())
Write-Output $cloudEvent
}
}
#region Set Data Functions
function Set-CloudEventData {
<#
.SYNOPSIS
This function sets data in a cloud event.
.DESCRIPTION
This function sets data in a cloud event object with the provided parameters.
.PARAMETER CloudEvent
Specifies the cloud event object that receives the data.
.PARAMETER Data
Specifies the data object for the cloud event 'data' attribute.
.PARAMETER DataContentType
Specifies the 'datacontenttype' attribute of the cloud event.
.EXAMPLE
$cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date)
$cloudEvent | Set-CloudEventData -Data '<much wow="xml"/>' -DataContentType 'application/xml'
Sets xml data to the cloud event
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent,
[Parameter(Mandatory = $true,
ValueFromPipeline = $false)]
[ValidateNotNullOrEmpty()]
[object]
$Data,
# CloudEvent 'datacontenttype' attribute. Content type of the 'data' attribute value.
# This attribute enables the data attribute to carry any type of content, whereby
# format and encoding might differ from that of the chosen event format.
[Parameter(Mandatory = $false,
ValueFromPipeline = $false)]
[string]
$DataContentType)
PROCESS {
# https://github.com/cloudevents/spec/blob/master/spec.md#datacontenttype
$contentType = New-Object `
-TypeName 'System.Net.Mime.ContentType' `
-ArgumentList ($DataContentType)
$cloudEvent.Data = $Data
$cloudEvent.DataContentType = $dataContentType
Write-Output $CloudEvent
}
}
function Set-CloudEventJsonData {
<#
.SYNOPSIS
This function sets JSON format data in a cloud event.
.DESCRIPTION
This function converts a PowerShell hashtable to JSON format data and sets it in a cloud event.
.PARAMETER CloudEvent
Specifies the cloud event object that receives the data.
.PARAMETER Data
Specifies the PowerShell hashtable object that is set as JSON on the cloud event 'data' attribute.
The 'datacontenttype' attribute is set to 'application/json'
.PARAMETER Depth
The maximum depth of the input hashtable specified on the `Data` parameter that will be converted to JSON.
This parameter is passed on the `-Depth` parameter of the `ConvertTo-Json` cmdlet.
The default value is 3
.EXAMPLE
$cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date)
$cloudEvent | Set-CloudEventJsonData -Data @{ 'key1' = 'value1'; 'key2' = 'value2'; }
Sets JSON data to the cloud event
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent,
[Parameter(Mandatory = $true,
ValueFromPipeline = $false)]
[ValidateNotNull()]
[Hashtable]
$Data,
[Parameter(Mandatory = $false,
ValueFromPipeline = $false)]
[int]
$Depth = 3)
PROCESS {
# DataContentType is set to 'application/json'
# https://github.com/cloudevents/spec/blob/master/spec.md#datacontenttype
$dataContentType = New-Object `
-TypeName 'System.Net.Mime.ContentType' `
-ArgumentList ([System.Net.Mime.MediaTypeNames+Application]::Json)
$cloudEvent.DataContentType = $dataContentType
$cloudEvent.Data = ConvertTo-Json -InputObject $Data -Depth $Depth
Write-Output $CloudEvent
}
}
function Set-CloudEventXmlData {
<#
.SYNOPSIS
This function sets XML format data in a cloud event.
.DESCRIPTION
This function converts a PowerShell hashtable to XML format data and sets it in a cloud event.
.PARAMETER CloudEvent
Specifies the cloud event object that receives the data.
.PARAMETER Data
Specifies the PowerShell hashtable object that is set as XML on the cloud event 'data' attribute.
The 'datacontenttype' attribute is set to 'application/xml'
.PARAMETER AttributesKeysInElementAttributes
Specifies how to format the XML. If specified and the input Data hashtable has pairs of 'Attributes', 'Value' keys
creates XML element with attributes, otherwise each key is formatted as XML element.
If true
@{'root' = @{'Attributes' = @{'att1' = 'true'}; 'Value' = 'val-1'}} would be '<root att1="true">val-1</root>'
Otherwise
@{'root' = @{'Attributes' = @{'att1' = 'true'}; 'Value' = 'val-1'}} would be '<root><Attributes><att1>true</att1></Attributes><Value>val-1</Value></root>'
.EXAMPLE
$cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date)
$cloudEvent | Set-CloudEventXmlData -Data @{ 'key1' = 'value1'; 'key2' = 'value2'; } -AttributesKeysInElementAttributes $true
Sets XML data in the cloud event
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent,
[Parameter(Mandatory = $true,
ValueFromPipeline = $false)]
[ValidateNotNull()]
[Hashtable]
$Data,
[Parameter(Mandatory = $true)]
[bool]
$AttributesKeysInElementAttributes)
PROCESS {
# DataContentType is set to 'application/xml'
$dataContentType = New-Object `
-TypeName 'System.Net.Mime.ContentType' `
-ArgumentList ([System.Net.Mime.MediaTypeNames+Application]::Xml)
$cloudEvent.DataContentType = $dataContentType
$cloudEvent.Data = ConvertTo-CEDataXml -InputObject $Data -AttributesKeysInElementAttributes $AttributesKeysInElementAttributes
Write-Output $CloudEvent
}
}
#endregion Set Data Functions
#region Read Data Functions
function Read-CloudEventData {
<#
.SYNOPSIS
This function gets the data from a cloud event.
.DESCRIPTION
This function gets the data as-is from a cloud event. It is equiualent of accessing the Data property of a CloudEvent object
.PARAMETER CloudEvent
Specifies the cloud event object to get data from.
.EXAMPLE
$cloudEvent = ConvertFrom-HttpMessage -Headers $httpResponse.Headers -Body $httpResponse.Content
$cloudEvent | Read-CloudEventData
Reads data from a cloud event received on the http response
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent
)
PROCESS {
Write-Output $CloudEvent.Data
}
}
function Read-CloudEventJsonData {
<#
.SYNOPSIS
This function gets JSON fromat data from a cloud event as a PowerShell hashtable.
.DESCRIPTION
This function gets the data from a cloud event and converts it to a PowerShell hashtable.
If the cloud event datacontenttype is not 'application/json' nothing is returned.
.PARAMETER CloudEvent
Specifies the cloud event object to get data from.
.PARAMETER Depth
Specifies how many levels of contained objects are included in the JSON representation. The default value is 3.
.EXAMPLE
$cloudEvent = ConvertFrom-HttpMessage -Headers $httpResponse.Headers -Body $httpResponse.Content
$hashtable = $cloudEvent | Read-CloudEventJsonData
Reads JSON data as a hashtable from a cloud event received on the http response
#>
<#
.DESCRIPTION
Returns PowerShell hashtable that represents the CloudEvent Json Data
if the data content type is 'application/json', otherwise otherwise non-terminating error and no result
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent,
[Parameter(Mandatory = $false,
ValueFromPipeline = $false)]
[int]
$Depth = 3
)
PROCESS {
# DataContentType is expected to be 'application/json'
# https://github.com/cloudevents/spec/blob/master/spec.md#datacontenttype
$dataContentType = New-Object `
-TypeName 'System.Net.Mime.ContentType' `
-ArgumentList ([System.Net.Mime.MediaTypeNames+Application]::Json)
if ($CloudEvent.DataContentType -eq $dataContentType -or `
($CloudEvent.DataContentType -eq $null -and ` # Datacontent Type is Optional, if it is not specified we assume it is JSON as per https://github.com/cloudevents/spec/blob/v1.0.1/spec.md#datacontenttype
$cloudEvent.Data -is [Newtonsoft.Json.Linq.JObject])) {
$data = $cloudEvent.Data
if ($cloudEvent.Data -is [byte[]]) {
$data = [System.Text.Encoding]::UTF8.GetString($data)
}
$result = $data.ToString() | ConvertFrom-Json -AsHashtable -Depth $Depth
Write-Output $result
} else {
Write-Error "Cloud Event '$($cloudEvent.Id)' has no json data"
}
}
}
function Read-CloudEventXmlData {
<#
.SYNOPSIS
This function gets XML fromat data from a cloud event as a PowerShell hashtable.
.DESCRIPTION
This function gets the data from a cloud event and converts it to a PowerShell hashtable.
If the cloud event datacontenttype is not 'application/xml' nothing is returned.
.PARAMETER CloudEvent
Specifies the cloud event object to get data from.
.PARAMETER ConvertMode
Specifies the how to convert the xml data to a hashtable
'SkipAttributes' - Skips attributes of the XML elements. XmlElement is represented as a
Key-Value pair where key is the xml element name, and the value is the xml element inner text
Example:
"<key att='true'>value1</key>" is converted to
@{'key' = 'value-1'}
'AlwaysAttrValue' - Each element is represented as a hashtable with two keys
'Attributes' - key-value pair of the cml element attributes if any, otherwise null
'Value' - string value represinting the xml element inner text
Example:
"<key1 att='true'>value1</key1><key2>value2</key2>" is converted to
@{
'key1' = @{
'Attributes' = @{
'att' = 'true'
}
'Value' = 'value1'
}
'key2' = @{
'Attributes' = $null
'Value' = 'value2'
}
}
'AttrValueWhenAttributes' - Uses 'SkipAttributes' for xml elements without attributes and
'AlwaysAttrValue' for xml elements with attributes
Example:
"<key1 att='true'>value1</key1><key2>value2</key2>" is converted to
@{
'key1' = @{
'Attributes' = @{
'att' = 'true'
}
'Value' = 'value1'
}
'key2' = 'value2'
}
.EXAMPLE
$cloudEvent = ConvertFrom-HttpMessage -Headers $httpResponse.Headers -Body $httpResponse.Content
$hashtable = $cloudEvent | Read-CloudEventXmlData -ConvertMode AttrValueWhenAttributes
Reads XML data as a hashtable from a cloud event received on the http response
#>
<#
.DESCRIPTION
Returns PowerShell hashtable that represents the CloudEvent Xml Data
if the data content type is 'application/xml', otherwise non-terminating error and no result
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true,
ValueFromPipeline = $true)]
[ValidateNotNullOrEmpty()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent,
[Parameter(Mandatory = $true)]
[ValidateSet("SkipAttributes", "AlwaysAttrValue", "AttrValueWhenAttributes")]
[string]
$ConvertMode
)
PROCESS {
# DataContentType is expected to be 'application/xml'
$dataContentType = New-Object `
-TypeName 'System.Net.Mime.ContentType' `
-ArgumentList ([System.Net.Mime.MediaTypeNames+Application]::Xml)
if ($CloudEvent.DataContentType -eq $dataContentType) {
$data = $cloudEvent.Data
if ($cloudEvent.Data -is [byte[]]) {
$data = [System.Text.Encoding]::UTF8.GetString($data)
}
$result = $data.ToString() | ConvertFrom-CEDataXml -ConvertMode $ConvertMode
Write-Output $result
} else {
Write-Error "Cloud Event '$($cloudEvent.Id)' has no xml data"
}
}
}
#endregion Read Data Functions
#region HTTP Protocol Binding Conversion Functions
function ConvertTo-HttpMessage {
<#
.SYNOPSIS
This function converts a cloud event object to a Http Message.
.DESCRIPTION
This function converts a cloud event object to a PSObject with Headers and Body properties.
The 'Headers' propery is a hashtable that can pe provided to the 'Headers' parameter of the Inveok-WebRequest cmdlet.
The 'Body' propery is byte[] that can pe provided to the 'Body' parameter of the Inveok-WebRequest cmdlet.
.PARAMETER CloudEvent
Specifies the cloud event object to convert.
.PARAMETER ContentMode
Specifies the cloud event content mode. Structured and Binary content modes are supporterd.
.EXAMPLE
$cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date)
$cloudEvent | Add-CloudEventJsonData -Data @{ 'key1' = 'value1'; 'key2' = 'value2'; }
$cloudEvent | ConvertTo-HttpMessage -ContentMode Binary
Converts a cloud event object to Headers and Body formatted in Binary content mode.
.EXAMPLE
$cloudEvent = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date)
$cloudEvent | Add-CloudEventJsonData -Data @{ 'key1' = 'value1'; 'key2' = 'value2'; }
$cloudEvent | ConvertTo-HttpMessage -ContentMode Structured
Converts a cloud event object to Headers and Body formatted in Structured content mode.
.EXAMPLE
$httpMessage = New-CloudEvent -Type 'com.example.object.deleted.v2' -Source 'mailto:cncf-wg-serverless@lists.cncf.io' -Id '6e8bc430-9c3a-11d9-9669-0800200c9a66' -Time (Get-Date) | `
Add-CloudEventJsonData -Data @{ 'key1' = 'value1'; 'key2' = 'value2'; } | `
ConvertTo-HttpMessage -ContentMode Structured
Invoke-WebRequest -Uri 'http://localhost:52673/' -Headers $httpMessage.Headers -Body $httpMessage.Body
Sends a cloud event http requests to a server
#>
[CmdletBinding()]
param(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $false)]
[ValidateNotNull()]
[CloudNative.CloudEvents.CloudEvent]
$CloudEvent,
[Parameter(
Mandatory = $true,
ValueFromPipeline = $false,
ValueFromPipelineByPropertyName = $false)]
[CloudNative.CloudEvents.ContentMode]
$ContentMode)
PROCESS {
# Output Object
$result = New-Object -TypeName PSCustomObject
$cloudEventFormatter = New-Object 'CloudNative.CloudEvents.JsonEventFormatter'
$HttpHeaderPrefix = "ce-";
$SpecVersionHttpHeader1 = $HttpHeaderPrefix + "cloudEventsVersion";
$SpecVersionHttpHeader2 = $HttpHeaderPrefix + "specversion";
$headers = @{}
# Build HTTP headers
foreach ($attribute in $cloudEvent.GetAttributes()) {
if (-not $attribute.Key.Equals([CloudNative.CloudEvents.CloudEventAttributes]::DataAttributeName($cloudEvent.SpecVersion)) -and `
-not $attribute.Key.Equals([CloudNative.CloudEvents.CloudEventAttributes]::DataContentTypeAttributeName($cloudEvent.SpecVersion))) {
if ($attribute.Value -is [string]) {
$headers.Add(($HttpHeaderPrefix + $attribute.Key), $attribute.Value.ToString())
}
elseif ($attribute.Value -is [DateTime]) {
$headers.Add(($HttpHeaderPrefix + $attribute.Key), $attribute.Value.ToUniversalTime().ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))
}
elseif ($attribute.Value -is [Uri] -or $attribute.Value -is [int]) {
$headers.Add(($HttpHeaderPrefix + $attribute.Key), $attribute.Value.ToString())
}
else
{
$headers.Add(($HttpHeaderPrefix + $attribute.Key),
[System.Text.Encoding]::UTF8.GetString($cloudEventFormatter.EncodeAttribute($cloudEvent.SpecVersion, $attribute.Key,
$attribute.Value,
$cloudEvent.Extensions.Values)));
}
}
}
# Add Headers property to the output object
$result | Add-Member -MemberType NoteProperty -Name 'Headers' -Value $headers
# Process Structured Mode
# Structured Mode supports non-batching JSON format only
# https://github.com/cloudevents/spec/blob/v1.0.1/http-protocol-binding.md#14-event-formats
if ($ContentMode -eq [CloudNative.CloudEvents.ContentMode]::Structured) {
# Format Body as byte[]
$contentType = $null
# CloudEventFormatter is instance of 'CloudNative.CloudEvents.JsonEventFormatter' from the
# .NET CloudEvents SDK for the purpose of fomatting structured mode
$buffer = $cloudEventFormatter.EncodeStructuredEvent($cloudEvent, [ref] $contentType)
$result | Add-Member -MemberType NoteProperty -Name 'Body' -Value $buffer
$result.Headers.Add('Content-Type', $contentType)
}
# Process Binary Mode
if ($ContentMode -eq [CloudNative.CloudEvents.ContentMode]::Binary) {
$bodyData = $null
if ($cloudEvent.DataContentType -ne $null) {
$result.Headers.Add('Content-Type', $cloudEvent.DataContentType)
}
if ($cloudEvent.Data -is [byte[]]) {
$bodyData = $cloudEvent.Data
}
elseif ($cloudEvent.Data -is [string]) {
$bodyData = [System.Text.Encoding]::UTF8.GetBytes($cloudEvent.Data.ToString())
}
elseif ($cloudEvent.Data -is [IO.Stream]) {
$buffer = New-Object 'byte[]' -ArgumentList 1024
$ms = New-Object 'IO.MemoryStream'
try {
$read = 0
while (($read = $cloudEvent.Data.Read($buffer, 0, 1024)) -gt 0)
{
$ms.Write($buffer, 0, $read);
}
$bodyData = $ms.ToArray()
} finally {
$ms.Dispose()
}
} else {
$bodyData = $cloudEventFormatter.EncodeAttribute($cloudEvent.SpecVersion,
[CloudNative.CloudEvents.CloudEventAttributes]::DataAttributeName($cloudEvent.SpecVersion),
$cloudEvent.Data, $cloudEvent.Extensions.Values)
}
# Add Body property to the output object
$result | Add-Member -MemberType NoteProperty -Name 'Body' -Value $bodyData
}
Write-Output $result
}
}
function ConvertFrom-HttpMessage {
<#
.SYNOPSIS
This function converts a Http Message to a cloud event object
.DESCRIPTION
This function converts a Http Message (Headers and Body) to a cloud event object.
Result of Invoke-WebRequest that contains a cloud event can be passed as input to this
function binding the the 'Headers' and 'Content' properties to the 'Headers' and 'Body' paramters.
.PARAMETER Headers
Specifies the Http Headers as a PowerShell hashtable.
.PARAMETER Body
Specifies the Http body as string or byte[].
.EXAMPLE
$httpReponse = Invoke-WebRequest -Uri 'http://localhost:52673/' -Headers $httpMessage.Headers -Body $httpMessage.Body
$cloudEvent = ConvertFrom-HttpMessage -Headers $httpResponse.Headers -Body $httpResponse.Content
Converts a http response to a cloud event object
#>
[CmdletBinding()]
param(
[Parameter(
Mandatory = $true,
ValueFromPipeline = $false,
ValueFromPipelineByPropertyName = $false)]
[ValidateNotNull()]
[hashtable]
$Headers,
[Parameter(
Mandatory = $false,
ValueFromPipeline = $false,
ValueFromPipelineByPropertyName = $false)]
[ValidateNotNull()]
$Body)
PROCESS {
$HttpHeaderPrefix = "ce-";
$SpecVersionHttpHeader1 = $HttpHeaderPrefix + "cloudEventsVersion";
$SpecVersionHttpHeader2 = $HttpHeaderPrefix + "specversion";
$result = $null
# Always Convert Body to byte[]
# Conversion works with byte[] while
# body can be string in HTTP responses
# for text content type
if ($Body -is [string]) {
$Body = [System.Text.Encoding]::UTF8.GetBytes($Body)
}
if ($Headers['Content-Type'] -ne $null) {
$ContentType = $Headers['Content-Type']
if ($ContentType -is [array]) {
# Get the first content-type value
$ContentType = $ContentType[0]
}
if ($ContentType.StartsWith([CloudNative.CloudEvents.CloudEvent]::MediaType,
[StringComparison]::InvariantCultureIgnoreCase)) {
# Handle Structured Mode
$ctParts = $ContentType.Split(';')
if ($ctParts[0].Trim().StartsWith(([CloudNative.CloudEvents.CloudEvent]::MediaType) + ([CloudNative.CloudEvents.JsonEventFormatter]::MediaTypeSuffix),
[StringComparison]::InvariantCultureIgnoreCase)) {
# Structured Mode supports non-batching JSON format only
# https://github.com/cloudevents/spec/blob/v1.0.1/http-protocol-binding.md#14-event-formats
# .NET SDK 'CloudNative.CloudEvents.JsonEventFormatter' type is used
# to decode the Structured Mode CloudEvents
$json = [System.Text.Encoding]::UTF8.GetString($Body)
$jObject = [Newtonsoft.Json.Linq.JObject]::Parse($json)
$formatter = New-Object 'CloudNative.CloudEvents.JsonEventFormatter'
$result = $formatter.DecodeJObject($jObject, $null)
$result.Data = $result.Data
} else {
# Throw error for unsupported encoding
throw "Unsupported CloudEvents encoding"
}
} else {
# Handle Binary Mode
$version = [CloudNative.CloudEvents.CloudEventsSpecVersion]::Default
if ($Headers.Contains($SpecVersionHttpHeader1)) {
$version = [CloudNative.CloudEvents.CloudEventsSpecVersion]::V0_1
}
if ($Headers.Contains($SpecVersionHttpHeader2)) {
if ($Headers[$SpecVersionHttpHeader2][0] -eq "0.2") {
$version = [CloudNative.CloudEvents.CloudEventsSpecVersion]::V0_2
} elseif ($Headers[$SpecVersionHttpHeader2][0] -eq "0.3") {
$version = [CloudNative.CloudEvents.CloudEventsSpecVersion]::V0_3
}
}
$cloudEvent = New-Object `
-TypeName 'CloudNative.CloudEvents.CloudEvent' `
-ArgumentList @($version, $null);
$attributes = $cloudEvent.GetAttributes();
# Get attributes from HTTP Headers
foreach ($httpHeader in $Headers.GetEnumerator()) {
if ($httpHeader.Key.Equals($SpecVersionHttpHeader1, [StringComparison]::InvariantCultureIgnoreCase) -or `
$httpHeader.Key.Equals($SpecVersionHttpHeader2, [StringComparison]::InvariantCultureIgnoreCase)) {
continue
}
if ($httpHeader.Key.StartsWith($HttpHeaderPrefix, [StringComparison]::InvariantCultureIgnoreCase)) {
$headerValue = $httpHeader.Value
if ($headerValue -is [array]) {
# Get the first object
$headerValue = $headerValue[0]
}
$name = $httpHeader.Key.Substring(3);
# Abolished structures in headers in 1.0
if ($version -ne [CloudNative.CloudEvents.CloudEventsSpecVersion]::V0_1 -and `
$headerValue -ne $null -and `
$headerValue.StartsWith('"') -and `
$headerValue.EndsWith('"') -or `
$headerValue.StartsWith("'") -and $headerValue.EndsWith("'") -or `
$headerValue.StartsWith("{") -and $headerValue.EndsWith("}") -or `
$headerValue.StartsWith("[") -and $headerValue.EndsWith("]")) {
$jsonFormatter = New-Object 'CloudNative.CloudEvents.JsonEventFormatter'
$attributes[$name] = $jsonFormatter.DecodeAttribute($version, $name,
[System.Text.Encoding]::UTF8.GetBytes($headerValue), $null);
} else {
$attributes[$name] = $headerValue
}
}
}
if ($Headers['Content-Type'] -ne $null -and $Headers['Content-Type'][0] -is [string]) {
$cloudEvent.DataContentType = New-Object 'System.Net.Mime.ContentType' -ArgumentList @($Headers['Content-Type'][0])
}
# Get Data from HTTP Body
$cloudEvent.Data = $Body
$result = $cloudEvent
}
}
Write-Output $result
}
}
#endregion HTTP Protocol Binding Conversion Functions