blob: 7c5508bc0cf4d30a08cbb5dd829d8e863172a7ab [file] [log] [blame]
khenaidooab1f7bd2019-11-14 14:00:27 -05001/*
2 * Copyright 2019-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Matteo Scandolod525ae32020-04-02 17:27:29 -070016package kafka
khenaidooab1f7bd2019-11-14 14:00:27 -050017
18import (
19 "fmt"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080020 "sync"
Scott Baker504b4802020-04-17 10:12:20 -070021 "time"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080022
23 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
24 "github.com/opencord/voltha-lib-go/v3/pkg/log"
25 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
khenaidooab1f7bd2019-11-14 14:00:27 -050026 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
khenaidooab1f7bd2019-11-14 14:00:27 -050028)
29
npujar467fe752020-01-16 20:17:45 +053030// static check to ensure KafkaClient implements kafka.Client
31var _ kafka.Client = &KafkaClient{}
32
khenaidooab1f7bd2019-11-14 14:00:27 -050033type KafkaClient struct {
34 topicsChannelMap map[string][]chan *ic.InterContainerMessage
35 lock sync.RWMutex
36}
37
38func NewKafkaClient() *KafkaClient {
39 return &KafkaClient{
40 topicsChannelMap: make(map[string][]chan *ic.InterContainerMessage),
41 lock: sync.RWMutex{},
42 }
43}
44
45func (kc *KafkaClient) Start() error {
serkant.uluderya2ae470f2020-01-21 11:13:09 -080046 logger.Debug("kafka-client-started")
khenaidooab1f7bd2019-11-14 14:00:27 -050047 return nil
48}
49
50func (kc *KafkaClient) Stop() {
51 kc.lock.Lock()
52 defer kc.lock.Unlock()
53 for topic, chnls := range kc.topicsChannelMap {
54 for _, c := range chnls {
55 close(c)
56 }
57 delete(kc.topicsChannelMap, topic)
58 }
serkant.uluderya2ae470f2020-01-21 11:13:09 -080059 logger.Debug("kafka-client-stopped")
khenaidooab1f7bd2019-11-14 14:00:27 -050060}
61
62func (kc *KafkaClient) CreateTopic(topic *kafka.Topic, numPartition int, repFactor int) error {
serkant.uluderya2ae470f2020-01-21 11:13:09 -080063 logger.Debugw("CreatingTopic", log.Fields{"topic": topic.Name, "numPartition": numPartition, "replicationFactor": repFactor})
khenaidooab1f7bd2019-11-14 14:00:27 -050064 kc.lock.Lock()
65 defer kc.lock.Unlock()
66 if _, ok := kc.topicsChannelMap[topic.Name]; ok {
67 return fmt.Errorf("Topic %s already exist", topic.Name)
68 }
69 ch := make(chan *ic.InterContainerMessage)
70 kc.topicsChannelMap[topic.Name] = append(kc.topicsChannelMap[topic.Name], ch)
71 return nil
72}
73
74func (kc *KafkaClient) DeleteTopic(topic *kafka.Topic) error {
serkant.uluderya2ae470f2020-01-21 11:13:09 -080075 logger.Debugw("DeleteTopic", log.Fields{"topic": topic.Name})
khenaidooab1f7bd2019-11-14 14:00:27 -050076 kc.lock.Lock()
77 defer kc.lock.Unlock()
78 delete(kc.topicsChannelMap, topic.Name)
79 return nil
80}
81
82func (kc *KafkaClient) Subscribe(topic *kafka.Topic, kvArgs ...*kafka.KVArg) (<-chan *ic.InterContainerMessage, error) {
serkant.uluderya2ae470f2020-01-21 11:13:09 -080083 logger.Debugw("Subscribe", log.Fields{"topic": topic.Name, "args": kvArgs})
khenaidooab1f7bd2019-11-14 14:00:27 -050084 kc.lock.Lock()
85 defer kc.lock.Unlock()
86 ch := make(chan *ic.InterContainerMessage)
87 kc.topicsChannelMap[topic.Name] = append(kc.topicsChannelMap[topic.Name], ch)
88 return ch, nil
89}
90
91func removeChannel(s []chan *ic.InterContainerMessage, i int) []chan *ic.InterContainerMessage {
92 s[i] = s[len(s)-1]
93 return s[:len(s)-1]
94}
95
96func (kc *KafkaClient) UnSubscribe(topic *kafka.Topic, ch <-chan *ic.InterContainerMessage) error {
serkant.uluderya2ae470f2020-01-21 11:13:09 -080097 logger.Debugw("UnSubscribe", log.Fields{"topic": topic.Name})
khenaidooab1f7bd2019-11-14 14:00:27 -050098 kc.lock.Lock()
99 defer kc.lock.Unlock()
100 if chnls, ok := kc.topicsChannelMap[topic.Name]; ok {
101 idx := -1
102 for i, c := range chnls {
103 if c == ch {
104 close(c)
105 idx = i
106 }
107 }
108 if idx >= 0 {
109 kc.topicsChannelMap[topic.Name] = removeChannel(kc.topicsChannelMap[topic.Name], idx)
110 }
111 }
112 return nil
113}
114
Scott Baker504b4802020-04-17 10:12:20 -0700115func (kc *KafkaClient) SubscribeForMetadata(_ func(fromTopic string, timestamp time.Time)) {
Kent Hagerman16ce36a2019-12-17 13:40:53 -0500116 logger.Debug("SubscribeForMetadata - unimplemented")
npujar467fe752020-01-16 20:17:45 +0530117}
118
khenaidooab1f7bd2019-11-14 14:00:27 -0500119func (kc *KafkaClient) Send(msg interface{}, topic *kafka.Topic, keys ...string) error {
120 req, ok := msg.(*ic.InterContainerMessage)
121 if !ok {
122 return status.Error(codes.InvalidArgument, "msg-not-InterContainerMessage-type")
123 }
124 if req == nil {
125 return status.Error(codes.InvalidArgument, "msg-nil")
126 }
127 kc.lock.RLock()
128 defer kc.lock.RUnlock()
129 for _, ch := range kc.topicsChannelMap[topic.Name] {
serkant.uluderya2ae470f2020-01-21 11:13:09 -0800130 logger.Debugw("Publishing", log.Fields{"fromTopic": req.Header.FromTopic, "toTopic": topic.Name, "id": req.Header.Id})
khenaidooab1f7bd2019-11-14 14:00:27 -0500131 ch <- req
132 }
133 return nil
134}
135
136func (kc *KafkaClient) SendLiveness() error {
137 return status.Error(codes.Unimplemented, "SendLiveness")
138}
139
140func (kc *KafkaClient) EnableLivenessChannel(enable bool) chan bool {
Kent Hagerman16ce36a2019-12-17 13:40:53 -0500141 logger.Debug("EnableLivenessChannel - unimplemented")
khenaidooab1f7bd2019-11-14 14:00:27 -0500142 return nil
143}
serkant.uluderya2ae470f2020-01-21 11:13:09 -0800144
145func (kc *KafkaClient) EnableHealthinessChannel(enable bool) chan bool {
Kent Hagerman16ce36a2019-12-17 13:40:53 -0500146 logger.Debug("EnableHealthinessChannel - unimplemented")
serkant.uluderya2ae470f2020-01-21 11:13:09 -0800147 return nil
148}