Skip to content

Commit

Permalink
Merge pull request #22 from SolaceDev/dev
Browse files Browse the repository at this point in the history
Release v1.7.0
  • Loading branch information
oodigie authored Oct 24, 2024
2 parents cd7f02d + 2f864c6 commit b633bee
Show file tree
Hide file tree
Showing 63 changed files with 3,800 additions and 383 deletions.
13 changes: 10 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ jobs:
run: go test -coverprofile ./unitcoverage.out ./...
- name: Uploads artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
path: |
./unitcoverage.out
overwrite: true

# this job runs linux based tests
Linux:
Expand All @@ -39,6 +40,11 @@ jobs:
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Install Compose
uses: ndeloof/[email protected]
with:
version: v2.29.1 # pinned to 'latest' as of 06/08/2024
legacy: true # will also install in PATH as `docker-compose`
- name: Setup Go environment
uses: actions/[email protected]
with:
Expand Down Expand Up @@ -104,16 +110,17 @@ jobs:
run: |
mkdir reports
go install github.com/onsi/ginkgo/v2/[email protected]
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
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'
working-directory: ./test

- name: Uploads artifacts
if: ${{ always() }}
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
path: |
./unitcoverage.out
./test/reports/report.xml
./test/reports/coverage.out
./test/diagnostics.tgz
overwrite: true

6 changes: 5 additions & 1 deletion Jenkinsfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ builder.goapi([
"validationGoVer": 'auto-v1.17.x',
"getTestPermutations": {
List<List<String>> permutations = []
for (platform in [builder.LINUX_ARM, builder.LINUX_X86_64, builder.LINUX_MUSL, builder.DARWIN_X86_64, builder.DARWIN_ARM]) {
for (platform in [builder.LINUX_ARM, builder.LINUX_X86_64, builder.DARWIN_X86_64, builder.DARWIN_ARM]) {
for (gover in ['auto-latest', 'auto-previous']) {
permutations << [platform, gover]
}
}
// run tests on the last stable Go version (1.22.4) for linux musl
// See EBP-46
// and this issue here - https://go-review.googlesource.com/c/go/+/600296
permutations << [builder.LINUX_MUSL, 'auto-v1.22.4']
return permutations
}
])
4 changes: 2 additions & 2 deletions internal/ccsmp/ccsmp_container.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (opaqueContainer *SolClientOpaqueContainer) SolClientContainerGetNextField(
if errorInfo != nil {
// we expect and end of stream, but an error is logged if we fail
if errorInfo.ReturnCode == SolClientReturnCodeFail {
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetNextField: Unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode))
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetNextField: Unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode()))
}
return "", fieldT, false
}
Expand All @@ -172,7 +172,7 @@ func (opaqueContainer *SolClientOpaqueContainer) SolClientContainerGetField(key
if errorInfo != nil {
// we expect and end of stream, but an error is logged if we fail
if errorInfo.ReturnCode == SolClientReturnCodeFail {
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetField: unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode))
logging.Default.Debug(fmt.Sprintf("ccsmp.SolClientContainerGetField: unable to retrieve next field: %s, subcode: %d", errorInfo.GetMessageAsString(), errorInfo.SubCode()))
}
return fieldT, false
}
Expand Down
118 changes: 100 additions & 18 deletions internal/ccsmp/ccsmp_core.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,19 +193,46 @@ type SolClientResponseCode = C.solClient_session_responseCode_t
// SolClientErrorInfoWrapper is assigned a value
type SolClientErrorInfoWrapper C.solClient_errorInfo_wrapper_t

// SolClientErrorInfoWrapperDetailed is assigned a value
type SolClientErrorInfoWrapperDetailed C.solClient_errorInfo_t

func (info *SolClientErrorInfoWrapper) String() string {
if info == nil {
return ""
}
return fmt.Sprintf("{ReturnCode: %d, SubCode: %d, ResponseCode: %d, ErrorStr: %s}", info.ReturnCode, info.SubCode, info.ResponseCode, info.GetMessageAsString())
if info.DetailedErrorInfo == nil {
return fmt.Sprintf("{ReturnCode: %d, SubCode: nil, ResponseCode: nil, ErrorStr: nil}", info.ReturnCode)
}
detailedErrorInfo := *(info.DetailedErrorInfo)
return fmt.Sprintf("{ReturnCode: %d, SubCode: %d, ResponseCode: %d, ErrorStr: %s}",
info.ReturnCode,
detailedErrorInfo.subCode,
detailedErrorInfo.responseCode,
info.GetMessageAsString())
}

