Skip to content

Commit b633bee

Browse files
authored
Merge pull request #22 from SolaceDev/dev
Release v1.7.0
2 parents cd7f02d + 2f864c6 commit b633bee

63 files changed

Lines changed: 3800 additions & 383 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/test.yml

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,11 @@ jobs:
2525
run: go test -coverprofile ./unitcoverage.out ./...
2626
- name: Uploads artifacts
2727
if: ${{ always() }}
28-
uses: actions/upload-artifact@v2
28+
uses: actions/upload-artifact@v4
2929
with:
3030
path: |
3131
./unitcoverage.out
32+
overwrite: true
3233

3334
# this job runs linux based tests
3435
Linux:
@@ -39,6 +40,11 @@ jobs:
3940
steps:
4041
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
4142
- uses: actions/checkout@v2
43+
- name: Install Compose
44+
uses: ndeloof/install-compose-action@v0.0.1
45+
with:
46+
version: v2.29.1 # pinned to 'latest' as of 06/08/2024
47+
legacy: true # will also install in PATH as `docker-compose`
4248
- name: Setup Go environment
4349
uses: actions/setup-go@v2.1.3
4450
with:
@@ -104,16 +110,17 @@ jobs:
104110
run: |
105111
mkdir reports
106112
go install github.com/onsi/ginkgo/v2/ginkgo@v2.1.3
107-
ginkgo --junit-report=./reports/report.xml -coverprofile ./reports/coverage.out -coverpkg solace.dev/go/messaging/internal/...,solace.dev/go/messaging/pkg/... -tags enable_debug_logging
113+
ginkgo --junit-report=./reports/report.xml -coverprofile ./reports/coverage.out -coverpkg solace.dev/go/messaging/internal/...,solace.dev/go/messaging/pkg/... -tags enable_debug_logging --label-filter='!flaky-test'
108114
working-directory: ./test
109115

110116
- name: Uploads artifacts
111117
if: ${{ always() }}
112-
uses: actions/upload-artifact@v2
118+
uses: actions/upload-artifact@v4
113119
with:
114120
path: |
115121
./unitcoverage.out
116122
./test/reports/report.xml
117123
./test/reports/coverage.out
118124
./test/diagnostics.tgz
125+
overwrite: true
119126

Jenkinsfile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,15 @@ builder.goapi([
3939
"validationGoVer": 'auto-v1.17.x',
4040
"getTestPermutations": {
4141
List<List<String>> permutations = []
42-
for (platform in [builder.LINUX_ARM, builder.LINUX_X86_64, builder.LINUX_MUSL, builder.DARWIN_X86_64, builder.DARWIN_ARM]) {
42+
for (platform in [builder.LINUX_ARM, builder.LINUX_X86_64, builder.DARWIN_X86_64, builder.DARWIN_ARM]) {
4343
for (gover in ['auto-latest', 'auto-previous']) {
4444
permutations << [platform, gover]
4545
}
4646
}
47+
// run tests on the last stable Go version (1.22.4) for linux musl
48+
// See EBP-46
49+
// and this issue here - https://go-review.googlesource.com/c/go/+/600296
50+
permutations << [builder.LINUX_MUSL, 'auto-v1.22.4']
4751
return permutations
4852
}
4953
])

internal/ccsmp/ccsmp_container.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ func (opaqueContainer *SolClientOpaqueContainer) SolClientContainerGetNextField(
147147
if errorInfo != nil {
148148
// we expect and end of stream, but an error is logged if we fail
149149
if errorInfo.ReturnCode == SolClientReturnCodeFail {
150-
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetNextField: Unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode))
150+
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetNextField: Unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode()))
151151
}
152152
return "", fieldT, false
153153
}
@@ -172,7 +172,7 @@ func (opaqueContainer *SolClientOpaqueContainer) SolClientContainerGetField(key
172172
if errorInfo != nil {
173173
// we expect and end of stream, but an error is logged if we fail
174174
if errorInfo.ReturnCode == SolClientReturnCodeFail {
175-
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetField: unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode))
175+
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetField: unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode()))
176176
}
177177
return fieldT, false
178178
}

