Skip to content

Commit

Permalink
SubmitTestEvent is diffrent for some oem vendors and zt event subscri…
Browse files Browse the repository at this point in the history
…ption
  • Loading branch information
nwaizer committed Jul 8, 2022
1 parent 46c07e7 commit aa733ec
Show file tree
Hide file tree
Showing 7 changed files with 977 additions and 30 deletions.
61 changes: 61 additions & 0 deletions oem/dell/dell.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package dell

import (
"fmt"
"net/http"

"github.com/stmcginnis/gofish/redfish"
)

const eventContext string = "root"

var SubmitTestEventTarget = "/redfish/v1/EventService/Actions/EventService.SendTestEvent"

type (
PayloadType struct {
Destination string `json:"Destination"`
EventTypes string `json:"EventTypes"`
Context string `json:"Context"`
Protocol string `json:"Protocol"`
MessageID string `json:"MessageId"`
}
)

type EventService struct {
redfish.EventService
}

// SubmitTestEvent sends event according to msgId and returns error.
func (eventservice *EventService) SubmitTestEvent(messageID, eType, protocol string) error {
payload := PayloadType{
Destination: SubmitTestEventTarget,
EventTypes: eType,
Context: eventContext,
Protocol: protocol,
MessageID: messageID,
}
resp, err := eventservice.Client.Post(SubmitTestEventTarget, payload)

if err != nil {
return fmt.Errorf("failed to post submitTestEvent due to: %w", err)
}
defer resp.Body.Close()

valid := map[int]bool{
http.StatusNoContent: true,
http.StatusCreated: true}

if !valid[resp.StatusCode] {
return fmt.Errorf("on send event received response: %v due to: %s", resp.StatusCode, resp.Body)
}

return nil
}

func FromEventService(eventservice *redfish.EventService) (EventService, error) {
return EventService{*eventservice}, nil
}
237 changes: 237 additions & 0 deletions oem/dell/test/dell_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package test

import (
"encoding/json"
"log"
"net/http"
"net/http/httptest"
"testing"

"github.com/stmcginnis/gofish"
"github.com/stmcginnis/gofish/common"
"github.com/stmcginnis/gofish/oem/dell"
"github.com/stmcginnis/gofish/redfish"
)

const serviceRootBody = `{
"@odata.context": "/redfish/v1/$metadata#ServiceRoot.ServiceRoot",
"@odata.id": "/redfish/v1",
"@odata.type": "#ServiceRoot.v1_8_0.ServiceRoot",
"AccountService": {
"@odata.id": "/redfish/v1/AccountService"
},
"CertificateService": {
"@odata.id": "/redfish/v1/CertificateService"
},
"Chassis": {
"@odata.id": "/redfish/v1/Chassis"
},
"Description": "Root Service",
"EventService": {
"@odata.id": "/redfish/v1/EventService"
},
"Fabrics": {
"@odata.id": "/redfish/v1/Fabrics"
},
"Id": "RootService",
"JobService": {
"@odata.id": "/redfish/v1/JobService"
},
"JsonSchemas": {
"@odata.id": "/redfish/v1/JsonSchemas"
},
"Links": {
"Sessions": {
"@odata.id": "/redfish/v1/SessionService/Sessions"
}
},
"Managers": {
"@odata.id": "/redfish/v1/Managers"
},
"Name": "Root Service",
"Oem": {
"Dell": {
"@odata.context": "/redfish/v1/$metadata#DellServiceRoot.DellServiceRoot",
"@odata.type": "#DellServiceRoot.v1_0_0.DellServiceRoot",
"IsBranded": 0,
"ManagerMACAddress": "00:00:00:00:00:00",
"ServiceTag": "0000000"
}
},
"Product": "Integrated Dell Remote Access Controller",
"ProtocolFeaturesSupported": {
"DeepOperations": {
"DeepPATCH": false,
"DeepPOST": false
},
"ExcerptQuery": false,
"ExpandQuery": {
"ExpandAll": true,
"Levels": true,
"Links": true,
"MaxLevels": 1,
"NoLinks": true
},
"FilterQuery": true,
"OnlyMemberQuery": true,
"SelectQuery": true
},
"RedfishVersion": "1.11.0",
"Registries": {
"@odata.id": "/redfish/v1/Registries"
},
"SessionService": {
"@odata.id": "/redfish/v1/SessionService"
},
"Systems": {
"@odata.id": "/redfish/v1/Systems"
},
"Tasks": {
"@odata.id": "/redfish/v1/TaskService"
},
"TelemetryService": {
"@odata.id": "/redfish/v1/TelemetryService"
},
"UpdateService": {
"@odata.id": "/redfish/v1/UpdateService"
},
"Vendor": "Dell"
}`

