20장. PTP 이벤트 소비자 애플리케이션 개발

베어 메탈 클러스터 노드에서 PTP(Precision Time Protocol) 이벤트를 사용하는 소비자 애플리케이션을 개발할 때 소비자 애플리케이션 및 클라우드 이벤트 프록시 컨테이너를 별도의 애플리케이션 Pod에 배포해야 합니다. cloud-event-proxy 컨테이너는 PTP Operator Pod에서 이벤트를 수신하여 소비자 애플리케이션으로 전달합니다. 소비자 애플리케이션은 REST API를 사용하여 cloud-event-proxy 컨테이너에 게시된 이벤트를 구독합니다.

PTP 이벤트 애플리케이션 배포에 대한 자세한 내용은 PTP 빠른 이벤트 알림 프레임워크 정보를 참조하십시오.

참고

다음 정보는 PTP 이벤트를 사용하는 소비자 애플리케이션을 개발하기 위한 일반적인 지침을 제공합니다. 전체 이벤트 소비자 애플리케이션 예는 이 정보의 범위를 벗어납니다.

20.1. PTP 이벤트 소비자 애플리케이션 참조

PTP 이벤트 소비자 애플리케이션에는 다음 기능이 필요합니다.

  1. 클라우드 기본 PTP 이벤트 JSON 페이로드를 수신하기 위해 POST 처리기로 실행되는 웹 서비스
  2. PTP 이벤트 프로듀서에 가입하는 createSubscription 함수
  3. PTP 이벤트 프로듀서의 현재 상태를 폴링하는 getCurrentState 함수

다음 예제 Go 스니펫에서는 이러한 요구 사항을 보여줍니다.

Go의 PTP 이벤트 소비자 서버 함수의 예

func server() {
  http.HandleFunc("/event", getEvent)
  http.ListenAndServe("localhost:8989", nil)
}

func getEvent(w http.ResponseWriter, req *http.Request) {
  defer req.Body.Close()
  bodyBytes, err := io.ReadAll(req.Body)
  if err != nil {
    log.Errorf("error reading event %v", err)
  }
  e := string(bodyBytes)
  if e != "" {
    processEvent(bodyBytes)
    log.Infof("received event %s", string(bodyBytes))
  } else {
    w.WriteHeader(http.StatusNoContent)
  }
}

Go에서 PTP 이벤트 createSubscription 함수의 예

import (
"github.com/redhat-cne/sdk-go/pkg/pubsub"
"github.com/redhat-cne/sdk-go/pkg/types"
v1pubsub "github.com/redhat-cne/sdk-go/v1/pubsub"
)

// Subscribe to PTP events using REST API
s1,_:=createsubscription("/cluster/node/<node_name>/sync/sync-status/os-clock-sync-state") 1
s2,_:=createsubscription("/cluster/node/<node_name>/sync/ptp-status/ptp-clock-class-change")
s3,_:=createsubscription("/cluster/node/<node_name>/sync/ptp-status/lock-state")

// Create PTP event subscriptions POST
func createSubscription(resourceAddress string) (sub pubsub.PubSub, err error) {
  var status int
      apiPath:= "/api/ocloudNotifications/v1/"
      localAPIAddr:=localhost:8989 // vDU service API address
      apiAddr:= "localhost:8089" // event framework API address

  subURL := &types.URI{URL: url.URL{Scheme: "http",
    Host: apiAddr
    Path: fmt.Sprintf("%s%s", apiPath, "subscriptions")}}
  endpointURL := &types.URI{URL: url.URL{Scheme: "http",
    Host: localAPIAddr,
    Path: "event"}}

  sub = v1pubsub.NewPubSub(endpointURL, resourceAddress)
  var subB []byte

  if subB, err = json.Marshal(&sub); err == nil {
    rc := restclient.New()
    if status, subB = rc.PostWithReturn(subURL, subB); status != http.StatusCreated {
      err = fmt.Errorf("error in subscription creation api at %s, returned status %d", subURL, status)
    } else {
      err = json.Unmarshal(subB, &sub)
    }
  } else {
    err = fmt.Errorf("failed to marshal subscription for %s", resourceAddress)
  }
  return
}

1
& lt;node_name >을 PTP 이벤트를 생성하는 노드의 FQDN으로 바꿉니다. 예: compute-1.example.com.

Go의 PTP 이벤트 소비자 getCurrentState 함수의 예

//Get PTP event state for the resource
func getCurrentState(resource string) {
  //Create publisher
  url := &types.URI{URL: url.URL{Scheme: "http",
    Host: localhost:8989,
    Path: fmt.SPrintf("/api/ocloudNotifications/v1/%s/CurrentState",resource}}
  rc := restclient.New()
  status, event := rc.Get(url)
  if status != http.StatusOK {
    log.Errorf("CurrentState:error %d from url %s, %s", status, url.String(), event)
  } else {
    log.Debugf("Got CurrentState: %s ", event)
  }
}