EOF when connecting to IBM MQ with AMQP 1.0 from golang - go

I've installed IBM MQ (8.0.0.4) on a local Windows VM and followed the instructions in the docs to enable AMQP (https://www.ibm.com/support/knowledgecenter/en/SSFKSJ_8.0.0/com.ibm.mq.con.doc/tamqp_creating.htm), and also disabled authentication since this is just a local development environment. With that done, I am able to connect from my host OS using the node.js sample in IBM's mqlight package:
>npm install mqlight
...
>node node_modules/mqlight/samples/recv.js -s amqp://windows-10:5672
Connected to amqp://windows-10:5672 using client-id recv_126117c
Subscribed to pattern: public
However, when attempting to connect from a golang app using vcabbage/amqp (version 0.12.5), it returns an EOF error on the attempt to dial the host. Minimal example:
package main
import (
"fmt"
"pack.ag/amqp"
)
func main() {
_, err := amqp.Dial("amqp://windows-10:5672")
fmt.Println(err) // EOF
}
Nothing is appearing in the IBM MQ error logs.
Unfortunately Google does not turn up any relevant results for connecting to IBM MQ via AMQP 1.0 in golang, so I'm stuck. Does anyone have any ideas?

So the solution is apparently to use SASL Anonymous mode; this allows the client to connect.
package main
import (
"fmt"
"pack.ag/amqp"
)
func main() {
_, err := amqp.Dial("amqp://windows-10:5672", amqp.ConnSASLAnonymous())
fmt.Println(err) // nil
}
If anybody wants to try to make it work in "normal" mode, it appears that IBM MQ was closing the channel as soon as the initial header packet was sent. The EOF was bubbling up from the receiving goroutine in any case.

Related

simple client on golang returns "net/http: HTTP/1.x transport connection broken: unexpected EOF"

I use simple client on golang
package main
import (
"fmt"
"net/http"
)
func main() {
_, err := http.Get("http://localhost:8080/health")
fmt.Println(err)
}
and simple http server on python https://gist.github.com/huyng/814831
but I got an error
Get "http://localhost:8080/health": net/http: HTTP/1.x transport connection broken: unexpected EOF
What is wrong with my client or server?
...net/http: HTTP/1.x transport connection broken: unexpected EOF
What is wrong with my client or server?
The answer lies in the 6 year old comment immediately below the code you use for the server:
Nice. A minor HTTP protocol glitch though, as there's no self.end_headers() so the response is malformed when served to picky clients (haproxy). ;)
Thus, don't just take code from somewhere on the internet w/o understanding what it does. Especially, if there is already an explicitly comment saying that the code is broken

Kafka-Consumer issue, showing some time out error

I'm new to this Apache Kafka topic and I was writing some basic producer-consumer code, and I'm facing some issues with consumer code, after starting the zookeeper and Kafka, I created a topic name "firsttopic", and I'm entering some events using CLI commands as a producer and to retrieve those events as a consumer I've written a go code using Kafka-go that I'm attaching below and the error that I'm facing too. For Kafka I'm using "github.com/segmentio/kafka-go".
func Startkafka() {
conf := kafka.ReaderConfig{
Brokers: []string{"localhost:9092"},
Topic: "firsttopic",
GroupID: "g1",
MaxBytes: 10,
}
reader := kafka.NewReader(conf)
for {
m, err := reader.ReadMessage((context.Background()))
if err != nil {
fmt.Println("Some error occured", err)
continue
}
fmt.Println("Message is : ", string(m.Value))
}}
func main() {
go Startkafka()
fmt.Println("Kafka has been started...")
}
Error:
Kafka has been started...
Some error occured read tcp 127.0.0.1:34858->127.0.1.1:9092: i/o timeout
Based on the error, you should remove 127.0.1.1 from /etc/hosts mapping to localhost as it ought to remain as 127.0.0.1 during the client connection to localhost
Alternatively, connect to 127.0.0.1:9092 instead
MaxBytes: 10 is very low, You should increase that as that may be causing an issue. The rest of the code seems to be correct. you should first try connecting using Kafka-consumer shipped with Kafka installation whether it is up which will also verify the connection string that you are using.
In you main function, that StartKafka() calling in a go routine. Then it is start in another stack and run concurrently while main routine end the execution.
Remove that go routine and run the application. it will blocking the application and consume from Kafka topic.
If you need to build proper graceful shutdown process for the application, you have to use channels or something. But following code simply works for consume the topic content.
func main() {
fmt.Println("starting kafka...")
Startkafka()
}

Connecting to PubSub inside GAE application

