239 lines
7.5 KiB
Go
239 lines
7.5 KiB
Go
// TODO: move protocol to a separate package
|
|
package client
|
|
|
|
import (
|
|
"git.netflux.io/rob/octoplex/internal/domain"
|
|
"git.netflux.io/rob/octoplex/internal/event"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
pb "git.netflux.io/rob/octoplex/internal/generated/grpc"
|
|
)
|
|
|
|
// EventToProto converts an event to a protobuf message.
|
|
func EventToProto(ev event.Event) *pb.Event {
|
|
switch evt := ev.(type) {
|
|
case event.AppStateChangedEvent:
|
|
return buildAppStateChangeEvent(evt)
|
|
case event.DestinationAddedEvent:
|
|
return buildDestinationAddedEvent(evt)
|
|
case event.AddDestinationFailedEvent:
|
|
return buildAddDestinationFailedEvent(evt)
|
|
case event.DestinationStreamExitedEvent:
|
|
return buildDestinationStreamExitedEvent(evt)
|
|
case event.StartDestinationFailedEvent:
|
|
return buildStartDestinationFailedEvent(evt)
|
|
case event.DestinationRemovedEvent:
|
|
return buildDestinationRemovedEvent(evt)
|
|
case event.RemoveDestinationFailedEvent:
|
|
return buildRemoveDestinationFailedEvent(evt)
|
|
case event.FatalErrorOccurredEvent:
|
|
return buildFatalErrorOccurredEvent(evt)
|
|
case event.OtherInstanceDetectedEvent:
|
|
return buildOtherInstanceDetectedEvent(evt)
|
|
case event.MediaServerStartedEvent:
|
|
return buildMediaServerStartedEvent(evt)
|
|
default:
|
|
panic("unknown event type")
|
|
}
|
|
}
|
|
|
|
// CommandToProto converts a command to a protobuf message.
|
|
func CommandToProto(command event.Command) *pb.Command {
|
|
switch evt := command.(type) {
|
|
case event.CommandAddDestination:
|
|
return buildAddDestinationCommand(evt)
|
|
case event.CommandRemoveDestination:
|
|
return buildRemoveDestinationCommand(evt)
|
|
case event.CommandStartDestination:
|
|
return buildStartDestinationCommand(evt)
|
|
case event.CommandStopDestination:
|
|
return buildStopDestinationCommand(evt)
|
|
case event.CommandCloseOtherInstance:
|
|
return buildCloseOtherInstanceCommand(evt)
|
|
case event.CommandQuit:
|
|
return buildQuitCommand(evt)
|
|
default:
|
|
panic("unknown command type")
|
|
}
|
|
}
|
|
|
|
func buildAppStateChangeEvent(evt event.AppStateChangedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_AppStateChanged{
|
|
AppStateChanged: &pb.AppStateChangedEvent{
|
|
AppState: &pb.AppState{
|
|
Source: &pb.Source{
|
|
Container: containerToProto(evt.State.Source.Container),
|
|
Live: evt.State.Source.Live,
|
|
LiveChangedAt: timestamppb.New(evt.State.Source.LiveChangedAt),
|
|
Tracks: evt.State.Source.Tracks,
|
|
ExitReason: evt.State.Source.ExitReason,
|
|
},
|
|
Destinations: destinationsToProto(evt.State.Destinations),
|
|
BuildInfo: &pb.BuildInfo{
|
|
GoVersion: evt.State.BuildInfo.GoVersion,
|
|
Version: evt.State.BuildInfo.Version,
|
|
Commit: evt.State.BuildInfo.Commit,
|
|
Date: evt.State.BuildInfo.Date,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildDestinationAddedEvent(evt event.DestinationAddedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_DestinationAdded{
|
|
DestinationAdded: &pb.DestinationAddedEvent{Url: evt.URL},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildAddDestinationFailedEvent(evt event.AddDestinationFailedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_AddDestinationFailed{
|
|
AddDestinationFailed: &pb.AddDestinationFailedEvent{Url: evt.URL, Error: evt.Err.Error()},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildDestinationStreamExitedEvent(evt event.DestinationStreamExitedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_DestinationStreamExited{
|
|
DestinationStreamExited: &pb.DestinationStreamExitedEvent{Name: evt.Name, Error: evt.Err.Error()},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildStartDestinationFailedEvent(evt event.StartDestinationFailedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_StartDestinationFailed{
|
|
StartDestinationFailed: &pb.StartDestinationFailedEvent{Url: evt.URL, Message: evt.Message},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildDestinationRemovedEvent(evt event.DestinationRemovedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_DestinationRemoved{
|
|
DestinationRemoved: &pb.DestinationRemovedEvent{Url: evt.URL},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildRemoveDestinationFailedEvent(evt event.RemoveDestinationFailedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_RemoveDestinationFailed{
|
|
RemoveDestinationFailed: &pb.RemoveDestinationFailedEvent{Url: evt.URL, Error: evt.Err.Error()},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildFatalErrorOccurredEvent(evt event.FatalErrorOccurredEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_FatalError{
|
|
FatalError: &pb.FatalErrorEvent{Message: evt.Message},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildOtherInstanceDetectedEvent(_ event.OtherInstanceDetectedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_OtherInstanceDetected{
|
|
OtherInstanceDetected: &pb.OtherInstanceDetectedEvent{},
|
|
},
|
|
}
|
|
}
|
|
|
|
func buildMediaServerStartedEvent(evt event.MediaServerStartedEvent) *pb.Event {
|
|
return &pb.Event{
|
|
EventType: &pb.Event_MediaServerStarted{
|
|
MediaServerStarted: &pb.MediaServerStartedEvent{RtmpUrl: evt.RTMPURL, RtmpsUrl: evt.RTMPSURL},
|
|
},
|
|
}
|
|
}
|
|
|
|
func containerToProto(c domain.Container) *pb.Container {
|
|
var errString string
|
|
if c.Err != nil {
|
|
errString = c.Err.Error()
|
|
}
|
|
|
|
var exitCode *int32
|
|
if c.ExitCode != nil {
|
|
code := int32(*c.ExitCode)
|
|
exitCode = &code
|
|
}
|
|
|
|
return &pb.Container{
|
|
Id: c.ID,
|
|
Status: c.Status,
|
|
HealthState: c.HealthState,
|
|
CpuPercent: c.CPUPercent,
|
|
MemoryUsageBytes: c.MemoryUsageBytes,
|
|
RxRate: int32(c.RxRate),
|
|
TxRate: int32(c.TxRate),
|
|
RxSince: timestamppb.New(c.RxSince),
|
|
ImageName: c.ImageName,
|
|
PullStatus: c.PullStatus,
|
|
PullProgress: c.PullProgress,
|
|
PullPercent: int32(c.PullPercent),
|
|
RestartCount: int32(c.RestartCount),
|
|
ExitCode: exitCode,
|
|
Err: errString,
|
|
}
|
|
}
|
|
|
|
func destinationsToProto(inDests []domain.Destination) []*pb.Destination {
|
|
destinations := make([]*pb.Destination, 0, len(inDests))
|
|
for _, d := range inDests {
|
|
destinations = append(destinations, destinationToProto(d))
|
|
}
|
|
return destinations
|
|
}
|
|
|
|
func destinationToProto(d domain.Destination) *pb.Destination {
|
|
return &pb.Destination{
|
|
Container: containerToProto(d.Container),
|
|
Status: destinationStatusToProto(d.Status),
|
|
Name: d.Name,
|
|
Url: d.URL,
|
|
}
|
|
}
|
|
|
|
func destinationStatusToProto(s domain.DestinationStatus) pb.Destination_Status {
|
|
switch s {
|
|
case domain.DestinationStatusStarting:
|
|
return pb.Destination_STATUS_STARTING
|
|
case domain.DestinationStatusLive:
|
|
return pb.Destination_STATUS_LIVE
|
|
default:
|
|
return pb.Destination_STATUS_OFF_AIR
|
|
}
|
|
}
|
|
|
|
func buildAddDestinationCommand(cmd event.CommandAddDestination) *pb.Command {
|
|
return &pb.Command{CommandType: &pb.Command_AddDestination{AddDestination: &pb.AddDestinationCommand{Url: cmd.URL}}}
|
|
}
|
|
|
|
func buildRemoveDestinationCommand(cmd event.CommandRemoveDestination) *pb.Command {
|
|
return &pb.Command{CommandType: &pb.Command_RemoveDestination{RemoveDestination: &pb.RemoveDestinationCommand{Url: cmd.URL}}}
|
|
}
|
|
|
|
func buildStartDestinationCommand(cmd event.CommandStartDestination) *pb.Command {
|
|
return &pb.Command{CommandType: &pb.Command_StartDestination{StartDestination: &pb.StartDestinationCommand{Url: cmd.URL}}}
|
|
}
|
|
|
|
func buildStopDestinationCommand(cmd event.CommandStopDestination) *pb.Command {
|
|
return &pb.Command{CommandType: &pb.Command_StopDestination{StopDestination: &pb.StopDestinationCommand{Url: cmd.URL}}}
|
|
}
|
|
|
|
func buildCloseOtherInstanceCommand(event.CommandCloseOtherInstance) *pb.Command {
|
|
return &pb.Command{CommandType: &pb.Command_CloseOtherInstances{CloseOtherInstances: &pb.CloseOtherInstancesCommand{}}}
|
|
}
|
|
|
|
func buildQuitCommand(event.CommandQuit) *pb.Command {
|
|
return &pb.Command{CommandType: &pb.Command_Quit{Quit: &pb.QuitCommand{}}}
|
|
}
|