TIBCO FTL® Go Quick Start
Contents
- Getting Started
- Building and running samples
- Description of sample applications
- Using the FTL SDK
- Connecting to TIBCO Cloud Messaging
- Publishing a message
- Subscribing and receiving messages
- Cleanup
- Related Links
Getting Started
This quick start guide provides basic instructions for writing TIBCO FTL applications in Go for TIBCO Cloud™ Messaging.
Follow the steps below to use the sample applications:
- Download and install the TIBCO FTL Messaging SDK and sample applications for Go. This guide refers to your FTL installation location as
<ftl>
. - The FTL samples require Go 1.19 or later.
- Download a client configuration file using the roles REST API or user interface.
- Review the FTL API documentation.
Building and running samples
Follow the steps below to build and run the Go samples. The Go samples are implemented as a Go module. Dependencies are defined in the included go.mod
files.
The FTL Go SDK requires GCC to compile (CGO).
Linux and macOS
- Unzip
ftl-go-samples.zip
- Source FTL setup script:
source <ftl>/samples/setup
- Change into module directory:
cd ftl-go-samples/tcm/samples/ftl
- Set GOBIN:
export GOBIN=$PWD/bin
- Copy FTL Go source to the current directory:
cp -r <ftl>/samples/src/golang/src/tibco.com/ftl .
- Generate vendor directory:
go mod tidy
thengo mod vendor
- Build and install binaries:
go install tibco.com/tcm/samples/ftl...
- Use
-f
option to specify the configuration file. - Run sample:
$GOBIN/tcmdemopub -f <path-to>/tcm-config.yaml
Windows
- Ensure you have mingw64 (5.3 or later) installed and gcc is in your PATH
- Unzip
ftl-go-samples.zip
- Run FTL setup script:
<ftl>\samples\setup.bat
- Change into module directory:
cd ftl-go-samples\tcm\samples\ftl
- Set GOBIN:
set GOBIN=%CD%\bin
- Copy FTL Go source to the current directory:
xcopy /E /I <ftl>\samples\src\golang\src\tibco.com\ftl ftl
- Generate vendor directory:
go mod tidy
thengo mod vendor
- Build and install binaries:
go install tibco.com/tcm/samples/ftl...
- Use
-f
option to specify the configuration file - Run sample:
%GOBIN%\tcmdemopub -f <path-to>/tcm-config.yaml
Description of sample applications
Publisher
The publisher demonstrates connecting an FTL Go application to Cloud Messaging and publishing FTL messages:
Usage of tcmdemopub:
-c int
the number of messages to send before exiting (default -1)
-f string
the path to a configuration yaml (default "tcm-config.yaml")
-i duration
the duration between sends, e.g. 500ms, 1s, etc. (default 1s)
-id string
client id (default "tcmdemopub")
-t duration
duration before timeout, e.g. 1h, 5m, 10s, etc.
Subscriber
The consumer demonstrates connecting an FTL Go application to Cloud Messaging, creating a subscription, and receiving FTL messages:
Usage of tcmdemosub:
-c int
the number of messages to send before exiting (default -1)
-durable string
durable name (default "tcmdemosub.go")
-f string
the path to a configuration yaml (default "tcm-config.yaml")
-id string
client id (default "tcmdemosub.go")
-t duration
duration before timeout, e.g. 1h, 5m, 10s, etc.
Run the Subscriber and Publisher at the same time to demonstrate real-time messaging. Stop the Subscriber, run the Publisher, and restart the Subscriber to demonstrate persistence.
Using the FTL SDK
To use the FTL SDK include the library and any third-party dependencies in your source files:
import "tibco.com/ftl"
import "gopkg.in/yaml.v3"
CGO
FTL GO applications depend on native C libraries (CGO). Instructions for configuring CGO can be found in the GO sample directory of the GO SDK download.
Connecting to TIBCO Cloud Messaging
The client configuration file contains all the information client applications need to securely connect to TIBCO Cloud Messaging. Generate the client configuration file using the roles REST API or user interface. Generate as many configuration files as needed for each Role.
Note: TIBCO Cloud Messaging samples require a client configuration file to run.
TIBCO FTL Server Validation
TIBCO FTL applications cannot use their host’s certificate pool to automatically validate TIBCO Cloud Messaging servers. For server verification to work, TIBCO FTL applications must supply the value of ftl_certificate
as the server certificate when connecting to TIBCO Cloud Messaging. The value of ftl_certificate
can be found in the configuration file.
Connection Example
realmProps = make(ftl.Props)
realmProps[ftl.RealmPropertyStringClientLabel] = "tcmdemopub.go"
realmProps[ftl.RealmPropertyStringUsername] = options.AuthID
realmProps[ftl.RealmPropertyStringUserpassword] = options.AuthKey
realmProps[ftl.RealmPropertyLongTrustType] = ftl.RealmHTTPSConnectionUseSpecifiedTrustString
realmProps[ftl.RealmPropertyStringTrustPemString] = options.Cert
realm, err := ftl.Connect(options.FtlURL, options.AppName, realmProps)
Publishing a message
Before a message can be published, the publisher must be created on the previously-created realm. Specify the endpoint onto which the messages will be published. In this example we are using the “default” endpoint.
pub, err := realm.NewPublisher("default", nil)
In order to send a message, the message object must first be created via a call to realm.CreateMessage()
. Specify the format name. Here the format “demo_tcm” is used. TCM only supports dynamic formats.
msg, err := realm.NewMessage("demo_tcm")
A newly-created message is empty - it contains no fields. The next step is to add one or more fields to the message. msg.SetString
adds a string field. In this example a string field named demo_tcm
is added, with the value seq
.
content := struct {
DemoTcm string `ftl:"demo_tcm"`
}{
DemoTcm: fmt.Sprintf("message %d", seq),
}
err = msg.Marshal(&content)
Once the message is complete, it can be sent via pub.Send
. Specify the message to be sent.
err = pub.Send(msg)
Subscribing and receiving messages
For messages to be delivered to a client application, three things are required:
- An event queue.
- A message channel.
- A subscriber.
Event Queue
An event queue is required to facilitate message dispatching. Since creating the queue object implicitly also creates a thread from which to dispatch the queue, an error channel is used to notify the client application of any errors detected by the event queue dispatch thread.
errChan := make(chan error)
queue, err = realm.NewQueue(errChan, nil)
Message Channel
Messages are delivered to the client application through a channel. This channel must be created by the client application, and provided to the event queue when creating a subscriber. This is analogous to specifying the message delivery callback function in the C API. Continuing with the analogy, specifying separate message delivery callback functions for different subscribers in the C API would require creating and servicing multiple channels in go.
msgChan := make(chan ftl.Message)
Subscriber
Create the subscriber object by specifying the endpoint name, an optional content matcher, an optional properties object and the message channel.
sub, err = queue.Subscribe("default", matcher, subscriberProps, msgChan)
Endpoints
TIBCO Cloud Messaging only supports a fixed set of endpoints: default
, shared
, last-value
and map
. Each endpoint is associated with a durable type of the same name. If your application does not need persistence use the default endpoint.
Content Matcher
A content matcher is used to limit which messages are delivered to a client application based on the content
of the message. In this case, {"demo_tcm":true}
matches any message which contains the field demo_tcm
.
matcher := `{"demo_tcm":true}`
Subscriber Properties
A shared durable essentially acts like a queue. Messages are stored in the persistent server, and apportioned among active subscribers to the durable in a round-robin fashion. Each subscriber must specify the same durable name. The durable name is defined by properties specified when the subscriber is created. If your application does not need persistence do not supply a durable name.
subscriberProps := make(ftl.Props)
subscriberProps[ftl.SubscriberPropertyStringDurableName] = "tcmdemosub.go"
Subscribing to Notifications
All asynchronous events are communicated from the FTL API to go via channels. This includes message delivery and notifications.
notificationChan := make(chan ftl.Notification)
realm.SetNotificatonChannel(notificationChan)
Dispatching
signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
Loop:
for {
select {
case err := <-errChan:
log.Printf("received message on error channel: %s", err)
break Loop
case note := <-notificationChan:
log.Printf("received message on notification channel: %s", note)
break Loop
case <-signals:
break Loop
case msg := <-msgChan:
content := struct {
DemoTcm string `ftl:"demo_tcm"`
}{}
err := msg.Unmarshal(&content)
if err != nil {
log.Fatal(ftl.ErrStack(err))
}
log.Printf("Received %v\n", msg)
}
}
Cleanup
Once objects are no longer needed, they should be disposed of - and generally in reverse order of creation.
Publisher
msg.Destroy();
pub.Close()
realm.Close();
Subscriber
queue.CloseSubscription(sub)
close(msgChan)
queue.Destroy()
close(errChan)
realm.Close();
To permanently destroy a durable subscription, including any messages stored by TIBCO Cloud Messaging for that durable, first close the subscription and then call unsubscribe using the realm object. Supply the unsubscribe call with the endpoint name and durable name used to create the durable subscription.
queue.CloseSubscription(sub)
realm.Unsubscribe("default", "tcmdemosub.go")