internal/ccsmp/ccsmp_core.go

Lines changed: 100 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -193,19 +193,46 @@ type SolClientResponseCode = C.solClient_session_responseCode_t
193193
// SolClientErrorInfoWrapper is assigned a value
194194
type SolClientErrorInfoWrapper C.solClient_errorInfo_wrapper_t
195195

196+
// SolClientErrorInfoWrapperDetailed is assigned a value
197+
type SolClientErrorInfoWrapperDetailed C.solClient_errorInfo_t
198+
196199
func (info *SolClientErrorInfoWrapper) String() string {
197200
if info == nil {
198201
return ""
199202
}
200-
return fmt.Sprintf("{ReturnCode: %d, SubCode: %d, ResponseCode: %d, ErrorStr: %s}", info.ReturnCode, info.SubCode, info.ResponseCode, info.GetMessageAsString())
203+
if info.DetailedErrorInfo == nil {
204+
return fmt.Sprintf("{ReturnCode: %d, SubCode: nil, ResponseCode: nil, ErrorStr: nil}", info.ReturnCode)
205+
}
206+
detailedErrorInfo := *(info.DetailedErrorInfo)
207+
return fmt.Sprintf("{ReturnCode: %d, SubCode: %d, ResponseCode: %d, ErrorStr: %s}",
208+
info.ReturnCode,
209+
detailedErrorInfo.subCode,
210+
detailedErrorInfo.responseCode,
211+
info.GetMessageAsString())
201212
}
202213

