Skip to content
Snippets Groups Projects
server.go 3.17 KiB
Newer Older
  • Learn to ignore specific revisions
  • package main
    
    import (
    	"context"
    	"errors"
    	"fmt"
    	"io"
    	"os"
    	"time"
    
    	pb "code.fbi.h-da.de/danet/gosdn/api/go/gosdn/plugin-registry"
    	"github.com/google/uuid"
    	log "github.com/sirupsen/logrus"
    	"google.golang.org/grpc/codes"
    	status "google.golang.org/grpc/status"
    )
    
    type Server struct {
    	pb.UnimplementedPluginRegistryServiceServer
    	registry *PluginRegistry
    }
    
    func NewServer(registry *PluginRegistry) *Server {
    	return &Server{
    		registry: registry,
    	}
    }
    
    func (s *Server) Get(ctx context.Context, req *pb.GetRequest) (*pb.GetResponse, error) {
    	pluginResultSlice := make([]*pb.Plugin, 0)
    
    	for _, query := range req.Query {
    		var plugin *Plugin
    		var err error
    
    		switch x := query.Identifier.(type) {
    		case *pb.Query_Id:
    			id, err := uuid.Parse(x.Id)
    			if err != nil {
    				return nil, status.Errorf(codes.Aborted, "%v", err)
    			}
    			plugin, err = s.registry.GetPluginByID(id)
    			if err != nil {
    				return nil, status.Errorf(codes.Aborted, "%v", err)
    			}
    		case *pb.Query_Name:
    			plugin, err = s.registry.GetPluginByName(x.Name)
    			if err != nil {
    				return nil, status.Errorf(codes.Aborted, "%v", err)
    			}
    		case nil:
    			return nil, status.Errorf(codes.Aborted, "Query.Identifier is not set")
    		default:
    			return nil, status.Errorf(codes.Aborted, "Unsupported type for identifier: %T", x)
    		}
    		// add the found plugin to the result slice
    		pluginResultSlice = append(pluginResultSlice, pluginConverter(plugin))
    	}
    
    	return &pb.GetResponse{
    		Timestamp: time.Now().UnixNano(),
    		Plugins:   pluginResultSlice,
    	}, nil
    }
    
    
    func (s *Server) GetAll(ctx context.Context, req *pb.GetAllRequest) (*pb.GetResponse, error) {
    	pluginResultSlice := make([]*pb.Plugin, 0)
    	for _, plugin := range s.registry.Plugins {
    		pluginResultSlice = append(pluginResultSlice, pluginConverter(plugin))
    	}
    	return &pb.GetResponse{
    		Timestamp: time.Now().UnixNano(),
    		Plugins:   pluginResultSlice,
    	}, nil
    }
    
    
    func (s *Server) Download(req *pb.GetDownloadRequest, stream pb.PluginRegistryService_DownloadServer) (err error) {
    	var file *os.File
    	defer func() {
    		if ferr := file.Close(); ferr != nil {
    			fErrString := ferr.Error()
    			err = fmt.Errorf("InternalError=%w DeferError=%+s", err, fErrString)
    		}
    	}()
    
    	// validate if req.ID() is a valid uuid.UUID
    	idAsUUID, err := uuid.Parse(req.GetId())
    	if err != nil {
    		return status.Errorf(codes.Aborted, "%v", err)
    	}
    
    	plugin, err := s.registry.GetPluginByID(idAsUUID)
    	if err != nil {
    		return status.Errorf(codes.Aborted, "%v", err)
    	}
    
    	file, err = os.Open(plugin.Path)
    	if err != nil {
    		return status.Errorf(codes.Aborted, "%v", err)
    	}
    
    	// buffer of kilobyte
    	buffer := make([]byte, int(1<<(10*1)))
    
    	for {
    		n, err := file.Read(buffer)
    		if err != nil {
    			if errors.Is(err, io.EOF) {
    				fmt.Println(err)
    			}
    			break
    		}
    		log.WithField("n", n).Trace("read bytes")
    		payload := &pb.GetDownloadPayload{Chunk: buffer[:n]}
    		err = stream.Send(payload)
    		if err != nil {
    			return status.Errorf(codes.Aborted, "%v", err)
    		}
    	}
    	return nil
    }
    
    
    Malte Bauch's avatar
    Malte Bauch committed
    // Delete removes a plugin from the plugin registry.
    
    func (s *Server) Delete(ctx context.Context, req *pb.DeleteRequest) (*pb.DeleteResponse, error) {
    
    Malte Bauch's avatar
    Malte Bauch committed
    	return nil, status.Error(codes.Unimplemented, "The delete method is currently not implemented.")