const eventServiceBody = `{
"@odata.context": "/redfish/v1/$metadata#EventService.EventService",
"@odata.id": "/redfish/v1/EventService",
"@odata.type": "#EventService.v1_7_0.EventService",
"Actions": {
"#EventService.SubmitTestEvent": {
"EventType@Redfish.AllowableValues": ["Alert"],
"target": "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent"
}
},
"DeliveryRetryAttempts": 3,
"DeliveryRetryIntervalSeconds": 5,
"Description": "Event Service represents the properties for the service",
"EventFormatTypes": ["Event", "MetricReport"],
"EventFormatTypes@odata.count": 2,
"EventTypesForSubscription": ["Alert", "MetricReport", "Other"],
"EventTypesForSubscription@odata.count": 3,
"Id": "EventService",
"Name": "Event Service",
"SMTP": {
"Authentication": "None",
"ConnectionProtocol": "StartTLS",
"FromAddress": "",
"Password": null,
"Port": 25,
"ServerAddress": "0.0.0.0",
"Username": ""
},
"SSEFilterPropertiesSupported": {
"EventFormatType": true,
"EventType": true,
"MessageId": true,
"MetricReportDefinition": true,
"OriginResource": true,
"RegistryPrefix": true,
"ResourceType": true,
"SubordinateResources": false
},
"ServerSentEventUri": "/redfish/v1/SSE",
"ServiceEnabled": true,
"Status": {
"Health": "OK",
"HealthRollup": "OK",
"State": "Enabled"
},
"Subscriptions": {
"@odata.id": "/redfish/v1/EventService/Subscriptions"
}
}`

func TestDellSubmitTestEvent(t *testing.T) {
const redfishBaseURL = "/redfish/v1/"
var (
c common.Client
err error
requestCounter int // this counter is used to verify that the received requests, are in the expected order
)

// Start a local HTTP server
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
if req.Method == http.MethodGet &&
req.URL.String() == redfishBaseURL &&
requestCounter < 2 { // ServiceRoot
log.Printf("Mock received login request")
contentType := req.Header.Get("Content-Type")
if contentType != "application/json" {
t.Errorf("gofish connect sent wrong header. Content-Type:"+
" is %v and not expected application/json", contentType)
}

requestCounter++

// Send response to be tested
rw.WriteHeader(http.StatusOK)
rw.Header().Set("Content-Type", "application/json")

rw.Write([]byte(serviceRootBody)) // nolint:errcheck
} else if req.Method == http.MethodGet && // Get event service
req.URL.String() == "/redfish/v1/EventService" &&
requestCounter == 2 {
log.Printf("Getting event service")

requestCounter++

rw.Write([]byte(eventServiceBody)) // nolint:errcheck
} else if req.Method == http.MethodPost && // SubmitTestEvent
req.URL.String() == dell.SubmitTestEventTarget &&
requestCounter == 3 {
log.Printf("Mock got SubmitTestEvent POST")

err := json.NewDecoder(req.Body).Decode(&dell.PayloadType{})
if err != nil {
t.Errorf("error in SubmitTestEvent payload for Dell due to: %v", err)
}

requestCounter++

rw.WriteHeader(http.StatusCreated)
} else {
t.Errorf("mock got unexpected %v request to path %v while request counter is %v",
req.Method, req.URL.String(), requestCounter)
}
}))
// Close the server when test finishes
defer server.Close()

c, err = gofish.Connect(gofish.ClientConfig{Endpoint: server.URL, HTTPClient: server.Client()})

if err != nil {
t.Errorf("failed to establish client to mock http server due to: %v", err)
}

serviceRoot, err := gofish.ServiceRoot(c)
if err != nil {
t.Errorf("failed to get redfish service root due to: %v", err)
}
eventService, err := serviceRoot.EventService()
if err != nil {
t.Errorf("failed to get event service due to: %v", err)
}
dellEventService, err := dell.FromEventService(eventService)
if err != nil {
t.Errorf("failed to get dell event service due to: %v", err)
}

err = dellEventService.SubmitTestEvent(
"AMP0300",
"Alert",
string(redfish.RedfishEventDestinationProtocol))
if err != nil {
t.Errorf("failed to submit test event due to: %v", err)
}
}
65 changes: 65 additions & 0 deletions oem/hpe/events/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//
// SPDX-License-Identifier: BSD-3-Clause
//

package events

import (
"fmt"
"net/http"
"time"

"github.com/stmcginnis/gofish/common"
)

var (
SubmitTestEventTarget = "/redfish/v1/EventService/Actions/EventService.SendTestEvent"
)

type PayloadType struct {
EventID string `json:"EventID"`
EventTimestamp string `json:"EventTimestamp"`
EventType string `json:"EventType"`
Message string
MessageArgs []string
MessageID string `json:"MessageId"`
OriginOfCondition string
Severity string
}

// SubmitTestEvent sends event according to msgId and returns error
// more info https://hewlettpackard.github.io/iLOAmpPack-Redfish-API-Docs/#submitting-a-test-event
func SubmitTestEvent(client common.Client, eventID, msgID, eventType, message string) error {
const condition = "/redfish/v1/Systems/1/"
const severity = "OK"

var messageArgs = []string{"NoAMS", "Busy", "Cached"}

payload := PayloadType{
EventID: eventID,
EventTimestamp: time.Now().Format(time.RFC3339), // "2019-07-29T15:13:49Z",
EventType: eventType, // redfish.SupportedEventTypes["Alert"],
Message: message,
MessageArgs: messageArgs,
MessageID: msgID,
OriginOfCondition: condition,
Severity: severity,
}
resp, err := client.Post(SubmitTestEventTarget, payload)

if err != nil {
return fmt.Errorf("failed to send submitTestEvent due to: %w", err)
}
defer resp.Body.Close()

valid := map[int]bool{
http.StatusOK: true,
http.StatusNoContent: true,
http.StatusCreated: true}

if !valid[resp.StatusCode] {
return fmt.Errorf("on send event received response: %v due to: %s", resp.StatusCode, resp.Body)
}

return nil
}
Loading

0 comments on commit aa733ec

Please sign in to comment.