Files
paralus/pkg/service/metro.go
2022-03-24 12:42:59 +05:30

239 lines
6.2 KiB
Go

package service
import (
"context"
"time"
"github.com/RafayLabs/rcloud-base/internal/dao"
"github.com/RafayLabs/rcloud-base/internal/models"
commonv3 "github.com/RafayLabs/rcloud-base/proto/types/commonpb/v3"
infrav3 "github.com/RafayLabs/rcloud-base/proto/types/infrapb/v3"
"github.com/google/uuid"
bun "github.com/uptrace/bun"
"google.golang.org/protobuf/types/known/timestamppb"
)
// MetroService is the interface for metro operations
type MetroService interface {
// create metro
Create(ctx context.Context, metro *infrav3.Location) (*infrav3.Location, error)
// get metro by id
GetById(ctx context.Context, id uuid.UUID) (*infrav3.Location, error)
// get metro by name
GetByName(ctx context.Context, name string) (*infrav3.Location, error)
// get metro id by name
GetIDByName(ctx context.Context, name string) (uuid.UUID, error)
// create or update metro
Update(ctx context.Context, metro *infrav3.Location) (*infrav3.Location, error)
// delete metro
Delete(ctx context.Context, metro *infrav3.Location) (*infrav3.Location, error)
// list metro
List(ctx context.Context, partner string) (*infrav3.LocationList, error)
}
// metroService implements MetroService
type metroService struct {
db *bun.DB
}
// NewProjectService return new project service
func NewMetroService(db *bun.DB) MetroService {
return &metroService{db}
}
func (s *metroService) Create(ctx context.Context, metro *infrav3.Location) (*infrav3.Location, error) {
var part models.Partner
_, err := dao.GetByName(ctx, s.db, metro.Metadata.Partner, &part)
if err != nil {
return nil, err
}
//convert v3 spec to internal models
metrodb := models.Metro{
Name: metro.Spec.Name,
CreatedAt: time.Now(),
ModifiedAt: time.Now(),
Trash: false,
Latitude: metro.Spec.Latitude,
Longitude: metro.Spec.Longitude,
City: metro.Spec.City,
State: metro.Spec.State,
Country: metro.Spec.Country,
CountryCode: metro.Spec.CountryCode,
StateCode: metro.Spec.StateCode,
OrganizationId: uuid.Nil,
PartnerId: part.ID,
}
_, err = dao.Create(ctx, s.db, &metrodb)
if err != nil {
return nil, err
}
return metro, nil
}
func (s *metroService) GetByName(ctx context.Context, name string) (*infrav3.Location, error) {
var metro infrav3.Location
entity, err := dao.GetByName(ctx, s.db, name, &models.Metro{})
if err != nil {
return nil, err
}
if metrodb, ok := entity.(*models.Metro); ok {
location := &infrav3.Location{
Metadata: &commonv3.Metadata{
Name: metrodb.Name,
ModifiedAt: timestamppb.New(metrodb.ModifiedAt),
},
Spec: &infrav3.Metro{
Name: metrodb.Name,
Country: metrodb.Country,
City: metrodb.City,
State: metrodb.State,
Latitude: metrodb.Latitude,
Longitude: metrodb.Longitude,
StateCode: metrodb.StateCode,
CountryCode: metrodb.CountryCode,
},
}
return location, nil
}
return &metro, nil
}
func (s *metroService) GetById(ctx context.Context, id uuid.UUID) (*infrav3.Location, error) {
var location infrav3.Location
entity, err := dao.GetByID(ctx, s.db, id, &models.Metro{})
if err != nil {
return nil, err
}
if metrodb, ok := entity.(*models.Metro); ok {
location := &infrav3.Location{
Metadata: &commonv3.Metadata{
Name: metrodb.Name,
ModifiedAt: timestamppb.New(metrodb.ModifiedAt),
},
Spec: &infrav3.Metro{
Name: metrodb.Name,
Country: metrodb.Country,
City: metrodb.City,
State: metrodb.State,
Latitude: metrodb.Latitude,
Longitude: metrodb.Longitude,
StateCode: metrodb.StateCode,
CountryCode: metrodb.CountryCode,
},
}
return location, nil
}
return &location, nil
}
func (s *metroService) Update(ctx context.Context, metro *infrav3.Location) (*infrav3.Location, error) {
entity, err := dao.GetByName(ctx, s.db, metro.Metadata.Name, &models.Metro{})
if err != nil {
return metro, err
}
if metrodb, ok := entity.(*models.Metro); ok {
//update metro details
metrodb.City = metro.Spec.City
metrodb.Country = metro.Spec.Country
metrodb.State = metro.Spec.State
metrodb.StateCode = metro.Spec.StateCode
metrodb.CountryCode = metro.Spec.CountryCode
metrodb.Latitude = metro.Spec.Latitude
metrodb.Longitude = metro.Spec.Longitude
metrodb.ModifiedAt = time.Now()
_, err = dao.Update(ctx, s.db, metrodb.ID, metrodb)
if err != nil {
return metro, err
}
}
return metro, nil
}
func (s *metroService) Delete(ctx context.Context, metro *infrav3.Location) (*infrav3.Location, error) {
entity, err := dao.GetByName(ctx, s.db, metro.Metadata.Name, &models.Metro{})
if err != nil {
return metro, err
}
if metrodb, ok := entity.(*models.Metro); ok {
err = dao.Delete(ctx, s.db, metrodb.ID, metrodb)
if err != nil {
return metro, err
}
}
return metro, nil
}
func (s *metroService) List(ctx context.Context, partner string) (*infrav3.LocationList, error) {
var locations infrav3.LocationList
var metros []*infrav3.Metro
var metrodbs []models.Metro
var part models.Partner
_, err := dao.GetByName(ctx, s.db, partner, &part)
if err != nil {
return nil, err
}
entities, err := dao.List(ctx, s.db, uuid.NullUUID{UUID: part.ID, Valid: true}, uuid.NullUUID{UUID: uuid.Nil, Valid: false}, &metrodbs)
if err != nil {
return nil, err
}
if metrodbs, ok := entities.(*[]models.Metro); ok {
for _, metrodb := range *metrodbs {
metro := &infrav3.Metro{
Name: metrodb.Name,
City: metrodb.City,
State: metrodb.State,
Country: metrodb.Country,
Latitude: metrodb.Latitude,
Longitude: metrodb.Longitude,
StateCode: metrodb.StateCode,
CountryCode: metrodb.CountryCode,
}
metros = append(metros, metro)
}
locations = infrav3.LocationList{
Metadata: &commonv3.ListMetadata{
Count: int64(len(metros)),
},
Items: metros,
}
}
return &locations, nil
}
func (s *metroService) GetIDByName(ctx context.Context, name string) (uuid.UUID, error) {
entity, err := dao.GetByName(ctx, s.db, name, &models.Metro{})
if err != nil {
return uuid.Nil, err
}
if metrodb, ok := entity.(*models.Metro); ok {
return metrodb.ID, nil
}
return uuid.Nil, nil
}