203214
// GetMessageAsString function outputs a string
204215
func (info *SolClientErrorInfoWrapper) GetMessageAsString() string {
205-
if len(info.ErrorStr) == 0 {
216+
if info.DetailedErrorInfo == nil || len(info.DetailedErrorInfo.errorStr) == 0 {
206217
return ""
207218
}
208-
return C.GoString((*C.char)(&info.ErrorStr[0]))
219+
return C.GoString((*C.char)(&info.DetailedErrorInfo.errorStr[0]))
220+
}
221+
222+
// SubCode function returns subcode if available
223+
func (info *SolClientErrorInfoWrapper) SubCode() SolClientSubCode {
224+
if info.DetailedErrorInfo != nil {
225+
return (*(info.DetailedErrorInfo)).subCode
226+
}
227+
return SolClientSubCode(0)
228+
}
229+
230+
// ResponseCode function returns response code if available
231+
func (info *SolClientErrorInfoWrapper) ResponseCode() SolClientResponseCode {
232+
if info.DetailedErrorInfo != nil {
233+
return (*(info.DetailedErrorInfo)).responseCode
234+
}
235+
return SolClientResponseCode(0)
209236
}
210237

211238
// Definition of structs returned from this package to be used externally
@@ -415,6 +442,21 @@ func (session *SolClientSession) SolClientSessionUnsubscribe(topic string, dispa
415442
return session.solClientSessionUnsubscribeWithFlags(topic, C.SOLCLIENT_SUBSCRIBE_FLAGS_REQUEST_CONFIRM, dispatchID, correlationID)
416443
}
417444

445+
// SolClientEndpointUnsusbcribe wraps solClient_session_endpointTopicUnsubscribe
446+
func (session *SolClientSession) SolClientEndpointUnsusbcribe(properties []string, topic string, correlationID uintptr) *SolClientErrorInfoWrapper {
447+
return handleCcsmpError(func() SolClientReturnCode {
448+
cString := C.CString(topic)
449+
defer C.free(unsafe.Pointer(cString))
450+
endpointProps, endpointFree := ToCArray(properties, true)
451+
defer endpointFree()
452+
return C.SessionTopicEndpointUnsubscribeWithFlags(session.pointer,
453+
endpointProps,
454+
C.SOLCLIENT_SUBSCRIBE_FLAGS_REQUEST_CONFIRM,
455+
cString,
456+
C.solClient_uint64_t(correlationID))
457+
})
458+
}
459+
418460
// SolClientEndpointProvision wraps solClient_session_endpointProvision
419461
func (session *SolClientSession) SolClientEndpointProvision(properties []string) *SolClientErrorInfoWrapper {
420462
return handleCcsmpError(func() SolClientReturnCode {
@@ -424,29 +466,54 @@ func (session *SolClientSession) SolClientEndpointProvision(properties []string)
424466
})
425467
}
426468

427-
// SolClientEndpointUnsusbcribe wraps solClient_session_endpointTopicUnsubscribe
428-
func (session *SolClientSession) SolClientEndpointUnsusbcribe(properties []string, topic string, correlationID uintptr) *SolClientErrorInfoWrapper {
469+
// SolClientEndpointProvisionWithFlags wraps solClient_session_endpointProvision
470+
func (session *SolClientSession) SolClientEndpointProvisionWithFlags(properties []string, flags C.solClient_uint32_t, correlationID uintptr) *SolClientErrorInfoWrapper {
429471
return handleCcsmpError(func() SolClientReturnCode {
430-
cString := C.CString(topic)
431-
defer C.free(unsafe.Pointer(cString))
432472
endpointProps, endpointFree := ToCArray(properties, true)
433473
defer endpointFree()
434-
return C.SessionTopicEndpointUnsubscribeWithFlags(session.pointer,
474+
return C.SessionEndpointProvisionWithFlags(session.pointer,
435475
endpointProps,
436-
C.SOLCLIENT_SUBSCRIBE_FLAGS_REQUEST_CONFIRM,
437-
cString,
476+
flags,
477+
C.solClient_uint64_t(correlationID))
478+
})
479+
}
480+
481+
// SolClientEndpointDeprovisionWithFlags wraps solClient_session_endpointDeprovision
482+
func (session *SolClientSession) SolClientEndpointDeprovisionWithFlags(properties []string, flags C.solClient_uint32_t, correlationID uintptr) *SolClientErrorInfoWrapper {
483+
return handleCcsmpError(func() SolClientReturnCode {
484+
endpointProps, endpointFree := ToCArray(properties, true)
485+
defer endpointFree()
486+
return C.SessionEndpointDeprovisionWithFlags(session.pointer,
487+
endpointProps,
488+
flags,
438489
C.solClient_uint64_t(correlationID))
439490
})
440491
}
441492

493+
// SolClientEndpointProvisionAsync wraps solClient_session_endpointProvision
494+
func (session *SolClientSession) SolClientEndpointProvisionAsync(properties []string, correlationID uintptr, ignoreExistErrors bool) *SolClientErrorInfoWrapper {
495+
if ignoreExistErrors {
496+
return session.SolClientEndpointProvisionWithFlags(properties, C.SOLCLIENT_PROVISION_FLAGS_IGNORE_EXIST_ERRORS, correlationID)
497+
}
498+
return session.SolClientEndpointProvisionWithFlags(properties, 0x0, correlationID) // no flag pass here
499+
}
500+
501+
// SolClientEndpointDeprovisionAsync wraps solClient_session_endpointDeprovision
502+
func (session *SolClientSession) SolClientEndpointDeprovisionAsync(properties []string, correlationID uintptr, ignoreMissingErrors bool) *SolClientErrorInfoWrapper {
503+
if ignoreMissingErrors {
504+
return session.SolClientEndpointDeprovisionWithFlags(properties, C.SOLCLIENT_PROVISION_FLAGS_IGNORE_EXIST_ERRORS, correlationID)
505+
}
506+
return session.SolClientEndpointDeprovisionWithFlags(properties, 0x0, correlationID) // no flag pass here
507+
}
508+
442509
// SolClientSessionGetRXStat wraps solClient_session_getRxStat
443510
func (session *SolClientSession) SolClientSessionGetRXStat(stat SolClientStatsRX) (value uint64) {
444511
err := handleCcsmpError(func() SolClientReturnCode {
445512
return C.solClient_session_getRxStat(session.pointer, C.solClient_stats_rx_t(stat), (C.solClient_stats_pt)(unsafe.Pointer(&value)))
446513
})
447514
// we should not in normal operation encounter an error fetching stats, but just in case...
448515
if err != nil {
449-
logging.Default.Warning("Encountered error loading core rx stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode))
516+
logging.Default.Warning("Encountered error loading core rx stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode()))
450517
}
451518
return value
452519
}
@@ -457,7 +524,7 @@ func (session *SolClientSession) SolClientSessionGetTXStat(stat SolClientStatsTX
457524
return C.solClient_session_getTxStat(session.pointer, C.solClient_stats_tx_t(stat), (C.solClient_stats_pt)(unsafe.Pointer(&value)))
458525
})
459526
if err != nil {
460-
logging.Default.Warning("Encountered error loading core stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode))
527+
logging.Default.Warning("Encountered error loading core stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode()))
461528
}
462529
return value
463530
}
@@ -581,17 +648,28 @@ func NewSessionReplyDispatch(id uint64) uintptr {
581648
return uintptr(id)
582649
}
583650

651+
// GetLastErrorInfoReturnCodeOnly returns a SolClientErrorInfoWrapper with only the ReturnCode field set.
652+
// This adds a function call on failure paths, but we'd be passing strings around in that case anyways and it should
653+
// happen rarely, so it's fine to slow it down a bit more if it means avoiding code duplication. See this function's
654+
// usage in GetLastErrorInfo() and handleCcsmpError to see where the duplicated code would otherwise have been.
655+
func GetLastErrorInfoReturnCodeOnly(returnCode SolClientReturnCode) *SolClientErrorInfoWrapper {
656+
errorInfo := &SolClientErrorInfoWrapper{}
657+
errorInfo.ReturnCode = returnCode
658+
return errorInfo
659+
}
660+
584661
// GetLastErrorInfo should NOT be called in most cases as it is dependent on the thread.
585662
// Unless you know that the goroutine running the code will not be interrupted, do NOT
586663
// call this function!
587664
func GetLastErrorInfo(returnCode SolClientReturnCode) *SolClientErrorInfoWrapper {
588-
errorInfo := &SolClientErrorInfoWrapper{}
589-
errorInfo.ReturnCode = returnCode
665+
errorInfo := GetLastErrorInfoReturnCodeOnly(returnCode)
590666
if returnCode != SolClientReturnCodeNotFound {
667+
detailedErrorInfo := C.solClient_errorInfo_t{}
591668
solClientErrorInfoPt := C.solClient_getLastErrorInfo()
592-
errorInfo.SubCode = solClientErrorInfoPt.subCode
593-
errorInfo.ResponseCode = solClientErrorInfoPt.responseCode
594-
C.strcpy((*C.char)(&errorInfo.ErrorStr[0]), (*C.char)(&solClientErrorInfoPt.errorStr[0]))
669+
detailedErrorInfo.subCode = solClientErrorInfoPt.subCode
670+
detailedErrorInfo.responseCode = solClientErrorInfoPt.responseCode
671+
C.strcpy((*C.char)(&detailedErrorInfo.errorStr[0]), (*C.char)(&solClientErrorInfoPt.errorStr[0]))
672+
errorInfo.DetailedErrorInfo = &detailedErrorInfo
595673
}
596674
return errorInfo
597675
}
@@ -609,8 +687,12 @@ func handleCcsmpError(f func() SolClientReturnCode) *SolClientErrorInfoWrapper {
609687
defer runtime.UnlockOSThread()
610688

611689
returnCode := f()
612-
if returnCode != SolClientReturnCodeOk && returnCode != SolClientReturnCodeInProgress {
690+
if returnCode == SolClientReturnCodeFail || returnCode == SolClientReturnCodeNotReady {
691+
// Return full error struct if rc requires additional error info.
613692
return GetLastErrorInfo(returnCode)
693+
} else if returnCode != SolClientReturnCodeOk && returnCode != SolClientReturnCodeInProgress {
694+
// Return partial error if not ok but not failure so that caller can parse on rc
695+
return GetLastErrorInfoReturnCodeOnly(returnCode)
614696
}
615697
return nil
616698
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// pubsubplus-go-client
2+
//
3+
// Copyright 2021-2024 Solace Corporation. All rights reserved.
4+
//
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
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
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.
16+
17+
package ccsmp
18+
19+
/*
20+
#include "solclient/solClient.h"
21+
*/
22+
import "C"
23+
24+
const (
25+
// SolClientEndpointPermissionNone: with no permissions
26+
SolClientEndpointPermissionNone = C.SOLCLIENT_ENDPOINT_PERM_NONE
27+
// SolClientEndpointPermissionReadOnly: with read-only permission
28+
SolClientEndpointPermissionReadOnly = C.SOLCLIENT_ENDPOINT_PERM_READ_ONLY
29+
// SolClientEndpointPermissionConsume: with consume permission
30+
SolClientEndpointPermissionConsume = C.SOLCLIENT_ENDPOINT_PERM_CONSUME
31+
// SolClientEndpointPermissionTopic: with Modify Topic permission
32+
SolClientEndpointPermissionModifyTopic = C.SOLCLIENT_ENDPOINT_PERM_MODIFY_TOPIC
33+
// SolClientEndpointPermissionDelete: with Delete (all) permissions
34+
SolClientEndpointPermissionDelete = C.SOLCLIENT_ENDPOINT_PERM_DELETE
35+
)

internal/ccsmp/ccsmp_endpoint_prop_generated.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/ccsmp/ccsmp_helper.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,3 +213,29 @@ SessionTopicEndpointUnsubscribeWithFlags( solClient_opaqueSession_pt opaqueSess
213213
topicSubscription_p,
214214
(void *)correlationTag);
215215
}
216+
217+
solClient_returnCode_t
218+
SessionEndpointProvisionWithFlags( solClient_opaqueSession_pt opaqueSession_p,
219+
solClient_propertyArray_pt endpointProps,
220+
solClient_uint32_t flags,
221+
solClient_uint64_t correlationTag)
222+
{
223+
return solClient_session_endpointProvision( endpointProps,
224+
opaqueSession_p,
225+
flags,
226+
(void *)correlationTag,
227+
NULL,
228+
0);
229+
}
230+
231+
solClient_returnCode_t
232+
SessionEndpointDeprovisionWithFlags( solClient_opaqueSession_pt opaqueSession_p,
233+
solClient_propertyArray_pt endpointProps,
234+
solClient_uint32_t flags,
235+
solClient_uint64_t correlationTag)
236+
{
237+
return solClient_session_endpointDeprovision( endpointProps,
238+
opaqueSession_p,
239+
flags,
240+
(void *)correlationTag);
241+
}

internal/ccsmp/ccsmp_helper.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,7 @@
2626
typedef struct solClient_errorInfo_wrapper
2727
{
2828
solClient_returnCode_t ReturnCode;
29-
solClient_subCode_t SubCode;
30-
solClient_session_responseCode_t ResponseCode;
31-
char ErrorStr[SOLCLIENT_ERRORINFO_STR_SIZE];
29+
solClient_errorInfo_t * DetailedErrorInfo;
3230
} solClient_errorInfo_wrapper_t;
3331

3432
/**
@@ -101,6 +99,18 @@ solClient_returnCode_t SessionTopicEndpointUnsubscribeWithFlags(
10199
const char *topicSubscription_p,
102100
solClient_uint64_t correlationTag);
103101

102+
solClient_returnCode_t SessionEndpointProvisionWithFlags(
103+
solClient_opaqueSession_pt opaqueSession_p,
104+
solClient_propertyArray_pt endpointProps,
105+
solClient_uint32_t flags,
106+
solClient_uint64_t correlationTag);
107+
108+
solClient_returnCode_t SessionEndpointDeprovisionWithFlags(
109+
solClient_opaqueSession_pt opaqueSession_p,
110+
solClient_propertyArray_pt endpointProps,
111+
solClient_uint32_t flags,
112+
solClient_uint64_t correlationTag);
113+
104114
/**
105115
* Definition of solclientgo correlation prefix
106116
*/

0 commit comments

Comments
 (0)