// GetMessageAsString function outputs a string
func (info *SolClientErrorInfoWrapper) GetMessageAsString() string {
if len(info.ErrorStr) == 0 {
if info.DetailedErrorInfo == nil || len(info.DetailedErrorInfo.errorStr) == 0 {
return ""
}
return C.GoString((*C.char)(&info.ErrorStr[0]))
return C.GoString((*C.char)(&info.DetailedErrorInfo.errorStr[0]))
}

// SubCode function returns subcode if available
func (info *SolClientErrorInfoWrapper) SubCode() SolClientSubCode {
if info.DetailedErrorInfo != nil {
return (*(info.DetailedErrorInfo)).subCode
}
return SolClientSubCode(0)
}

// ResponseCode function returns response code if available
func (info *SolClientErrorInfoWrapper) ResponseCode() SolClientResponseCode {
if info.DetailedErrorInfo != nil {
return (*(info.DetailedErrorInfo)).responseCode
}
return SolClientResponseCode(0)
}

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

// SolClientEndpointUnsusbcribe wraps solClient_session_endpointTopicUnsubscribe
func (session *SolClientSession) SolClientEndpointUnsusbcribe(properties []string, topic string, correlationID uintptr) *SolClientErrorInfoWrapper {
return handleCcsmpError(func() SolClientReturnCode {
cString := C.CString(topic)
defer C.free(unsafe.Pointer(cString))
endpointProps, endpointFree := ToCArray(properties, true)
defer endpointFree()
return C.SessionTopicEndpointUnsubscribeWithFlags(session.pointer,
endpointProps,
C.SOLCLIENT_SUBSCRIBE_FLAGS_REQUEST_CONFIRM,
cString,
C.solClient_uint64_t(correlationID))
})
}

// SolClientEndpointProvision wraps solClient_session_endpointProvision
func (session *SolClientSession) SolClientEndpointProvision(properties []string) *SolClientErrorInfoWrapper {
return handleCcsmpError(func() SolClientReturnCode {
Expand All @@ -424,29 +466,54 @@ func (session *SolClientSession) SolClientEndpointProvision(properties []string)
})
}

// SolClientEndpointUnsusbcribe wraps solClient_session_endpointTopicUnsubscribe
func (session *SolClientSession) SolClientEndpointUnsusbcribe(properties []string, topic string, correlationID uintptr) *SolClientErrorInfoWrapper {
// SolClientEndpointProvisionWithFlags wraps solClient_session_endpointProvision
func (session *SolClientSession) SolClientEndpointProvisionWithFlags(properties []string, flags C.solClient_uint32_t, correlationID uintptr) *SolClientErrorInfoWrapper {
return handleCcsmpError(func() SolClientReturnCode {
cString := C.CString(topic)
defer C.free(unsafe.Pointer(cString))
endpointProps, endpointFree := ToCArray(properties, true)
defer endpointFree()
return C.SessionTopicEndpointUnsubscribeWithFlags(session.pointer,
return C.SessionEndpointProvisionWithFlags(session.pointer,
endpointProps,
C.SOLCLIENT_SUBSCRIBE_FLAGS_REQUEST_CONFIRM,
cString,
flags,
C.solClient_uint64_t(correlationID))
})
}

// SolClientEndpointDeprovisionWithFlags wraps solClient_session_endpointDeprovision
func (session *SolClientSession) SolClientEndpointDeprovisionWithFlags(properties []string, flags C.solClient_uint32_t, correlationID uintptr) *SolClientErrorInfoWrapper {
return handleCcsmpError(func() SolClientReturnCode {
endpointProps, endpointFree := ToCArray(properties, true)
defer endpointFree()
return C.SessionEndpointDeprovisionWithFlags(session.pointer,
endpointProps,
flags,
C.solClient_uint64_t(correlationID))
})
}

// SolClientEndpointProvisionAsync wraps solClient_session_endpointProvision
func (session *SolClientSession) SolClientEndpointProvisionAsync(properties []string, correlationID uintptr, ignoreExistErrors bool) *SolClientErrorInfoWrapper {
if ignoreExistErrors {
return session.SolClientEndpointProvisionWithFlags(properties, C.SOLCLIENT_PROVISION_FLAGS_IGNORE_EXIST_ERRORS, correlationID)
}
return session.SolClientEndpointProvisionWithFlags(properties, 0x0, correlationID) // no flag pass here
}

// SolClientEndpointDeprovisionAsync wraps solClient_session_endpointDeprovision
func (session *SolClientSession) SolClientEndpointDeprovisionAsync(properties []string, correlationID uintptr, ignoreMissingErrors bool) *SolClientErrorInfoWrapper {
if ignoreMissingErrors {
return session.SolClientEndpointDeprovisionWithFlags(properties, C.SOLCLIENT_PROVISION_FLAGS_IGNORE_EXIST_ERRORS, correlationID)
}
return session.SolClientEndpointDeprovisionWithFlags(properties, 0x0, correlationID) // no flag pass here
}

// SolClientSessionGetRXStat wraps solClient_session_getRxStat
func (session *SolClientSession) SolClientSessionGetRXStat(stat SolClientStatsRX) (value uint64) {
err := handleCcsmpError(func() SolClientReturnCode {
return C.solClient_session_getRxStat(session.pointer, C.solClient_stats_rx_t(stat), (C.solClient_stats_pt)(unsafe.Pointer(&value)))
})
// we should not in normal operation encounter an error fetching stats, but just in case...
if err != nil {
logging.Default.Warning("Encountered error loading core rx stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode))
logging.Default.Warning("Encountered error loading core rx stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode()))
}
return value
}
Expand All @@ -457,7 +524,7 @@ func (session *SolClientSession) SolClientSessionGetTXStat(stat SolClientStatsTX
return C.solClient_session_getTxStat(session.pointer, C.solClient_stats_tx_t(stat), (C.solClient_stats_pt)(unsafe.Pointer(&value)))
})
if err != nil {
logging.Default.Warning("Encountered error loading core stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode))
logging.Default.Warning("Encountered error loading core stat: " + err.GetMessageAsString() + ", subcode " + fmt.Sprint(err.SubCode()))
}
return value
}
Expand Down Expand Up @@ -581,17 +648,28 @@ func NewSessionReplyDispatch(id uint64) uintptr {
return uintptr(id)
}

// GetLastErrorInfoReturnCodeOnly returns a SolClientErrorInfoWrapper with only the ReturnCode field set.
// This adds a function call on failure paths, but we'd be passing strings around in that case anyways and it should
// happen rarely, so it's fine to slow it down a bit more if it means avoiding code duplication. See this function's
// usage in GetLastErrorInfo() and handleCcsmpError to see where the duplicated code would otherwise have been.
func GetLastErrorInfoReturnCodeOnly(returnCode SolClientReturnCode) *SolClientErrorInfoWrapper {
errorInfo := &SolClientErrorInfoWrapper{}
errorInfo.ReturnCode = returnCode
return errorInfo
}

// GetLastErrorInfo should NOT be called in most cases as it is dependent on the thread.
// Unless you know that the goroutine running the code will not be interrupted, do NOT
// call this function!
func GetLastErrorInfo(returnCode SolClientReturnCode) *SolClientErrorInfoWrapper {
errorInfo := &SolClientErrorInfoWrapper{}
errorInfo.ReturnCode = returnCode
errorInfo := GetLastErrorInfoReturnCodeOnly(returnCode)
if returnCode != SolClientReturnCodeNotFound {
detailedErrorInfo := C.solClient_errorInfo_t{}
solClientErrorInfoPt := C.solClient_getLastErrorInfo()
errorInfo.SubCode = solClientErrorInfoPt.subCode
errorInfo.ResponseCode = solClientErrorInfoPt.responseCode
C.strcpy((*C.char)(&errorInfo.ErrorStr[0]), (*C.char)(&solClientErrorInfoPt.errorStr[0]))
detailedErrorInfo.subCode = solClientErrorInfoPt.subCode
detailedErrorInfo.responseCode = solClientErrorInfoPt.responseCode
C.strcpy((*C.char)(&detailedErrorInfo.errorStr[0]), (*C.char)(&solClientErrorInfoPt.errorStr[0]))
errorInfo.DetailedErrorInfo = &detailedErrorInfo
}
return errorInfo
}
Expand All @@ -609,8 +687,12 @@ func handleCcsmpError(f func() SolClientReturnCode) *SolClientErrorInfoWrapper {
defer runtime.UnlockOSThread()

returnCode := f()
if returnCode != SolClientReturnCodeOk && returnCode != SolClientReturnCodeInProgress {
if returnCode == SolClientReturnCodeFail || returnCode == SolClientReturnCodeNotReady {
// Return full error struct if rc requires additional error info.
return GetLastErrorInfo(returnCode)
} else if returnCode != SolClientReturnCodeOk && returnCode != SolClientReturnCodeInProgress {
// Return partial error if not ok but not failure so that caller can parse on rc
return GetLastErrorInfoReturnCodeOnly(returnCode)
}
return nil
}
Expand Down
35 changes: 35 additions & 0 deletions internal/ccsmp/ccsmp_endpoint_permissions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// pubsubplus-go-client
//
// Copyright 2021-2024 Solace Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ccsmp

/*
#include "solclient/solClient.h"
*/
import "C"

const (
// SolClientEndpointPermissionNone: with no permissions
SolClientEndpointPermissionNone = C.SOLCLIENT_ENDPOINT_PERM_NONE
// SolClientEndpointPermissionReadOnly: with read-only permission
SolClientEndpointPermissionReadOnly = C.SOLCLIENT_ENDPOINT_PERM_READ_ONLY
// SolClientEndpointPermissionConsume: with consume permission
SolClientEndpointPermissionConsume = C.SOLCLIENT_ENDPOINT_PERM_CONSUME
// SolClientEndpointPermissionTopic: with Modify Topic permission
SolClientEndpointPermissionModifyTopic = C.SOLCLIENT_ENDPOINT_PERM_MODIFY_TOPIC
// SolClientEndpointPermissionDelete: with Delete (all) permissions
SolClientEndpointPermissionDelete = C.SOLCLIENT_ENDPOINT_PERM_DELETE
)
2 changes: 1 addition & 1 deletion internal/ccsmp/ccsmp_endpoint_prop_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 26 additions & 0 deletions internal/ccsmp/ccsmp_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,3 +213,29 @@ SessionTopicEndpointUnsubscribeWithFlags( solClient_opaqueSession_pt opaqueSess
topicSubscription_p,
(void *)correlationTag);
}

solClient_returnCode_t
SessionEndpointProvisionWithFlags( solClient_opaqueSession_pt opaqueSession_p,
solClient_propertyArray_pt endpointProps,
solClient_uint32_t flags,
solClient_uint64_t correlationTag)
{
return solClient_session_endpointProvision( endpointProps,
opaqueSession_p,
flags,
(void *)correlationTag,
NULL,
0);
}

solClient_returnCode_t
SessionEndpointDeprovisionWithFlags( solClient_opaqueSession_pt opaqueSession_p,
solClient_propertyArray_pt endpointProps,
solClient_uint32_t flags,
solClient_uint64_t correlationTag)
{
return solClient_session_endpointDeprovision( endpointProps,
opaqueSession_p,
flags,
(void *)correlationTag);
}
16 changes: 13 additions & 3 deletions internal/ccsmp/ccsmp_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
typedef struct solClient_errorInfo_wrapper
{
solClient_returnCode_t ReturnCode;
solClient_subCode_t SubCode;
solClient_session_responseCode_t ResponseCode;
char ErrorStr[SOLCLIENT_ERRORINFO_STR_SIZE];
solClient_errorInfo_t * DetailedErrorInfo;
} solClient_errorInfo_wrapper_t;

/**
Expand Down Expand Up @@ -101,6 +99,18 @@ solClient_returnCode_t SessionTopicEndpointUnsubscribeWithFlags(
const char *topicSubscription_p,
solClient_uint64_t correlationTag);

solClient_returnCode_t SessionEndpointProvisionWithFlags(
solClient_opaqueSession_pt opaqueSession_p,
solClient_propertyArray_pt endpointProps,
solClient_uint32_t flags,
solClient_uint64_t correlationTag);

solClient_returnCode_t SessionEndpointDeprovisionWithFlags(
solClient_opaqueSession_pt opaqueSession_p,
solClient_propertyArray_pt endpointProps,
solClient_uint32_t flags,
solClient_uint64_t correlationTag);

/**
* Definition of solclientgo correlation prefix
*/
Expand Down
Loading

0 comments on commit b633bee

Please sign in to comment.