builder.go raw
1 /*
2 * Copyright 2017 Baidu, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
5 * except in compliance with the License. You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software distributed under the
10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
11 * either express or implied. See the License for the specific language governing permissions
12 * and limitations under the License.
13 */
14
15 // builder.go - defines the RequestBuilder structure for BCE servies
16
17 package bce
18
19 import (
20 "encoding/json"
21 "fmt"
22 )
23
24 // RequestBuilder holds config data for bce request.
25 // Some of fields are required and the others are optional.
26 // The builder pattern can simplify the execution of requests.
27 type RequestBuilder struct {
28 client Client
29
30 url string // required
31 method string // required
32 queryParams map[string]string // optional
33 headers map[string]string // optional
34 body interface{} // optional
35 result interface{} // optional
36 }
37
38 // create RequestBuilder with the client.
39 func NewRequestBuilder(client Client) *RequestBuilder {
40 return &RequestBuilder{
41 client: client,
42 }
43 }
44
45 func (b *RequestBuilder) WithURL(url string) *RequestBuilder {
46 b.url = url
47 return b
48 }
49
50 func (b *RequestBuilder) WithMethod(method string) *RequestBuilder {
51 b.method = method
52 return b
53 }
54
55 // set query param with the key/value directly.
56 func (b *RequestBuilder) WithQueryParam(key, value string) *RequestBuilder {
57 if b.queryParams == nil {
58 b.queryParams = make(map[string]string)
59 }
60 b.queryParams[key] = value
61 return b
62 }
63
64 // set query param with the key/value only when the value is not blank.
65 func (b *RequestBuilder) WithQueryParamFilter(key, value string) *RequestBuilder {
66 if len(value) == 0 {
67 return b
68 }
69 return b.WithQueryParam(key, value)
70 }
71
72 func (b *RequestBuilder) WithQueryParams(params map[string]string) *RequestBuilder {
73 if b.queryParams == nil {
74 b.queryParams = params
75 } else {
76 for key, value := range params {
77 b.queryParams[key] = value
78 }
79 }
80 return b
81 }
82
83 func (b *RequestBuilder) WithHeader(key, value string) *RequestBuilder {
84 if b.headers == nil {
85 b.headers = make(map[string]string)
86 }
87 b.headers[key] = value
88 return b
89 }
90
91 func (b *RequestBuilder) WithHeaders(headers map[string]string) *RequestBuilder {
92 if b.headers == nil {
93 b.headers = headers
94 } else {
95 for key, value := range headers {
96 b.headers[key] = value
97 }
98 }
99 return b
100 }
101
102 func (b *RequestBuilder) WithBody(body interface{}) *RequestBuilder {
103 b.body = body
104 return b
105 }
106
107 func (b *RequestBuilder) WithResult(result interface{}) *RequestBuilder {
108 b.result = result
109 return b
110 }
111
112 // Do will send request to bce and get result with the builder's parameters.
113 func (b *RequestBuilder) Do() error {
114 if err := b.validate(); err != nil {
115 return err
116 }
117
118 // build BceRequest
119 req, err := b.buildBceRequest()
120 if err != nil {
121 return err
122 }
123
124 // get result from BceResponse
125 if err := b.buildBceResponse(req); err != nil {
126 return err
127 }
128
129 return nil
130 }
131
132 // Validate if the required fields are providered.
133 func (b *RequestBuilder) validate() error {
134 if len(b.url) == 0 {
135 return fmt.Errorf("The url can't be null.")
136 }
137 if len(b.method) == 0 {
138 return fmt.Errorf("The method can't be null.")
139 }
140 if b.client == nil {
141 return fmt.Errorf("The client can't be null.")
142 }
143 return nil
144 }
145
146 func (b *RequestBuilder) buildBceRequest() (*BceRequest, error) {
147 // Build the request
148 req := &BceRequest{}
149 req.SetUri(b.url)
150 req.SetMethod(b.method)
151
152 if b.headers != nil {
153 req.SetHeaders(b.headers)
154 }
155 if b.queryParams != nil {
156 req.SetParams(b.queryParams)
157 }
158 if b.body != nil {
159 bodyBytes, err := json.Marshal(b.body)
160 if err != nil {
161 return nil, err
162 }
163 body, err := NewBodyFromBytes(bodyBytes)
164 if err != nil {
165 return nil, err
166 }
167 req.SetBody(body)
168 }
169
170 return req, nil
171 }
172
173 func (b *RequestBuilder) buildBceResponse(req *BceRequest) error {
174 // Send request and get response
175 resp := &BceResponse{}
176 if err := b.client.SendRequest(req, resp); err != nil {
177 return err
178 }
179 if resp.IsFail() {
180 return resp.ServiceError()
181 }
182 defer resp.Body().Close()
183
184 if b.result == nil {
185 return nil
186 }
187
188 return resp.ParseJsonBody(b.result)
189 }
190