2 * Copyright (C) 2017-2019 "IoT.bzh"
3 * Author Sebastien Douheret <sebastien@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
26 common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git"
27 uuid "github.com/satori/go.uuid"
31 type XdsMonitoring struct {
40 client *common.HTTPClient
42 cbOnConnect OnConnectedXdsSupervCB
45 // XdsSuperVTraceConfig
46 type XdsSuperVTraceConfig struct {
48 Pids []int `json:"pids"`
49 WsName string `json:"ws"`
52 // OnConnectedXdsSupervCB connect callback
53 type OnConnectedXdsSupervCB func(svr *XdsMonitoring) error
55 // NewXdsMonitoring creates an instance of XdsMonitoring
56 func NewXdsMonitoring(ctx *Context) *XdsMonitoring {
57 return &XdsMonitoring{
59 ID: "XdsMonitoring-" + uuid.NewV1().String(),
60 BaseURL: ctx.Config.FileConf.ProfileConf.XDSMonitoring.URL,
61 ConnRetry: ctx.Config.FileConf.ProfileConf.XDSMonitoring.ConnRetry,
69 // Connect Establish HTTP connection with XDS Monitoring Dameon
70 func (xs *XdsMonitoring) Connect() error {
78 for retry = xs.ConnRetry; retry > 0; retry-- {
79 if err = xs._CreateConnectHTTP(); err == nil {
82 if retry == xs.ConnRetry {
83 // Notify only on the first conn error
84 // doing that avoid 2 notifs (conn false; conn true) on startup
87 xs.Log.Infof("Establishing connection to XDS Monitoring daemon (retry %d/%d)", retry, xs.ConnRetry)
88 time.Sleep(time.Second)
91 // FIXME: re-use _Reconnect to wait longer in background
92 return fmt.Errorf("Connection to XDS Monitoring daemon failure")
98 // Check HTTP connection and establish WS connection
99 err = xs._Connect(false)
104 // ConnectOn Register a callback on events reception
105 func (xs *XdsMonitoring) ConnectOn(f OnConnectedXdsSupervCB) error {
110 // GetVersion Send Get request to retrieve XDS Monitoring version
111 func (xs *XdsMonitoring) GetVersion(res interface{}) error {
112 // FIXME add suffix URLSuffix in common HTTP client lib instead of _BuildURL
113 return xs.client.Get(xs._BuildURL("/version"), &res)
116 // GetTopo Send Get request to retrieve Services/Daemons topology
117 func (xs *XdsMonitoring) GetTopo(res interface{}) error {
118 return xs.client.Get(xs._BuildURL("/list"), &res)
121 // StartTrace Send Monitoring config and start tracing
122 func (xs *XdsMonitoring) StartTrace(cfg XdsSuperVTraceConfig, res interface{}) error {
123 return xs.client.Post(xs._BuildURL("/trace/start"), cfg, &res)
126 // StopTrace Send Monitoring stop tracing
127 func (xs *XdsMonitoring) StopTrace(res interface{}) error {
129 return xs.client.Post(xs._BuildURL("/trace/stop"), cfg, res)
137 func (xs *XdsMonitoring) _BuildURL(url string) string {
138 return url + "?token=HELLO&uuid=magic"
141 // Create HTTP client
142 func (xs *XdsMonitoring) _CreateConnectHTTP() error {
144 // FIXME SEB - Client key not in header but in cookie
145 // temporary workaround: used _BuildURL to append uuid=magic in URL
146 // map[Set-Cookie:[x-afb-uuid-5678=2b185cc3-276b-4097-91fa-d607eaf937e6; Path=/api; Max-Age=32000000; ...
147 //port := strings.Split(xs.BaseURL, ":")[2]
148 //"x-afb-uuid-" + port
150 xs.client, err = common.HTTPNewClient(xs.BaseURL,
151 common.HTTPClientConfig{
152 //HeaderClientKeyName: "Xds-Sid",
153 HeaderAPIKeyName: "token",
155 URLPrefix: "/api/xds",
158 LogPrefix: "XDSSUPERV: ",
159 LogLevel: common.HTTPLogLevelWarning,
162 xs.client.SetLogLevel(xs.Log.Level.String())
165 msg := ": " + err.Error()
166 if strings.Contains(err.Error(), "connection refused") {
167 msg = fmt.Sprintf("(url: %s)", xs.BaseURL)
169 return fmt.Errorf("ERROR: cannot connect to XDS Monitoring %s", msg)
171 if xs.client == nil {
172 return fmt.Errorf("ERROR: cannot connect to XDS Monitoring (null client)")
178 // _Connect Established HTTP and WS connection
179 func (xs *XdsMonitoring) _Connect(reConn bool) error {
182 if err := xs.client.Get(xs._BuildURL("/ping"), &res); err != nil {
192 // Call OnConnect callback
193 if xs.cbOnConnect != nil {
201 // _NotifyState Send event to notify changes
202 func (xs *XdsMonitoring) _NotifyState() {
205 evSts := xaapiv1.ServerCfg{
209 PartialURL: xs.PartialURL,
210 ConnRetry: xs.ConnRetry,
211 Connected: xs.Connected,
213 if err := xs.events.Emit(xaapiv1.EVTServerConfig, evSts, ""); err != nil {
214 xs.Log.Warningf("Cannot notify XdsServer state change: %v", err)