2024-07-19 13:28:48 +00:00
|
|
|
package plug
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
|
|
|
"net"
|
|
|
|
|
2024-08-14 14:06:53 +00:00
|
|
|
"git.anthrove.art/Anthrove/otter-space-sdk/v3/pkg/database"
|
|
|
|
"git.anthrove.art/Anthrove/otter-space-sdk/v3/pkg/models"
|
2024-08-14 14:16:42 +00:00
|
|
|
pb "git.anthrove.art/Anthrove/plug-sdk/v3/pkg/grpc"
|
2024-08-26 11:05:50 +00:00
|
|
|
log "github.com/sirupsen/logrus"
|
2024-08-26 11:01:31 +00:00
|
|
|
"go.opentelemetry.io/otel"
|
|
|
|
"go.opentelemetry.io/otel/attribute"
|
|
|
|
"go.opentelemetry.io/otel/codes"
|
2024-07-19 13:28:48 +00:00
|
|
|
"google.golang.org/grpc"
|
2024-08-26 11:01:31 +00:00
|
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
2024-07-19 13:28:48 +00:00
|
|
|
)
|
|
|
|
|
2024-08-26 14:33:40 +00:00
|
|
|
var tracer = otel.Tracer("git.anthrove.art/Anthrove/plug-sdk/v3/pkg/plug")
|
|
|
|
|
2024-07-19 13:28:48 +00:00
|
|
|
type Message struct {
|
|
|
|
Title string
|
|
|
|
Body string
|
2024-08-26 08:57:05 +00:00
|
|
|
CreatedAt *timestamppb.Timestamp
|
2024-07-19 13:28:48 +00:00
|
|
|
}
|
|
|
|
|
2024-08-17 18:23:11 +00:00
|
|
|
type TaskExecution func(ctx context.Context, userSource models.UserSource, deepScrape bool, apiKey string, cancelFunction func()) error
|
|
|
|
type SendMessageExecution func(ctx context.Context, userSource models.UserSource, message string) error
|
|
|
|
type GetMessageExecution func(ctx context.Context, userSource models.UserSource) ([]Message, error)
|
2024-07-19 13:28:48 +00:00
|
|
|
|
|
|
|
type Plug struct {
|
|
|
|
address string
|
|
|
|
port string
|
|
|
|
taskExecutionFunction TaskExecution
|
|
|
|
sendMessageExecution SendMessageExecution
|
|
|
|
getMessageExecution GetMessageExecution
|
|
|
|
source models.Source
|
2024-08-26 11:01:31 +00:00
|
|
|
plugName string
|
2024-07-19 13:28:48 +00:00
|
|
|
}
|
|
|
|
|
2024-08-27 05:37:19 +00:00
|
|
|
func NewPlug(plugName string, address string, port string, source models.Source) Plug {
|
2024-07-19 13:28:48 +00:00
|
|
|
return Plug{
|
2024-08-26 11:01:31 +00:00
|
|
|
address: address,
|
|
|
|
port: port,
|
|
|
|
source: source,
|
|
|
|
plugName: plugName,
|
2024-07-19 13:28:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-27 05:37:19 +00:00
|
|
|
func (p *Plug) Listen(ctx context.Context) error {
|
|
|
|
ctx, span := tracer.Start(ctx, "Listen")
|
2024-08-26 11:01:31 +00:00
|
|
|
defer span.End()
|
|
|
|
|
2024-07-19 13:28:48 +00:00
|
|
|
var err error
|
2024-08-15 07:56:40 +00:00
|
|
|
var source models.Source
|
2024-07-19 13:28:48 +00:00
|
|
|
|
2024-08-26 11:01:31 +00:00
|
|
|
span.SetAttributes(
|
|
|
|
attribute.String("source_display_name", string(p.source.DisplayName)),
|
|
|
|
attribute.String("source_domain", string(p.source.Domain)),
|
|
|
|
)
|
|
|
|
|
2024-08-26 11:05:50 +00:00
|
|
|
sourceFields := log.Fields{
|
2024-08-26 11:01:31 +00:00
|
|
|
"source_display_name": p.source.DisplayName,
|
|
|
|
"source_domain": p.source.Domain,
|
|
|
|
}
|
|
|
|
|
2024-08-26 11:05:50 +00:00
|
|
|
serverFields := log.Fields{
|
2024-08-26 11:01:31 +00:00
|
|
|
"address": p.address,
|
|
|
|
"port": p.port,
|
|
|
|
}
|
|
|
|
|
|
|
|
source, err = database.GetSourceByDomain(ctx, p.source.Domain)
|
2024-07-19 13:28:48 +00:00
|
|
|
if err != nil {
|
2024-08-24 22:09:21 +00:00
|
|
|
if err.Error() == "Database error: NoDataFound" {
|
2024-08-26 11:01:31 +00:00
|
|
|
span.AddEvent("No Source found, initializing source")
|
|
|
|
|
2024-08-26 11:05:50 +00:00
|
|
|
log.WithContext(ctx).WithFields(sourceFields).Info("No Source found, initializing source!")
|
2024-08-26 11:01:31 +00:00
|
|
|
|
|
|
|
source, err = database.CreateSource(ctx, p.source)
|
2024-08-24 21:42:38 +00:00
|
|
|
if err != nil {
|
2024-08-26 11:01:31 +00:00
|
|
|
span.RecordError(err)
|
|
|
|
span.SetStatus(codes.Error, err.Error())
|
2024-08-26 11:05:50 +00:00
|
|
|
log.WithError(err).WithFields(sourceFields).Error("Failed to create source")
|
2024-08-14 14:06:53 +00:00
|
|
|
panic(err)
|
|
|
|
}
|
2024-08-26 11:01:31 +00:00
|
|
|
|
|
|
|
span.AddEvent("Source created")
|
2024-08-26 11:05:50 +00:00
|
|
|
log.WithContext(ctx).WithError(err).WithFields(sourceFields).WithField("source_id", source.ID).Info("Source created!")
|
2024-08-26 11:01:31 +00:00
|
|
|
|
2024-08-14 14:06:53 +00:00
|
|
|
} else {
|
2024-08-26 11:01:31 +00:00
|
|
|
span.RecordError(err)
|
|
|
|
span.SetStatus(codes.Error, err.Error())
|
2024-08-26 11:05:50 +00:00
|
|
|
log.WithContext(ctx).WithError(err).WithFields(sourceFields).Error("Failed to get source by domain")
|
2024-08-14 14:06:53 +00:00
|
|
|
panic(err)
|
2024-07-19 13:28:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-15 07:56:40 +00:00
|
|
|
p.source = source
|
|
|
|
|
2024-08-26 11:01:31 +00:00
|
|
|
span.SetAttributes(
|
|
|
|
attribute.String("source_id", string(p.source.ID)),
|
|
|
|
)
|
2024-08-17 18:23:11 +00:00
|
|
|
|
2024-07-19 13:28:48 +00:00
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf("%s:%s", p.address, p.port))
|
|
|
|
if err != nil {
|
2024-08-26 11:01:31 +00:00
|
|
|
span.RecordError(err)
|
|
|
|
span.SetStatus(codes.Error, err.Error())
|
2024-08-26 11:05:50 +00:00
|
|
|
log.WithContext(ctx).WithError(err).WithFields(serverFields).Error("Failed to listen on address")
|
2024-07-19 13:28:48 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
grpcServer := grpc.NewServer()
|
|
|
|
|
2024-08-15 07:56:40 +00:00
|
|
|
pb.RegisterPlugConnectorServer(grpcServer, NewGrpcServer(p.source, p.taskExecutionFunction, p.sendMessageExecution, p.getMessageExecution))
|
2024-07-19 13:28:48 +00:00
|
|
|
|
2024-08-27 05:37:19 +00:00
|
|
|
go func() {
|
|
|
|
err = grpcServer.Serve(lis)
|
|
|
|
if err != nil {
|
|
|
|
span.RecordError(err)
|
|
|
|
span.SetStatus(codes.Error, err.Error())
|
|
|
|
log.WithContext(ctx).WithError(err).Error("Failed to serve gRPC server")
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
log.WithContext(ctx).Info("Context stopped! Shutdown Plug")
|
|
|
|
grpcServer.GracefulStop()
|
2024-07-19 13:28:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-08-15 07:56:40 +00:00
|
|
|
func (p *Plug) GetSource() models.Source {
|
|
|
|
return p.source
|
|
|
|
}
|
|
|
|
|
2024-07-19 13:28:48 +00:00
|
|
|
func (p *Plug) TaskExecutionFunction(function TaskExecution) {
|
|
|
|
p.taskExecutionFunction = function
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Plug) SendMessageExecution(function SendMessageExecution) {
|
|
|
|
p.sendMessageExecution = function
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *Plug) GetMessageExecution(function GetMessageExecution) {
|
|
|
|
p.getMessageExecution = function
|
2024-08-26 11:01:31 +00:00
|
|
|
}
|