Connect to ActiveMQ via STOMP in Go - go

Trying to connect to ActiveMQ instance on AWS via github.com/go-stomp/stomp library.
The following code throws invalid command error:
func (s *STOMP) Init() error {
netConn, err := stomp.Dial("tcp", "host:61614")
if err != nil {
return errors.Wrap(err, "dial to server")
}
s.conn = netConn
return nil
}

AmazonMQ uses stomp+ssl proto, so the proper way to connect to it is to setup TLS connection on your own first:
func (s *STOMP) Init() error {
netConn, err := tls.Dial("tcp", "host:61614", &tls.Config{})
if err != nil {
return errors.Wrap(err, "dial tls")
}
stompConn, err := stomp.Connect(netConn)
if err != nil {
return errors.Wrap(err, "dial to server")
}
s.conn = stompConn
return nil
}
https://github.com/go-stomp/stomp/wiki/Connect-using-TLS

Related

Upload image fails with error "dial tcp: lookup api.cloudinary.com: no such host"

I have been trying to upload to cloudinary via golang sdk. but sometimes it seems to fail after several requests (sometimes it works, other times it doesn't).
I run the app in localhost (windows) and without vpn.
error message:
"https://api.cloudinary.com/v1_1/dd6mdlpgj/auto/upload": dial tcp: lookup api.cloudinary.com: no such host
type cloudinaryStorageRepository struct {
cld *cloudinary.Cloudinary
}
func NewCloudinaryStorageRepository(cloudName string, apiKey string, apiSecret string) domain.StorageRepository {
cld, err := cloudinary.NewFromParams(cloudName, apiKey, apiSecret)
if err != nil {
panic(err)
}
return &cloudinaryStorageRepository{cld}
}
func (c *cloudinaryStorageRepository) Upload(ctx context.Context, storage *domain.Storage) (string, error) {
file, err := storage.File.Open()
defer func(file multipart.File) {
err := file.Close()
if err != nil {
logrus.Error(err)
}
}(file)
if err != nil {
logrus.Error(err)
return "", err
}
uploaded, err := c.cld.Upload.Upload(ctx, file, uploader.UploadParams{
Folder: storage.Folder,
PublicID: storage.Name,
})
if err != nil {
logrus.Error(err)
return "", err
}
return uploaded.SecureURL, nil
}
If I understand you correctly, you can try to reset your DNS on your computer or use another computer to run the code because it might be a misconfiguration of your local host.

SMTP client using a remote SOCKS5/proxy in Go

I am trying to create an SMTP client that uses a proxy connection, SOCKS5.
When I use a local host proxy the code successfully creates an SMTP client.
When I try to use a remote proxy, I am getting a TTL expired. I am also getting an EOF error when trying to use a different proxy connection.
I have set up a proxy server in my localhost, socks5://dante:maluki#127.0.0.1:1080
I have also set up an identical proxy server on my remote VM, socks5://dante:maluki#35.242.186.23:1080
package main
import (
"errors"
"log"
"net"
"net/smtp"
"net/url"
"time"
"golang.org/x/net/idna"
"golang.org/x/net/proxy"
)
const (
smtpTimeout = time.Second * 60
smtpPort = ":25"
)
func init() {
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
func main() {
// The code works when I use a localhost proxy
// socks5://dante:maluki#127.0.0.1:1080
client, err := newSMTPClient("gmail.com", "socks5://dante:maluki#35.242.186.23:1080")
if err != nil {
log.Println(err)
return
}
log.Println(client)
}
// establishProxyConnection connects to the address on the named network address
// via proxy protocol
func establishProxyConnection(addr, proxyURI string) (net.Conn, error) {
// return socks.Dial(proxyURI)("tcp", addr)
u, err := url.Parse(proxyURI)
if err != nil {
log.Println(err)
return nil, err
}
var iface proxy.Dialer
if u.User != nil {
auth := proxy.Auth{}
auth.User = u.User.Username()
auth.Password, _ = u.User.Password()
iface, err = proxy.SOCKS5("tcp", u.Host, &auth, &net.Dialer{Timeout: 30 * time.Second})
if err != nil {
log.Println(err)
return nil, err
}
} else {
iface, err = proxy.SOCKS5("tcp", u.Host, nil, proxy.FromEnvironment())
if err != nil {
log.Println(err)
return nil, err
}
}
dialfunc := iface.Dial
return dialfunc("tcp", addr)
}
// newSMTPClient generates a new available SMTP client
func newSMTPClient(domain, proxyURI string) (*smtp.Client, error) {
domain = domainToASCII(domain)
mxRecords, err := net.LookupMX(domain)
if err != nil {
log.Println(err)
return nil, err
}
if len(mxRecords) == 0 {
return nil, errors.New("No MX records found")
}
// Attempt to connect to SMTP servers
for _, r := range mxRecords {
// Simplified to make the code short
addr := r.Host + smtpPort
c, err := dialSMTP(addr, proxyURI)
if err != nil {
log.Println(err)
continue
}
return c, err
}
return nil, errors.New("failed to created smtp.Client")
}
// dialSMTP is a timeout wrapper for smtp.Dial. It attempts to dial an
// SMTP server (socks5 proxy supported) and fails with a timeout if timeout is reached while
// attempting to establish a new connection
func dialSMTP(addr, proxyURI string) (*smtp.Client, error) {
// Channel holding the new smtp.Client or error
ch := make(chan interface{}, 1)
// Dial the new smtp connection
go func() {
var conn net.Conn
var err error
conn, err = establishProxyConnection(addr, proxyURI)
if err != nil {
log.Println(err)
}
if err != nil {
ch <- err
return
}
host, _, err := net.SplitHostPort(addr)
if err != nil {
log.Println(err)
}
client, err := smtp.NewClient(conn, host)
log.Println(client)
if err != nil {
log.Println(err)
ch <- err
return
}
ch <- client
}()
// Retrieve the smtp client from our client channel or timeout
select {
case res := <-ch:
switch r := res.(type) {
case *smtp.Client:
return r, nil
case error:
return nil, r
default:
return nil, errors.New("Unexpected response dialing SMTP server")
}
case <-time.After(smtpTimeout):
return nil, errors.New("Timeout connecting to mail-exchanger")
}
}
// domainToASCII converts any internationalized domain names to ASCII
// reference: https://en.wikipedia.org/wiki/Punycode
func domainToASCII(domain string) string {
asciiDomain, err := idna.ToASCII(domain)
if err != nil {
return domain
}
return asciiDomain
}

Getting error "failed to send packet header: EOF" while uploading file to sftp server

I am facing an issue where in, whenever I try to upload a file to a remote sftp server, I get an error saying "failed to send packet header: EOF". This occurs when I try to perform the uploading step from my own hosted EC2 instance. While locally, everything works fine.
Sftp client is initiated as follow.
// Connect to server
var authMethods []ssh.AuthMethod
// Use password authentication if password provided
if pass != "" {
authMethods = append(authMethods, ssh.Password(pass))
}
config := ssh.ClientConfig{
User: user,
Auth: authMethods,
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
}
conn, err := ssh.Dial("tcp", addr, &config)
if err != nil {
return nil, tearDown, errors.Wrap(err, fmt.Sprintf("failed to connect to %s", addr))
}
tearDown = func() {
_ = conn.Close()
}
// Create new SFTP client
sc, err := sftp.NewClient(conn)
if err != nil {
return nil, tearDown, errors.Wrap(err, "Unable to start SFTP subsystem")
}
tearDown = func() {
fmt.Println("defer is called. closing connection now .... ")
_ = conn.Close()
_ = sc.Close()
}
return sc, tearDown, nil
And instance of sc is attached to a struct and passed around the codebase
Function invoked while uploading file is as follow.
file, err := s.sc.OpenFile(remoteFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC)
defer func() {
if file == nil {
return
}
cErr := file.Close()
if cErr != nil {
fmt.Println(fmt.Sprintf("error while closing file %v", cErr))
}
}()
if err != nil {
fmt.Println(fmt.Sprintf("error while opening file %v", err))
return err
}
_, err = file.Write(data)
if err != nil {
fmt.Println(fmt.Sprintf("error while writing to file %v", err))
return err
}
return nil
Can someone guide me as in where is the error coming from?

Serving graphql server over GRPC server

I have below snippet to server the graphql server over http listener. Could you help me how I can do similar implementation with GRPC server? I mean serving graphQL server over grpc server?
func Run() {
var cfg AppConfig
cfg.ProductURL = "0.0.0.0:8001"
err := envconfig.Process("", &cfg)
if err != nil {
log.Fatal(err)
}
s, err := NewGraphQLServer(cfg.ProductURL)
if err != nil {
log.Fatal(err)
}
http.Handle("/graphql", handler.GraphQL(gql.NewExecutableSchema(gql.Config{
Resolvers: s,
})))
http.Handle("/playground", handler.Playground("test", "/graphql"))
log.Fatal(http.ListenAndServe(":8080", nil))
}
// NewGraphQLServer is to create get the connections to other services
func NewGraphQLServer(productURL string) (*resolvers.Resolver, error) {
// Connect to Product Service
productClient, err := service.NewProductClient(productURL)
if err != nil {
return nil, err
}
return &resolvers.Resolver{
ProductClient: productClient,
}, nil
}```

Sarama unable to produce message for Amazon MSK version 2.3.1

I was using sarama golang library for pushing the messages to Amazon MSK. Till now I was using msk version 2.2.1 my code was working fine, But now the msk version has been changed to 2.3.1. Now, I am unable to push the message to the Topic.
Error:
Partition -1
Offset -1
Request was for a topic or partition that does not exist on this broker.
Code:
func getKafkaEventClient() (sarama.Client, error) {
if !setupDone {
return nil, errors.New("Invalid setup")
}
if kafkaEventClient != nil {
return kafkaEventClient, nil
}
err := initKafkaEventClient()
if err != nil {
return nil, err
}
return kafkaEventClient, nil
}
func initKafkaEventClient() (err error) {
config := sarama.NewConfig()
config.Net.TLS.Enable = false
config.Producer.Return.Successes = true
config.Version = sarama.V0_10_0_0
brokers := strings.Split(kafkaEventHost, ",") //split the host into brokers
kafkaEventClient, err = sarama.NewClient(brokers, config)
if err != nil {
log.Println("initKafkaClient: failed to create new kafka client", err)
return
}
}
func PushMessageToKafka(message string) {
client, err := getKafkaEventClient()
if err != nil {
return
}
producer, err := sarama.NewSyncProducerFromClient(kafkaEventClient)
if err != nil {
fmt.Println("PushMessageToKafka: failed to get producer", err)
return
}
var msg sarama.ProducerMessage
msg.Topic = "some_topic"
msg.Value = sarama.StringEncoder("some_message")
p, o, err := producer.SendMessage(&msg)
fmt.Println("Partition", p)
fmt.Println("Offset", o)
if err != nil {
fmt.Println("PushMessageToKafka: failed to push message to be displayed", err)
}
}
I have changed the sarama version to maxVersion also config.Version = sarama.MaxVersion, but it is not working for Amazon MSK 2.3.1.
Please provide some solution.
I found the solution after debugging so many times.
It was not the version problem, in fact, the code which returns the client
func getKafkaEventClient() (sarama.Client, error) {
if !setupDone {
return nil, errors.New("Invalid setup")
}
if kafkaEventClient != nil {
return kafkaEventClient, nil
}
err := initKafkaEventClient()
if err != nil {
return nil, err
}
return kafkaEventClient, nil
}
Here if kafkaEventClient != nil then return the previous client which is wrong. For each client, if the broker/host is changing, then we have to create a new client and that client will be able to find the topic in which we want to push our message. If we are getting the old client and pushing the message to the topic which exists in different broker/host then we will get the error as I mentioned above.
Error:
Partition -1
Offset -1
Request was for a topic or partition that does not exist on this broker.
I hope it solves someone's problem who is facing the same issue.

Resources