1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
package vespa
import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"time"
"github.com/vespa-engine/vespa/client/go/version"
)
type customTarget struct {
targetType string
baseURL string
}
type serviceConvergeResponse struct {
Converged bool `json:"converged"`
}
// LocalTarget creates a target for a Vespa platform running locally.
func LocalTarget() Target {
return &customTarget{targetType: TargetLocal, baseURL: "http://127.0.0.1"}
}
// CustomTarget creates a Target for a Vespa platform running at baseURL.
func CustomTarget(baseURL string) Target {
return &customTarget{targetType: TargetCustom, baseURL: baseURL}
}
func (t *customTarget) Type() string { return t.targetType }
func (t *customTarget) Deployment() Deployment { return Deployment{} }
func (t *customTarget) createService(name string) (*Service, error) {
switch name {
case DeployService, QueryService, DocumentService:
url, err := t.urlWithPort(name)
if err != nil {
return nil, err
}
return &Service{BaseURL: url, Name: name}, nil
}
return nil, fmt.Errorf("unknown service: %s", name)
}
func (t *customTarget) Service(name string, timeout time.Duration, sessionOrRunID int64, cluster string) (*Service, error) {
service, err := t.createService(name)
if err != nil {
return nil, err
}
if timeout > 0 {
if name == DeployService {
status, err := service.Wait(timeout)
if err != nil {
return nil, err
}
if !isOK(status) {
return nil, fmt.Errorf("got status %d from deploy service at %s", status, service.BaseURL)
}
} else {
if err := t.waitForConvergence(timeout); err != nil {
return nil, err
}
}
}
return service, nil
}
func (t *customTarget) PrintLog(options LogOptions) error {
return fmt.Errorf("reading logs from non-cloud deployment is unsupported")
}
func (t *customTarget) SignRequest(req *http.Request, sigKeyId string) error { return nil }
func (t *customTarget) CheckVersion(version version.Version) error { return nil }
func (t *customTarget) urlWithPort(serviceName string) (string, error) {
u, err := url.Parse(t.baseURL)
if err != nil {
return "", err
}
port := u.Port()
if port == "" {
switch serviceName {
case DeployService:
port = "19071"
case QueryService, DocumentService:
port = "8080"
default:
return "", fmt.Errorf("unknown service: %s", serviceName)
}
u.Host = u.Host + ":" + port
}
return u.String(), nil
}
func (t *customTarget) waitForConvergence(timeout time.Duration) error {
deployURL, err := t.urlWithPort(DeployService)
if err != nil {
return err
}
url := fmt.Sprintf("%s/application/v2/tenant/default/application/default/environment/prod/region/default/instance/default/serviceconverge", deployURL)
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return err
}
converged := false
convergedFunc := func(status int, response []byte) (bool, error) {
if !isOK(status) {
return false, nil
}
var resp serviceConvergeResponse
if err := json.Unmarshal(response, &resp); err != nil {
return false, nil
}
converged = resp.Converged
return converged, nil
}
if _, err := wait(convergedFunc, func() *http.Request { return req }, nil, timeout); err != nil {
return err
}
if !converged {
return fmt.Errorf("services have not converged")
}
return nil
}
|