I've built an application in Go that connects to a Google PubSub to publish messages. It works perfectly in localhost (using pubsub emulator), but for some reason the connection hangs in GAE.
It hangs on this piece of code (removed unrelated code to improve readability)
import (
"cloud.google.com/go/pubsub"
)
client, err := pubsub.NewClient(ctx, config.Project_ID)
if err != nil {
return nil, errors.Wrap(err, "failed to create client")
}
topic, err := client.CreateTopic(ctx, id) // HANGS HERE
This is the app.yaml
runtime: go114
instance_class: B1
manual_scaling:
instances: 1
handlers:
- url: /.*
script: auto
Also, when the code is running (and hanged) it keeps outputting the following error message
internal.flushLog: Flush RPC: service bridge HTTP failed: Post "http://appengine.googleapis.internal:10001/rpc_http": dial tcp 169.254.169.253:10001: i/o timeout
It seems that something is dropping the packets sent to GCP internal API, but I don't know why or how to fix it. What I find even more weird is the fact that I have another app running almost the same code (and connecting successfully to pubsub). The only difference is that the app that is working is not the default service in GAE and the one that's failing is.
It seems like a network problem but unfortunately I haven't been able to find a solution online.
Below are the direct dependencies used by the app (extracted from go.mod)
cloud.google.com/go
cloud.google.com/go/storage
github.com/dgrijalva/jwt-go
github.com/getsentry/sentry-go
github.com/go-ozzo/ozzo-validation
github.com/golang/gddo
github.com/google/uuid
github.com/gorilla/handlers
github.com/gorilla/mux
github.com/jackc/pgx
github.com/jinzhu/copier
github.com/joho/godotenv
github.com/lib/pq
github.com/ory/dockertest
github.com/pkg/errors
github.com/stretchr/testify
google.golang.org/appengine
google.golang.org/genproto
cloud.google.com/go/pubsub
github.com/satori/go.uuid
github.com/sirupsen/logrus
github.com/spf13/pflag
google.golang.org/grpc
Okay guys, I finally found out what has happened. Dumb mistake.
We were using the pubsub emulator to test the application locally and unfortunately we left the PUBSUB_EMULATOR_HOST=localhost:8085 environment set in our GAE app. This means that the application was trying to connect with the emulator inside the GAE and not the real Pub/Sub. Since the emulator only exists locally, the application hangs on the TCP connection.
At least I can tell some thing to help other people that might have similar issues:
Pub/Sub works with the GAE standard environment
Pub/Sub works with Go 1.14 (you don't need to downgrade to 1.11)
Check your environment variables :)

TLS handshake error from xx.xx.xx.xx:14333: EOF

I am running a HTTPS server in Linux (RHEL 7). I am getting the below error as soon as I start the server.
2019/09/04 15:46:16 http: TLS handshake error from xx.xx.xx.xx:60206: EOF
2019/09/04 15:46:21 http: TLS handshake error from xx.xx.xx.xx:31824: EOF
This error is coming automatically and continuously in the terminal.
Below is the go code for creating https server -
package main
import (
"fmt"
"net/http"
"github.com/gin-gonic/gin"
)
func main() {
fmt.Println("Starting webserver")
router := gin.Default()
router.GET("/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"success": true,
})
})
router.RunTLS(":9001", "server.pem", "server.key")
}
We have purchased and combined the server certificate, intermidate certificate and root certificate into a single file to make the server.pem file.
As this error is coming continuously and in the terminal as soon as I start the server, I think there is some configuration problem in the VM?
Please suggest what are the things I can check here.
NOTE: This error is specific to the Go. I have tested on the same server on the same port with same certificates in Node JS. And it works fine.
Also the IP in the error message is of the reverse proxy server (WAF) which is continuosly doing health monitoring of the web application server.
I would attack the problem from two angles:
What is this xx.xx.xx.xx address? I'd expect that when I start some random piece of software, there is nothing to connect to it all by itself, right?
Is there anything special about that 9001 port? Try running nc -l -p 9001 and see whether those unidentified connections happen as well.
Run tcpdump and see whether there is any incoming traffic from the clients making those connections: those EOFs (that's "end of file") reported by the TLS mchinery most probably mean those clients—whatever they are—close their side of the connection somewhere amidst the TLS handshake—while the server is expecting to read some data from them.
This hints at that those clients do not actually expect to see TLS protocol in the connection they open; and they pretty much may send some plaintext in it, so you'll be able to peek at it.
Googling for "9001 port" hints at that it's used for some "ETL service manager" protocol—whatever it is. This hints at that traffic on 9001 might be related to VoIP.
I have no idea what to do with this, but it might give you some lead for further research.

Set connection friendly name in Go amqp client

I am using the http://github.com/streadway/amqp package in my application in order to handle connections to a remote RabbitMQ server. Everything is ok and works fine, but I have a question.
The current name for a connection is "ip:port", so when there are multiple connections from the same IP+port, they become hardly distinguishable. It would be great if you can specify a name for each connection.
Is there any way to set a distinct friendly name for each connection?
RabbitMQ 3.6.5 added the facility for the connecting client to report a friendly name string value to identify a connection for management purposes. This is strictly an identifier and, as it is client-reported, it cannot be relied upon for anything other than weak identification of connections. The release notes state:
Clients now can provide a human-readable connection name that will be displayed in the management UI... In order to use this feature, set the connection_name key in client properties. Note that this name doesn’t have to be unique and cannot be used as a connection identifier, for example, in HTTP API requests.
Solution
Provided you are using a sufficiently new version of RabbitMQ, you can set this parameter when making connections using streadway/amqp by passing an instance of amqp.Config when making the initial connection. The Properties field allows custom properties of the connection to be specified.
The example program below opens a connection using the AMQP URL provided in the environment variable AMQP_URL, identified using the connection name passed as the first command line argument to the invocation.
package main
import (
"log"
"os"
"github.com/streadway/amqp"
)
func main() {
amqpUrl := os.Getenv("AMQP_URL")
cfg := amqp.Config{
Properties: amqp.Table{
"connection_name": os.Args[1],
},
}
conn, err := amqp.DialConfig(amqpUrl, cfg)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
<-(chan struct{})(nil)
}
Starting multiple instances to connect to a local RabbitMQ instance using the following command line:
AMQP_URL=amqp://admin:password#localhost:5672 go run ./main.go connX
where a numeral is substituted for X yields the following output in the "Connections" page of the RabbitMQ Management web UI:
and the individual connection detail pages shows the value under the "Client-provided name" detail value:

Resources