Skip to content

Commit 0d481f2

Browse files
authored
Merge pull request #970 from jinlinGuan/bootstrap-issue-804
feat: use baseUrlFunc instead baseUrl for Clients
2 parents 8f6de19 + 3ce3929 commit 0d481f2

12 files changed

+704
-172
lines changed

clients/common.go

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (C) 2025 IOTech Ltd
2+
3+
package clients
4+
5+
import goErrors "errors"
6+
7+
type ClientBaseUrlFunc func() (string, error)
8+
9+
// GetDefaultClientBaseUrlFunc returns a ClientBaseUrlFunc that always returns the provided baseUrl.
10+
func GetDefaultClientBaseUrlFunc(baseUrl string) ClientBaseUrlFunc {
11+
return func() (string, error) {
12+
return baseUrl, nil
13+
}
14+
}
15+
16+
// GetBaseUrl retrieves the base URL using the provided ClientBaseUrlFunc.
17+
func GetBaseUrl(baseUrlFunc ClientBaseUrlFunc) (string, error) {
18+
if baseUrlFunc == nil {
19+
return "", goErrors.New("could not find ClientBaseUrlFunc to get base url")
20+
}
21+
return baseUrlFunc()
22+
}

clients/http/command.go

+43-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//
2-
// Copyright (C) 2021-2023 IOTech Ltd
2+
// Copyright (C) 2021-2025 IOTech Ltd
33
// Copyright (C) 2023 Intel Corporation
44
//
55
// SPDX-License-Identifier: Apache-2.0
@@ -11,6 +11,7 @@ import (
1111
"net/url"
1212
"strconv"
1313

14+
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients"
1415
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/http/utils"
1516
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/interfaces"
1617
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
@@ -20,15 +21,24 @@ import (
2021
)
2122

2223
type CommandClient struct {
23-
baseUrl string
24+
baseUrlFunc clients.ClientBaseUrlFunc
2425
authInjector interfaces.AuthenticationInjector
2526
enableNameFieldEscape bool
2627
}
2728

2829
// NewCommandClient creates an instance of CommandClient
2930
func NewCommandClient(baseUrl string, authInjector interfaces.AuthenticationInjector, enableNameFieldEscape bool) interfaces.CommandClient {
3031
return &CommandClient{
31-
baseUrl: baseUrl,
32+
baseUrlFunc: clients.GetDefaultClientBaseUrlFunc(baseUrl),
33+
authInjector: authInjector,
34+
enableNameFieldEscape: enableNameFieldEscape,
35+
}
36+
}
37+
38+
// NewCommandClientWithUrlCallback creates an instance of CommandClient with ClientBaseUrlFunc.
39+
func NewCommandClientWithUrlCallback(baseUrlFunc clients.ClientBaseUrlFunc, authInjector interfaces.AuthenticationInjector, enableNameFieldEscape bool) interfaces.CommandClient {
40+
return &CommandClient{
41+
baseUrlFunc: baseUrlFunc,
3242
authInjector: authInjector,
3343
enableNameFieldEscape: enableNameFieldEscape,
3444
}
@@ -40,7 +50,11 @@ func (client *CommandClient) AllDeviceCoreCommands(ctx context.Context, offset i
4050
requestParams := url.Values{}
4151
requestParams.Set(common.Offset, strconv.Itoa(offset))
4252
requestParams.Set(common.Limit, strconv.Itoa(limit))
43-
err = utils.GetRequest(ctx, &res, client.baseUrl, common.ApiAllDeviceRoute, requestParams, client.authInjector)
53+
baseUrl, goErr := clients.GetBaseUrl(client.baseUrlFunc)
54+
if goErr != nil {
55+
return res, errors.NewCommonEdgeXWrapper(goErr)
56+
}
57+
err = utils.GetRequest(ctx, &res, baseUrl, common.ApiAllDeviceRoute, requestParams, client.authInjector)
4458
if err != nil {
4559
return res, errors.NewCommonEdgeXWrapper(err)
4660
}
@@ -52,7 +66,11 @@ func (client *CommandClient) DeviceCoreCommandsByDeviceName(ctx context.Context,
5266
res responses.DeviceCoreCommandResponse, err errors.EdgeX) {
5367
path := common.NewPathBuilder().EnableNameFieldEscape(client.enableNameFieldEscape).
5468
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(name).BuildPath()
55-
err = utils.GetRequest(ctx, &res, client.baseUrl, path, nil, client.authInjector)
69+
baseUrl, goErr := clients.GetBaseUrl(client.baseUrlFunc)
70+
if goErr != nil {
71+
return res, errors.NewCommonEdgeXWrapper(goErr)
72+
}
73+
err = utils.GetRequest(ctx, &res, baseUrl, path, nil, client.authInjector)
5674
if err != nil {
5775
return res, errors.NewCommonEdgeXWrapper(err)
5876
}
@@ -66,7 +84,11 @@ func (client *CommandClient) IssueGetCommandByName(ctx context.Context, deviceNa
6684
requestParams.Set(common.ReturnEvent, strconv.FormatBool(dsReturnEvent))
6785
requestPath := common.NewPathBuilder().EnableNameFieldEscape(client.enableNameFieldEscape).
6886
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(deviceName).SetNameFieldPath(commandName).BuildPath()
69-
err = utils.GetRequest(ctx, &res, client.baseUrl, requestPath, requestParams, client.authInjector)
87+
baseUrl, goErr := clients.GetBaseUrl(client.baseUrlFunc)
88+
if goErr != nil {
89+
return res, errors.NewCommonEdgeXWrapper(goErr)
90+
}
91+
err = utils.GetRequest(ctx, &res, baseUrl, requestPath, requestParams, client.authInjector)
7092
if err != nil {
7193
return res, errors.NewCommonEdgeXWrapper(err)
7294
}
@@ -80,7 +102,11 @@ func (client *CommandClient) IssueGetCommandByNameWithQueryParams(ctx context.Co
80102
}
81103
requestPath := common.NewPathBuilder().EnableNameFieldEscape(client.enableNameFieldEscape).
82104
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(deviceName).SetNameFieldPath(commandName).BuildPath()
83-
err = utils.GetRequest(ctx, &res, client.baseUrl, requestPath, requestParams, client.authInjector)
105+
baseUrl, goErr := clients.GetBaseUrl(client.baseUrlFunc)
106+
if goErr != nil {
107+
return res, errors.NewCommonEdgeXWrapper(goErr)
108+
}
109+
err = utils.GetRequest(ctx, &res, baseUrl, requestPath, requestParams, client.authInjector)
84110
if err != nil {
85111
return res, errors.NewCommonEdgeXWrapper(err)
86112
}
@@ -91,7 +117,11 @@ func (client *CommandClient) IssueGetCommandByNameWithQueryParams(ctx context.Co
91117
func (client *CommandClient) IssueSetCommandByName(ctx context.Context, deviceName string, commandName string, settings map[string]string) (res dtoCommon.BaseResponse, err errors.EdgeX) {
92118
requestPath := common.NewPathBuilder().EnableNameFieldEscape(client.enableNameFieldEscape).
93119
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(deviceName).SetNameFieldPath(commandName).BuildPath()
94-
err = utils.PutRequest(ctx, &res, client.baseUrl, requestPath, nil, settings, client.authInjector)
120+
baseUrl, goErr := clients.GetBaseUrl(client.baseUrlFunc)
121+
if goErr != nil {
122+
return res, errors.NewCommonEdgeXWrapper(goErr)
123+
}
124+
err = utils.PutRequest(ctx, &res, baseUrl, requestPath, nil, settings, client.authInjector)
95125
if err != nil {
96126
return res, errors.NewCommonEdgeXWrapper(err)
97127
}
@@ -102,7 +132,11 @@ func (client *CommandClient) IssueSetCommandByName(ctx context.Context, deviceNa
102132
func (client *CommandClient) IssueSetCommandByNameWithObject(ctx context.Context, deviceName string, commandName string, settings map[string]interface{}) (res dtoCommon.BaseResponse, err errors.EdgeX) {
103133
requestPath := common.NewPathBuilder().EnableNameFieldEscape(client.enableNameFieldEscape).
104134
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(deviceName).SetNameFieldPath(commandName).BuildPath()
105-
err = utils.PutRequest(ctx, &res, client.baseUrl, requestPath, nil, settings, client.authInjector)
135+
baseUrl, goErr := clients.GetBaseUrl(client.baseUrlFunc)
136+
if goErr != nil {
137+
return res, errors.NewCommonEdgeXWrapper(goErr)
138+
}
139+
err = utils.PutRequest(ctx, &res, baseUrl, requestPath, nil, settings, client.authInjector)
106140
if err != nil {
107141
return res, errors.NewCommonEdgeXWrapper(err)
108142
}

clients/http/device.go

+68-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//
22
// Copyright (C) 2020-2021 Unknown author
33
// Copyright (C) 2023 Intel Corporation
4-
// Copyright (C) 2024 IOTech Ltd
4+
// Copyright (C) 2024-2025 IOTech Ltd
55
//
66
// SPDX-License-Identifier: Apache-2.0
77

@@ -13,6 +13,7 @@ import (
1313
"strconv"
1414
"strings"
1515

16+
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients"
1617
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/http/utils"
1718
"github.com/edgexfoundry/go-mod-core-contracts/v4/clients/interfaces"
1819
"github.com/edgexfoundry/go-mod-core-contracts/v4/common"
@@ -23,22 +24,35 @@ import (
2324
)
2425

2526
type DeviceClient struct {
26-
baseUrl string
27+
baseUrlFunc clients.ClientBaseUrlFunc
2728
authInjector interfaces.AuthenticationInjector
2829
enableNameFieldEscape bool
2930
}
3031

3132
// NewDeviceClient creates an instance of DeviceClient
3233
func NewDeviceClient(baseUrl string, authInjector interfaces.AuthenticationInjector, enableNameFieldEscape bool) interfaces.DeviceClient {
3334
return &DeviceClient{
34-
baseUrl: baseUrl,
35+
baseUrlFunc: clients.GetDefaultClientBaseUrlFunc(baseUrl),
36+
authInjector: authInjector,
37+
enableNameFieldEscape: enableNameFieldEscape,
38+
}
39+
}
40+
41+
// NewDeviceClientWithUrlCallback creates an instance of DeviceClient with ClientBaseUrlFunc.
42+
func NewDeviceClientWithUrlCallback(baseUrlFunc clients.ClientBaseUrlFunc, authInjector interfaces.AuthenticationInjector, enableNameFieldEscape bool) interfaces.DeviceClient {
43+
return &DeviceClient{
44+
baseUrlFunc: baseUrlFunc,
3545
authInjector: authInjector,
3646
enableNameFieldEscape: enableNameFieldEscape,
3747
}
3848
}
3949

4050
func (dc DeviceClient) Add(ctx context.Context, reqs []requests.AddDeviceRequest) (res []dtoCommon.BaseWithIdResponse, err errors.EdgeX) {
41-
err = utils.PostRequestWithRawData(ctx, &res, dc.baseUrl, common.ApiDeviceRoute, nil, reqs, dc.authInjector)
51+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
52+
if goErr != nil {
53+
return res, errors.NewCommonEdgeXWrapper(goErr)
54+
}
55+
err = utils.PostRequestWithRawData(ctx, &res, baseUrl, common.ApiDeviceRoute, nil, reqs, dc.authInjector)
4256
if err != nil {
4357
return res, errors.NewCommonEdgeXWrapper(err)
4458
}
@@ -50,15 +64,23 @@ func (dc DeviceClient) AddWithQueryParams(ctx context.Context, reqs []requests.A
5064
for k, v := range queryParams {
5165
requestParams.Set(k, v)
5266
}
53-
err = utils.PostRequestWithRawData(ctx, &res, dc.baseUrl, common.ApiDeviceRoute, requestParams, reqs, dc.authInjector)
67+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
68+
if goErr != nil {
69+
return res, errors.NewCommonEdgeXWrapper(goErr)
70+
}
71+
err = utils.PostRequestWithRawData(ctx, &res, baseUrl, common.ApiDeviceRoute, requestParams, reqs, dc.authInjector)
5472
if err != nil {
5573
return res, errors.NewCommonEdgeXWrapper(err)
5674
}
5775
return res, nil
5876
}
5977

6078
func (dc DeviceClient) Update(ctx context.Context, reqs []requests.UpdateDeviceRequest) (res []dtoCommon.BaseResponse, err errors.EdgeX) {
61-
err = utils.PatchRequest(ctx, &res, dc.baseUrl, common.ApiDeviceRoute, nil, reqs, dc.authInjector)
79+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
80+
if goErr != nil {
81+
return res, errors.NewCommonEdgeXWrapper(goErr)
82+
}
83+
err = utils.PatchRequest(ctx, &res, baseUrl, common.ApiDeviceRoute, nil, reqs, dc.authInjector)
6284
if err != nil {
6385
return res, errors.NewCommonEdgeXWrapper(err)
6486
}
@@ -70,7 +92,11 @@ func (dc DeviceClient) UpdateWithQueryParams(ctx context.Context, reqs []request
7092
for k, v := range queryParams {
7193
requestParams.Set(k, v)
7294
}
73-
err = utils.PatchRequest(ctx, &res, dc.baseUrl, common.ApiDeviceRoute, requestParams, reqs, dc.authInjector)
95+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
96+
if goErr != nil {
97+
return res, errors.NewCommonEdgeXWrapper(goErr)
98+
}
99+
err = utils.PatchRequest(ctx, &res, baseUrl, common.ApiDeviceRoute, requestParams, reqs, dc.authInjector)
74100
if err != nil {
75101
return res, errors.NewCommonEdgeXWrapper(err)
76102
}
@@ -84,7 +110,11 @@ func (dc DeviceClient) AllDevices(ctx context.Context, labels []string, offset i
84110
}
85111
requestParams.Set(common.Offset, strconv.Itoa(offset))
86112
requestParams.Set(common.Limit, strconv.Itoa(limit))
87-
err = utils.GetRequest(ctx, &res, dc.baseUrl, common.ApiAllDeviceRoute, requestParams, dc.authInjector)
113+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
114+
if goErr != nil {
115+
return res, errors.NewCommonEdgeXWrapper(goErr)
116+
}
117+
err = utils.GetRequest(ctx, &res, baseUrl, common.ApiAllDeviceRoute, requestParams, dc.authInjector)
88118
if err != nil {
89119
return res, errors.NewCommonEdgeXWrapper(err)
90120
}
@@ -100,7 +130,11 @@ func (dc DeviceClient) AllDevicesWithChildren(ctx context.Context, parent string
100130
requestParams.Set(common.MaxLevels, strconv.FormatUint(uint64(maxLevels), 10))
101131
requestParams.Set(common.Offset, strconv.Itoa(offset))
102132
requestParams.Set(common.Limit, strconv.Itoa(limit))
103-
err = utils.GetRequest(ctx, &res, dc.baseUrl, common.ApiAllDeviceRoute, requestParams, dc.authInjector)
133+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
134+
if goErr != nil {
135+
return res, errors.NewCommonEdgeXWrapper(goErr)
136+
}
137+
err = utils.GetRequest(ctx, &res, baseUrl, common.ApiAllDeviceRoute, requestParams, dc.authInjector)
104138
if err != nil {
105139
return res, errors.NewCommonEdgeXWrapper(err)
106140
}
@@ -110,7 +144,11 @@ func (dc DeviceClient) AllDevicesWithChildren(ctx context.Context, parent string
110144
func (dc DeviceClient) DeviceNameExists(ctx context.Context, name string) (res dtoCommon.BaseResponse, err errors.EdgeX) {
111145
path := common.NewPathBuilder().EnableNameFieldEscape(dc.enableNameFieldEscape).
112146
SetPath(common.ApiDeviceRoute).SetPath(common.Check).SetPath(common.Name).SetNameFieldPath(name).BuildPath()
113-
err = utils.GetRequest(ctx, &res, dc.baseUrl, path, nil, dc.authInjector)
147+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
148+
if goErr != nil {
149+
return res, errors.NewCommonEdgeXWrapper(goErr)
150+
}
151+
err = utils.GetRequest(ctx, &res, baseUrl, path, nil, dc.authInjector)
114152
if err != nil {
115153
return res, errors.NewCommonEdgeXWrapper(err)
116154
}
@@ -120,7 +158,11 @@ func (dc DeviceClient) DeviceNameExists(ctx context.Context, name string) (res d
120158
func (dc DeviceClient) DeviceByName(ctx context.Context, name string) (res responses.DeviceResponse, err errors.EdgeX) {
121159
path := common.NewPathBuilder().EnableNameFieldEscape(dc.enableNameFieldEscape).
122160
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(name).BuildPath()
123-
err = utils.GetRequest(ctx, &res, dc.baseUrl, path, nil, dc.authInjector)
161+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
162+
if goErr != nil {
163+
return res, errors.NewCommonEdgeXWrapper(goErr)
164+
}
165+
err = utils.GetRequest(ctx, &res, baseUrl, path, nil, dc.authInjector)
124166
if err != nil {
125167
return res, errors.NewCommonEdgeXWrapper(err)
126168
}
@@ -130,7 +172,11 @@ func (dc DeviceClient) DeviceByName(ctx context.Context, name string) (res respo
130172
func (dc DeviceClient) DeleteDeviceByName(ctx context.Context, name string) (res dtoCommon.BaseResponse, err errors.EdgeX) {
131173
path := common.NewPathBuilder().EnableNameFieldEscape(dc.enableNameFieldEscape).
132174
SetPath(common.ApiDeviceRoute).SetPath(common.Name).SetNameFieldPath(name).BuildPath()
133-
err = utils.DeleteRequest(ctx, &res, dc.baseUrl, path, dc.authInjector)
175+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
176+
if goErr != nil {
177+
return res, errors.NewCommonEdgeXWrapper(goErr)
178+
}
179+
err = utils.DeleteRequest(ctx, &res, baseUrl, path, dc.authInjector)
134180
if err != nil {
135181
return res, errors.NewCommonEdgeXWrapper(err)
136182
}
@@ -143,7 +189,11 @@ func (dc DeviceClient) DevicesByProfileName(ctx context.Context, name string, of
143189
requestParams := url.Values{}
144190
requestParams.Set(common.Offset, strconv.Itoa(offset))
145191
requestParams.Set(common.Limit, strconv.Itoa(limit))
146-
err = utils.GetRequest(ctx, &res, dc.baseUrl, requestPath, requestParams, dc.authInjector)
192+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
193+
if goErr != nil {
194+
return res, errors.NewCommonEdgeXWrapper(goErr)
195+
}
196+
err = utils.GetRequest(ctx, &res, baseUrl, requestPath, requestParams, dc.authInjector)
147197
if err != nil {
148198
return res, errors.NewCommonEdgeXWrapper(err)
149199
}
@@ -156,7 +206,11 @@ func (dc DeviceClient) DevicesByServiceName(ctx context.Context, name string, of
156206
requestParams := url.Values{}
157207
requestParams.Set(common.Offset, strconv.Itoa(offset))
158208
requestParams.Set(common.Limit, strconv.Itoa(limit))
159-
err = utils.GetRequest(ctx, &res, dc.baseUrl, requestPath, requestParams, dc.authInjector)
209+
baseUrl, goErr := clients.GetBaseUrl(dc.baseUrlFunc)
210+
if goErr != nil {
211+
return res, errors.NewCommonEdgeXWrapper(goErr)
212+
}
213+
err = utils.GetRequest(ctx, &res, baseUrl, requestPath, requestParams, dc.authInjector)
160214
if err != nil {
161215
return res, errors.NewCommonEdgeXWrapper(err)
162216
}

0 commit comments

Comments
 (0)