Skip to content

Commit 8b015cd

Browse files
authored
Merge pull request #56985 from aireilly/cloud-event-proxy-consumer-guide
TELCODOCS-1218 - Adding cloud-events consumer app developer documentation
2 parents 4b05769 + 42b29b0 commit 8b015cd

8 files changed

+520
-0
lines changed

_topic_maps/_topic_map.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,8 @@ Topics:
11511151
Distros: openshift-enterprise,openshift-origin
11521152
- Name: Using PTP hardware
11531153
File: using-ptp
1154+
- Name: Developing PTP events consumer applications
1155+
File: ptp-cloud-events-consumer-dev-reference
11541156
- Name: External DNS Operator
11551157
Dir: external_dns_operator
11561158
Topics:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * networking/ptp-cloud-events-consumer-dev-reference.adoc
4+
5+
:_content-type: REFERENCE
6+
[id="ptp-cloud-event-proxy-sidecar-api_{context}"]
7+
= PTP events available from the cloud-event-proxy sidecar REST API
8+
9+
PTP events consumer applications can poll the PTP events producer for the following PTP timing events.
10+
11+
.PTP events available from the cloud-event-proxy sidecar
12+
[options="header"]
13+
|====
14+
|Resource URI|Description
15+
|`/cluster/node/<node_name>/sync/ptp-status/lock-state`| Describes the current status of the PTP equipment lock state. Can be in `LOCKED`, `HOLDOVER`, or `FREERUN` state.
16+
|`/cluster/node/<node_name>/sync/sync-status/os-clock-sync-state`| Describes the host operating system clock synchronization state. Can be in `LOCKED` or `FREERUN` state.
17+
|`/cluster/node/<node_name>/sync/ptp-status/ptp-clock-class-change`| Describes the current state of the PTP clock class.
18+
|====
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * networking/ptp-cloud-events-consumer-dev-reference.adoc
4+
5+
:_content-type: REFERENCE
6+
[id="ptp-events-consumer-application_{context}"]
7+
= PTP events consumer application reference
8+
9+
PTP event consumer applications require the following features:
10+
11+
. A web service running with a `POST` handler to receive the cloud native PTP events JSON payload
12+
. A `createSubscription` function to subscribe to the PTP events producer
13+
. A `getCurrentState` function to poll the current state of the PTP events producer
14+
15+
The following example Go snippets illustrate these requirements:
16+
17+
.Example PTP events consumer server function in Go
18+
[source,go]
19+
----
20+
func server() {
21+
http.HandleFunc("/event", getEvent)
22+
http.ListenAndServe("localhost:8989", nil)
23+
}
24+
25+
func getEvent(w http.ResponseWriter, req *http.Request) {
26+
defer req.Body.Close()
27+
bodyBytes, err := io.ReadAll(req.Body)
28+
if err != nil {
29+
log.Errorf("error reading event %v", err)
30+
}
31+
e := string(bodyBytes)
32+
if e != "" {
33+
processEvent(bodyBytes)
34+
log.Infof("received event %s", string(bodyBytes))
35+
} else {
36+
w.WriteHeader(http.StatusNoContent)
37+
}
38+
}
39+
----
40+
41+
.Example PTP events createSubscription function in Go
42+
[source,go]
43+
----
44+
import (
45+
"github.com/redhat-cne/sdk-go/pkg/pubsub"
46+
"github.com/redhat-cne/sdk-go/pkg/types"
47+
v1pubsub "github.com/redhat-cne/sdk-go/v1/pubsub"
48+
)
49+
50+
// Subscribe to PTP events using REST API
51+
s1,_:=createsubscription("/cluster/node/<node_name>/sync/sync-status/os-clock-sync-state") <1>
52+
s2,_:=createsubscription("/cluster/node/<node_name>/sync/ptp-status/ptp-clock-class-change")
53+
s3,_:=createsubscription("/cluster/node/<node_name>/sync/ptp-status/lock-state")
54+
55+
// Create PTP event subscriptions POST
56+
func createSubscription(resourceAddress string) (sub pubsub.PubSub, err error) {
57+
var status int
58+
apiPath:= "/api/ocloudNotifications/v1/"
59+
localAPIAddr:=localhost:8989 // vDU service API address
60+
apiAddr:= "localhost:8089" // event framework API address
61+
62+
subURL := &types.URI{URL: url.URL{Scheme: "http",
63+
Host: apiAddr
64+
Path: fmt.Sprintf("%s%s", apiPath, "subscriptions")}}
65+
endpointURL := &types.URI{URL: url.URL{Scheme: "http",
66+
Host: localAPIAddr,
67+
Path: "event"}}
68+
69+
sub = v1pubsub.NewPubSub(endpointURL, resourceAddress)
70+
var subB []byte
71+
72+
if subB, err = json.Marshal(&sub); err == nil {
73+
rc := restclient.New()
74+
if status, subB = rc.PostWithReturn(subURL, subB); status != http.StatusCreated {
75+
err = fmt.Errorf("error in subscription creation api at %s, returned status %d", subURL, status)
76+
} else {
77+
err = json.Unmarshal(subB, &sub)
78+
}
79+
} else {
80+
err = fmt.Errorf("failed to marshal subscription for %s", resourceAddress)
81+
}
82+
return
83+
}
84+
----
85+
<1> Replace `<node_name>` with the FQDN of the node that is generating the PTP events. For example, `compute-1.example.com`.
86+
87+
.Example PTP events consumer getCurrentState function in Go
88+
[source,go]
89+
----
90+
//Get PTP event state for the resource
91+
func getCurrentState(resource string) {
92+
//Create publisher
93+
url := &types.URI{URL: url.URL{Scheme: "http",
94+
Host: localhost:8989,
95+
Path: fmt.SPrintf("/api/ocloudNotifications/v1/%s/CurrentState",resource}}
96+
rc := restclient.New()
97+
status, event := rc.Get(url)
98+
if status != http.StatusOK {
99+
log.Errorf("CurrentState:error %d from url %s, %s", status, url.String(), event)
100+
} else {
101+
log.Debugf("Got CurrentState: %s ", event)
102+
}
103+
}
104+
----
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * networking/ptp-cloud-events-consumer-dev-reference.adoc
4+
5+
:_content-type: REFERENCE
6+
[id="ptp-getting-the-current-ptp-clock-status_{context}"]
7+
= Getting the current PTP clock status
8+
9+
To get the current PTP status for the node, send a `GET` action to one of the following event REST APIs:
10+
11+
* `+http://localhost:8081/api/ocloudNotifications/v1/cluster/node/<node_name>/sync/ptp-status/lock-state/CurrentState+`
12+
13+
* `+http://localhost:8081/api/ocloudNotifications/v1/cluster/node/<node_name>/sync/sync-status/os-clock-sync-state/CurrentState+`
14+
15+
* `+http://localhost:8081/api/ocloudNotifications/v1/cluster/node/<node_name>/sync/ptp-status/ptp-clock-class-change/CurrentState+`
16+
17+
The response is a cloud native event JSON object. For example:
18+
19+
.Example lock-state API response
20+
[source,json]
21+
----
22+
{
23+
"id": "c1ac3aa5-1195-4786-84f8-da0ea4462921",
24+
"type": "event.sync.ptp-status.ptp-state-change",
25+
"source": "/cluster/node/compute-1.example.com/sync/ptp-status/lock-state",
26+
"dataContentType": "application/json",
27+
"time": "2023-01-10T02:41:57.094981478Z",
28+
"data": {
29+
"version": "v1",
30+
"values": [
31+
{
32+
"resource": "/cluster/node/compute-1.example.com/ens5fx/master",
33+
"dataType": "notification",
34+
"valueType": "enumeration",
35+
"value": "LOCKED"
36+
},
37+
{
38+
"resource": "/cluster/node/compute-1.example.com/ens5fx/master",
39+
"dataType": "metric",
40+
"valueType": "decimal64.3",
41+
"value": "29"
42+
}
43+
]
44+
}
45+
}
46+
----
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// Module included in the following assemblies:
2+
//
3+
// * networking/ptp-cloud-events-consumer-dev-reference.adoc
4+
5+
:_content-type: REFERENCE
6+
[id="ptp-reference-deployment-and-service-crs_{context}"]
7+
= Reference cloud-event-proxy deployment and service CRs
8+
9+
Use the following example `cloud-event-proxy` deployment and subscriber service CRs as a reference when deploying your PTP events consumer application.
10+
11+
[NOTE]
12+
====
13+
Use HTTP transport instead of AMQP for PTP and bare-metal events where possible.
14+
AMQ Interconnect is EOL from 30 June 2024.
15+
Extended life cycle support (ELS) for AMQ Interconnect ends 30 November 2030.
16+
For more information see, link:https://access.redhat.com/support/policy/updates/jboss_notes#p_Interconnect[Red Hat AMQ Interconnect support status].
17+
====
18+
19+
.Reference cloud-event-proxy deployment with HTTP transport
20+
[source,yaml]
21+
----
22+
apiVersion: apps/v1
23+
kind: Deployment
24+
metadata:
25+
name: event-consumer-deployment
26+
namespace: <namespace>
27+
labels:
28+
app: consumer
29+
spec:
30+
replicas: 1
31+
selector:
32+
matchLabels:
33+
app: consumer
34+
template:
35+
metadata:
36+
labels:
37+
app: consumer
38+
spec:
39+
serviceAccountName: sidecar-consumer-sa
40+
containers:
41+
- name: event-subscriber
42+
image: event-subscriber-app
43+
- name: cloud-event-proxy-as-sidecar
44+
image: openshift4/ose-cloud-event-proxy
45+
args:
46+
- "--metrics-addr=127.0.0.1:9091"
47+
- "--store-path=/store"
48+
- "--transport-host=consumer-events-subscription-service.cloud-events.svc.cluster.local:9043"
49+
- "--http-event-publishers=ptp-event-publisher-service-NODE_NAME.openshift-ptp.svc.cluster.local:9043"
50+
- "--api-port=8089"
51+
env:
52+
- name: NODE_NAME
53+
valueFrom:
54+
fieldRef:
55+
fieldPath: spec.nodeName
56+
- name: NODE_IP
57+
valueFrom:
58+
fieldRef:
59+
fieldPath: status.hostIP
60+
volumeMounts:
61+
- name: pubsubstore
62+
mountPath: /store
63+
ports:
64+
- name: metrics-port
65+
containerPort: 9091
66+
- name: sub-port
67+
containerPort: 9043
68+
volumes:
69+
- name: pubsubstore
70+
emptyDir: {}
71+
----
72+
73+
.Reference cloud-event-proxy deployment with AMQ transport
74+
[source,yaml]
75+
----
76+
apiVersion: apps/v1
77+
kind: Deployment
78+
metadata:
79+
name: cloud-event-proxy-sidecar
80+
namespace: cloud-events
81+
labels:
82+
app: cloud-event-proxy
83+
spec:
84+
selector:
85+
matchLabels:
86+
app: cloud-event-proxy
87+
template:
88+
metadata:
89+
labels:
90+
app: cloud-event-proxy
91+
spec:
92+
nodeSelector:
93+
node-role.kubernetes.io/worker: ""
94+
containers:
95+
- name: cloud-event-sidecar
96+
image: openshift4/ose-cloud-event-proxy
97+
args:
98+
- "--metrics-addr=127.0.0.1:9091"
99+
- "--store-path=/store"
100+
- "--transport-host=amqp://router.router.svc.cluster.local"
101+
- "--api-port=8089"
102+
env:
103+
- name: <node_name>
104+
valueFrom:
105+
fieldRef:
106+
fieldPath: spec.nodeName
107+
- name: <node_ip>
108+
valueFrom:
109+
fieldRef:
110+
fieldPath: status.hostIP
111+
volumeMounts:
112+
- name: pubsubstore
113+
mountPath: /store
114+
ports:
115+
- name: metrics-port
116+
containerPort: 9091
117+
- name: sub-port
118+
containerPort: 9043
119+
volumes:
120+
- name: pubsubstore
121+
emptyDir: {}
122+
----
123+
124+
.Reference cloud-event-proxy subscriber service
125+
[source,yaml]
126+
----
127+
apiVersion: v1
128+
kind: Service
129+
metadata:
130+
annotations:
131+
prometheus.io/scrape: "true"
132+
service.alpha.openshift.io/serving-cert-secret-name: sidecar-consumer-secret
133+
name: consumer-events-subscription-service
134+
namespace: cloud-events
135+
labels:
136+
app: consumer-service
137+
spec:
138+
ports:
139+
- name: sub-port
140+
port: 9043
141+
selector:
142+
app: consumer
143+
clusterIP: None
144+
sessionAffinity: None
145+
type: ClusterIP
146+
----

0 commit comments

Comments
 (0)