Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apricot/cacheproxy/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,11 @@ func (s Service) GetDetectorsForHosts(hosts []string) ([]string, error) {
return detList, nil
}

func (s Service) GetCRUCardsForHost(hostname string) (string, error) {
func (s Service) GetCRUCardsForHost(hostname string) ([]string, error) {
return s.base.GetCRUCardsForHost(hostname)
}

func (s Service) GetEndpointsForCRUCard(hostname, cardSerial string) (string, error) {
func (s Service) GetEndpointsForCRUCard(hostname, cardSerial string) ([]string, error) {
return s.base.GetEndpointsForCRUCard(hostname, cardSerial)
}

Expand Down
96 changes: 40 additions & 56 deletions apricot/local/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -351,24 +351,20 @@ func (s *Service) RawGetRecursive(path string) (string, error) {
func (s *Service) GetDetectorForHost(hostname string) (string, error) {
s.logMethod()

if cSrc, ok := s.src.(*cfgbackend.ConsulSource); ok {
keys, err := cSrc.GetKeysByPrefix(filepath.Join("o2/hardware", "detectors"))
if err != nil {
return "", err
}
for _, key := range keys {
// key example: o2/hardware/detectors/TST/flps/some-hostname/
splitKey := strings.Split(key, "/")
if len(splitKey) == 7 {
if splitKey[5] == hostname {
return splitKey[3], nil
}
keys, err := s.src.GetKeysByPrefix(filepath.Join("o2/hardware", "detectors"))
if err != nil {
return "", err
}
for _, key := range keys {
// key example: o2/hardware/detectors/TST/flps/some-hostname/
splitKey := strings.Split(key, "/")
if len(splitKey) == 7 {
if splitKey[5] == hostname {
return splitKey[3], nil
}
}
return "", fmt.Errorf("detector not found for host %s", hostname)
} else {
return "", errors.New("runtime KV not supported with file backend")
}
return "", fmt.Errorf("detector not found for host %s", hostname)
}

func (s *Service) GetDetectorsForHosts(hosts []string) ([]string, error) {
Expand All @@ -393,35 +389,27 @@ func (s *Service) GetDetectorsForHosts(hosts []string) ([]string, error) {
return detectorSlice, nil
}

func (s *Service) GetCRUCardsForHost(hostname string) (string, error) {
func (s *Service) GetCRUCardsForHost(hostname string) ([]string, error) {
s.logMethod()

if cSrc, ok := s.src.(*cfgbackend.ConsulSource); ok {
var cards map[string]Card
var serials []string
cfgCards, err := cSrc.Get(filepath.Join("o2/hardware", "flps", hostname, "cards"))
if err != nil {
return "", err
}
json.Unmarshal([]byte(cfgCards), &cards)
unique := make(map[string]bool)
for _, card := range cards {
if _, value := unique[card.Serial]; !value {
unique[card.Serial] = true
serials = append(serials, card.Serial)
}
}
bytes, err := json.Marshal(serials)
if err != nil {
return "", err
var cards map[string]Card
var serials []string
cfgCards, err := s.src.Get(filepath.Join("o2/hardware", "flps", hostname, "cards"))
if err != nil {
return nil, err
}
json.Unmarshal([]byte(cfgCards), &cards)
unique := make(map[string]bool)
for _, card := range cards {
if _, value := unique[card.Serial]; !value {
unique[card.Serial] = true
serials = append(serials, card.Serial)
}
return string(bytes), nil
} else {
return "", errors.New("runtime KV not supported with file backend")
}
return serials, nil
}

func (s *Service) GetEndpointsForCRUCard(hostname, cardSerial string) (string, error) {
func (s *Service) GetEndpointsForCRUCard(hostname, cardSerial string) ([]string, error) {
s.logMethod()

log.WithPrefix("rpcserver").
Expand All @@ -431,26 +419,22 @@ func (s *Service) GetEndpointsForCRUCard(hostname, cardSerial string) (string, e
WithField("cardSerial", cardSerial).
Debug("getting endpoints")

if cSrc, ok := s.src.(*cfgbackend.ConsulSource); ok {
var cards map[string]Card
var endpoints string
cfgCards, err := cSrc.Get(filepath.Join("o2/hardware", "flps", hostname, "cards"))
if err != nil {
return "", err
}
err = json.Unmarshal([]byte(cfgCards), &cards)
if err != nil {
return "", err
}
for _, card := range cards {
if card.Serial == cardSerial {
endpoints = endpoints + card.Endpoint + " "
}
var cards map[string]Card
var endpoints []string
cfgCards, err := s.src.Get(filepath.Join("o2/hardware", "flps", hostname, "cards"))
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(cfgCards), &cards)
if err != nil {
return nil, err
}
for _, card := range cards {
if card.Serial == cardSerial {
endpoints = append(endpoints, card.Endpoint)
}
return endpoints, nil
} else {
return "", errors.New("runtime KV not supported with file backend")
}
return endpoints, nil
}

func (s *Service) GetRuntimeEntry(component string, key string) (string, error) {
Expand Down
95 changes: 91 additions & 4 deletions apricot/local/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,98 @@ var _ = Describe("local service", func() {

})

Describe("getting detector for host", func() {
var (
detector string
err error
)
When("retrieving the detector for a host", func() {
It("should return the correct detector", func() {
detector, err = svc.GetDetectorForHost("flp001")
Expect(err).NotTo(HaveOccurred())
Expect(detector).To(Equal("ABC"))
})
})
When("retrieving the detector for a non-existing host", func() {
It("should produce an error", func() {
detector, err = svc.GetDetectorForHost("NOPE")
Expect(err).To(HaveOccurred())
})
})
})
Describe("getting detectors for hosts", func() {
var (
detectors []string
err error
)
When("retrieving the detectors for a list of hosts", func() {
It("should return the correct detectors", func() {
detectors, err = svc.GetDetectorsForHosts([]string{"flp001", "flp002"})
Expect(err).NotTo(HaveOccurred())
Expect(detectors).To(ContainElements("ABC", "DEF"))
})
})
When("retrieving the detectors for a non-existing host", func() {
It("should produce an error", func() {
detectors, err = svc.GetDetectorsForHosts([]string{"NOPE"})
Expect(err).To(HaveOccurred())
})
})
When("retrieving the detectors for a list of hosts with a non-existing host", func() {
It("should produce an error", func() {
detectors, err = svc.GetDetectorsForHosts([]string{"flp001", "NOPE"})
Expect(err).To(HaveOccurred())
})
})
})
Describe("getting CRU cards for a host", func() {
var (
cards []string
err error
)
When("retrieving the CRU cards for a host", func() {
It("should return the correct CRU cards", func() {
cards, err = svc.GetCRUCardsForHost("flp001")
Expect(err).NotTo(HaveOccurred())
Expect(cards).To(ContainElements("0228", "0229"))
})
})
When("retrieving the CRU cards for a non-existing host", func() {
It("should produce an error", func() {
cards, err = svc.GetCRUCardsForHost("NOPE")
Expect(err).To(HaveOccurred())
})
})
})
Describe("getting endpoints for a CRU card", func() {
var (
endpoints []string
err error
)
When("retrieving the endpoints for a CRU card", func() {
It("should return the correct endpoints", func() {
endpoints, err = svc.GetEndpointsForCRUCard("flp001", "0228")
Expect(err).NotTo(HaveOccurred())
Expect(endpoints).To(ContainElements("0", "1"))
})
})
When("retrieving the endpoints for a non-existing host", func() {
It("should produce an error", func() {
endpoints, err = svc.GetEndpointsForCRUCard("NOPE", "0228")
Expect(err).To(HaveOccurred())
})
})
When("retrieving the endpoints for a non-existing CRU card", func() {
// fixme: probably incorrect behaviour, but I don't want to risk breaking something
It("should not return an empty slice", func() {
endpoints, err = svc.GetEndpointsForCRUCard("flp001", "NOPE")
Expect(endpoints).To(BeEmpty())
Expect(err).NotTo(HaveOccurred())
})
})
})

// TODO:
// GetDetectorForHost (currently not supporting yaml backend)
// GetDetectorsForHosts (currently not supporting yaml backend)
// GetCRUCardsForHost (currently not supporting yaml backend)
// GetEndpointsForCRUCard (currently not supporting yaml backend)
// GetRuntimeEntry (currently not supporting yaml backend)
// SetRuntimeEntry (currently not supporting yaml backend)
// GetRuntimeEntries (currently not supporting yaml backend)
Expand Down
7 changes: 6 additions & 1 deletion apricot/local/service_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,12 @@ o2:
flps: {}
flps:
flp001:
cards: "{ \"key\" : \"value\" }"
cards: "{
\"0\": {\"serial\": \"0228\", \"endpoint\": \"0\"},
\"1\": {\"serial\": \"0229\", \"endpoint\": \"0\"},
\"2\": {\"serial\": \"0228\", \"endpoint\": \"1\"},
\"3\": {\"serial\": \"0229\", \"endpoint\": \"1\"}
}"
flp002:
cards: "{ \"key\" : \"value\" }"
flp003:
Expand Down
13 changes: 11 additions & 2 deletions apricot/remote/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ package remote

import (
"context"
"encoding/json"
"runtime"
"strings"

apricotpb "github.com/AliceO2Group/Control/apricot/protos"
"github.com/AliceO2Group/Control/common/logger"
Expand Down Expand Up @@ -253,7 +255,12 @@ func (m *RpcServer) GetCRUCardsForHost(_ context.Context, request *apricotpb.Hos
if err != nil {
return nil, err
}
return &apricotpb.CRUCardsResponse{Cards: cards}, E_OK.Err()
cardsJson, err := json.Marshal(cards)
if err != nil {
return nil, err
}

return &apricotpb.CRUCardsResponse{Cards: string(cardsJson)}, E_OK.Err()
}

func (m *RpcServer) GetEndpointsForCRUCard(_ context.Context, request *apricotpb.CardRequest) (*apricotpb.CRUCardEndpointResponse, error) {
Expand All @@ -269,7 +276,9 @@ func (m *RpcServer) GetEndpointsForCRUCard(_ context.Context, request *apricotpb
if err != nil {
return nil, err
}
return &apricotpb.CRUCardEndpointResponse{Endpoints: endpoints}, E_OK.Err()
endpointsSpaceSeparated := strings.Join(endpoints, " ")

return &apricotpb.CRUCardEndpointResponse{Endpoints: endpointsSpaceSeparated}, E_OK.Err()
}

func (m *RpcServer) GetRuntimeEntry(_ context.Context, request *apricotpb.GetRuntimeEntryRequest) (*apricotpb.ComponentResponse, error) {
Expand Down
22 changes: 16 additions & 6 deletions apricot/remote/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,11 @@ package remote

import (
"context"
"encoding/json"
"errors"
"fmt"
"net/url"
"strings"
"time"

apricotpb "github.com/AliceO2Group/Control/apricot/protos"
Expand Down Expand Up @@ -199,29 +201,37 @@ func (c *RemoteService) GetDetectorsForHosts(hosts []string) (payload []string,

}

func (c *RemoteService) GetCRUCardsForHost(hostname string) (cards string, err error) {
func (c *RemoteService) GetCRUCardsForHost(hostname string) (cards []string, err error) {
var response *apricotpb.CRUCardsResponse
request := &apricotpb.HostRequest{
Hostname: hostname,
}
response, err = c.cli.GetCRUCardsForHost(context.Background(), request, grpc.EmptyCallOption{})
if err != nil {
return "", err
return nil, err
}
cardsStr := response.GetCards()
err = json.Unmarshal([]byte(cardsStr), &cards)
if err != nil {
return nil, err
}
return response.GetCards(), nil

return cards, nil
}

func (c *RemoteService) GetEndpointsForCRUCard(hostname, cardSerial string) (cards string, err error) {
func (c *RemoteService) GetEndpointsForCRUCard(hostname, cardSerial string) (endpoints []string, err error) {
var response *apricotpb.CRUCardEndpointResponse
request := &apricotpb.CardRequest{
Hostname: hostname,
CardSerial: cardSerial,
}
response, err = c.cli.GetEndpointsForCRUCard(context.Background(), request, grpc.EmptyCallOption{})
if err != nil {
return "", err
return nil, err
}
return response.GetEndpoints(), nil
endpointsStr := response.GetEndpoints()
endpoints = strings.Split(endpointsStr, " ")
return endpoints, nil
}

func (c *RemoteService) GetRuntimeEntry(component string, key string) (payload string, err error) {
Expand Down
3 changes: 3 additions & 0 deletions common/gera/map.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ type Map[K comparable, V any] interface {
Set(key K, value V) bool
Del(key K) bool

// Flattened should return a flat representation of the tree in the root direction,
// where children kv pairs overwrite parent kv pairs.
Flattened() (map[K]V, error)
// FlattenedParent should return a flat representation of the tree in the root direction,
FlattenedParent() (map[K]V, error)
WrappedAndFlattened(m Map[K, V]) (map[K]V, error)

Expand Down
4 changes: 2 additions & 2 deletions configuration/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ type Service interface {

GetDetectorForHost(hostname string) (string, error)
GetDetectorsForHosts(hosts []string) ([]string, error)
GetCRUCardsForHost(hostname string) (string, error)
GetEndpointsForCRUCard(hostname, cardSerial string) (string, error)
GetCRUCardsForHost(hostname string) ([]string, error)
GetEndpointsForCRUCard(hostname, cardSerial string) ([]string, error)

RawGetRecursive(path string) (string, error)
}
2 changes: 1 addition & 1 deletion configuration/template/dplutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func extractConfigURIs(dplCommand string) (uris []string) {
// Match any consul/apricot URI
// it would be the easiest to use a backreference in the regex, but regexp does not support those:
// (['"]?)((consul-json|apricot)://[^ |\n]*)(\1)
re := regexp.MustCompile(`['"]?(consul-json|apricot)://[^ |\n]*`)
re := regexp.MustCompile(`['"]?(consul-json|apricot)://[^ |\n]+`)
matches := re.FindAllStringSubmatch(dplCommand, nMaxExpectedQcPayloads)

for _, match := range matches {
Expand Down
8 changes: 8 additions & 0 deletions configuration/template/dplutil_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ var _ = Describe("DPL utilities", func() {
Expect(uris).To(HaveLen(0))
})
})
When("URI is not complete", func() {
BeforeEach(func() {
uris = extractConfigURIs("myexe --config apricot://")
})
It("should return an empty slice", func() {
Expect(uris).To(HaveLen(0))
})
})
When("the URI is the last argument", func() {
BeforeEach(func() {
uris = extractConfigURIs("myexe --config apricot://host.cern.ch:12345/components/qc/ANY/any/ctp-raw")
Expand Down
Loading
Loading