Using go with redis - not able to connect - azure

I'm trying to connect to Redis service in azure
I use the following code:
import (
"fmt"
"os"
"github.com/go-redis/redis"
)
func main() {
uri := os.Getenv("uri")
fmt.Println("uri is", uri)
opt, err := redis.ParseURL(uri)
if err != nil {
fmt.Println(err)
}
fmt.Println("addr is:”, opt.Addr)
fmt.Println("db is:”, opt.DB)
fmt.Println("password is:”, opt.Password)
//connect to redis
client = redis.NewClient(opt)
//Here I want to get connection
pong, err := client.Ping().Result()
https://github.com/go-redis/redis
https://godoc.org/github.com/go-redis/redis#example-ParseURL
The printed data is like following I was able to the the connection string
uri is rediss://:bBMfQ7wFdkPHr8u%2B2zzNOzUpy85OEjYv7KbPZd8B89M%3D#e49ab3c6-8f72-416a-a6c1-ddfe75gf200e.redis.cache.windows.net:6380
addr is: e49ab3c6-8f72-416a-a6c1-ddfe75gf200e.redis.cache.windows.net:6380
db is: 0
password is: bBMfQ7wFdkPHr8u+2zzNOzUpy85OEjYv7KbPZd8B89M=
The Redis service is up and running and I was able to connect with nodejs application and get the data, any idea why I got the error in go:
dial tcp 40.128.8.87:6380: connect: connection refused
We are trying to migrate some apps from Nodejs to go ...
The strange thing is that in nodejs I use the following which works!
https://github.com/NodeRedis/node-redis
const redisClient = redis.createClient(process.env.uri);
redisClient.on("connect", () => console.log("Redis is connected"));
update
I've provisioned a new instance without ssl which is not working either
This is the logs
uri is redis://:TKq1n%2BO29jsSdIkoysXL%2Btwd6Xi0IO0KNxw%3D#2dca2dx1-20e0-48ca-83ed-20bf52e99b97.redis.cache.windows.net:6379
addr is 2dca2dx1-20e0-48ca-83ed-20bf52e99b97.redis.cache.windows.net:6379
db is 0
password is TKq1n+O29jsSdIkoysXL+twd6Xi0IO0KNxw=
dial tcp 40.113.7.3:6379: connect: connection refused
Any idea how should I use the GO api to connect to redis properly ?
Btw, when I connected to local Redis it works, but not to azure cache
like this
client := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "",
DB: 0,
})
Maybe I miss something in the Redis api, as I do the same (connect to the same service instance ) for nodejs and it works!

Related

504 Gateway Time-Out 240000 ms when using EventSource

I'm using this node.js library in order to Reconnect to an EventSource in case it closes.
The Problem
My web app is hosted on Microsoft Azure , in which i've enabled Web Sockets
After 240000ms the event source object closes with a 504 Gateway time-out error.
Web app architecture:
The project is designed with the Spring boot framework and this is one of my Streaming Endpoints
#GetMapping(path = "/completed/receive", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Event> receiveCompleted() {
return Flux.create(sink -> {
completedProcessor.register(sink::next);
});
}
Headers I've tried and didn't work
Connection : Keep-Alive
Keep - Alive: timeout=500000
Enable Web Sockets from Microsoft Azure
How i'm listening to the endpoint with JS
var eventSourceCompleted;
eventSourceCompleted = new ReconnectingEventSource("/api/completed/receive");
// Receive messages
eventSourceCompleted.onmessage = function (evt) {
//Do Something
};
eventSourceCompleted.onerror = function (e) {
console.log("EventSource failed: " + e);
};
No matter what i try, 240k ms later the connection closes, how can that be?

unable to create session: control: unable to connect to initial hosts: Invalid Cosmos DB account or key

I have been trying to connect to cosmos cassandra db using gocql.
func GetSession(cosmosCassandraContactPoint, cosmosCassandraPort, cosmosCassandraUser, cosmosCassandraPassword string) *gocql.Session {
clusterConfig := gocql.NewCluster(cosmosCassandraContactPoint)
port, err := strconv.Atoi(cosmosCassandraPort)
if err != nil {
log.Fatal(err)
}
clusterConfig.Port = port
clusterConfig.ProtoVersion = 4
clusterConfig.Authenticator = gocql.PasswordAuthenticator{Username: cosmosCassandraUser, Password: cosmosCassandraPassword}
clusterConfig.SslOpts = &gocql.SslOptions{Config: &tls.Config{MinVersion: tls.VersionTLS12}}
clusterConfig.ConnectTimeout = 10 * time.Second
clusterConfig.Timeout = 10 * time.Second
clusterConfig.DisableInitialHostLookup = true
// uncomment if you want to track time taken for individual queries
//clusterConfig.QueryObserver = timer{}
// uncomment if you want to track time taken for each connection to Cassandra
//clusterConfig.ConnectObserver = timer{}
session, err := clusterConfig.CreateSession()
if err != nil {
log.Fatal("Failed to connect to Azure Cosmos DB", err)
}
return session
}
I have been getting the following error :
unable to create session: control: unable to connect to initial hosts: Invalid Cosmos DB account or key
Not sure what the issue here is.
It doesn't look like you've configured the necessary options for the SSL/TLS configuration, particularly the certificates.
I haven't connected to a Cosmos DB before so I'm not sure of the certs/keys required but I previously helped someone configure the gocql driver with the right TLS settings in this post -- https://community.datastax.com/questions/3753/.
In their environment, they needed to provide the certs and keys to connect as follows:
certPath, _ := filepath.Abs("/home/erick/astra-bundle/cert")
keyPath, _ := filepath.Abs("/home/erick/astra-bundle/key")
caPath, _ := filepath.Abs("/home/erick/astra-bundle/ca.crt")
cert, _ := tls.LoadX509KeyPair(certPath, keyPath)
caCert, _ := ioutil.ReadFile(caPath)
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
RootCAs: caCertPool,
}
cluster.SslOpts = &gocql.SslOptions{
Config: tlsConfig,
EnableHostVerification: false,
}
Details are in the post above. I hope this helps. Cheers!
It seems your account or key is wrong.
First,please make sure your API is CASSANDRA API.You can check at here.
Second,please make sure your account or key is right.
COSMOSDB_CASSANDRA_CONTACT_POINT=<value for "CONTACT POINT">
COSMOSDB_CASSANDRA_PORT=<value for "PORT">
COSMOSDB_CASSANDRA_USER=<value for "USERNAME">
COSMOSDB_CASSANDRA_PASSWORD=<value for "PRIMARY PASSWORD">
You can find them here:
More details,you can refer to this documentation.
Hope this can help you.

TcpIp communication from an Azure Function?

I have an azure Queue trigger function that has this code:
using (var client = new TcpClient(AddressFamily.InterNetworkV6))
{
client.Client.DualMode = true;
client.Connect(endpoint);
var data = Encoding.ASCII.GetBytes("test");
using (var outStream = client.GetStream())
{
outStream.Write(data, 0, data.Length);
}
}
The error I am getting back:
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond
The endpoint address looks correct and this code works when I debug locally, so I suspect that the azure server might not be allowing the outbound connection.
Any ideas why this connection is not working?
Update: This is still not working and I have tried generating the client in the following ways:
// DualMode IPV6
var client = new TcpClient(AddressFamily.InterNetworkV6);
client.Client.DualMode = true;
client.Connect(endpoint);
// SingleMode Internetwork
var client = new TcpClient(AddressFamily.InterNetwork);
client.Connect(endpoint);
// Just Endpoint
var client = new TcpClient(endpoint);
client.Connect(endpoint);
// Normal
var client = new TcpClient(hostAddress, port);
// Forced IPV6
var client = new TcpClient("::ffff:" + hostAddress, port);
Debugging locally, all of these methods except for "forced IPV6" work just fine. On the server, I get these errors:
== DualMode IPV6
Failed PingBack: A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host
has failed to respond [::ffff:204.16.184.62]:3164
== SingleMode Internetwork
Failed PingBack: A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host
has failed to respond 204.16.184.62:3164
== Just Endpoint
Failed PingBack: The requested address is not valid in its context
== Normal
Failed PingBack: A connection attempt failed because the connected party did not properly
respond after a period of time, or established connection failed because connected host
has failed to respond 204.16.184.62:3164
== Forced IPV6
Failed PingBack: The requested address is not valid in its context [::ffff:204.16.184.62]:3164
Looking at your TcpClient instance,
var client = new TcpClient(AddressFamily.InterNetworkV6)
there's no IPv6 in Azure Functions yet. Switch your AddressFamily to v4:
var client = new TcpClient(AddressFamily.InterNetwork)
There are no restrictions on outbound desinations in App Service/Functions.

node net.createServer get connection path

Trying to cluster Socket.io using net.createServer. All examples are using IP to split what connection goes to witch node. However I'm using 4 servers with a load balancer that points ip;s to the different servers.
So in node cluster I would like to use an unique id to point the connection to a specific cluster.
Figure that each user that wants to connect can add a parameter to the connection url ws://localhost/socket.io?id=xxyyzz
How can I get the connection url in net.createServer
todays code for ip:
var server = net.createServer({ pauseOnConnect: true }, function(connection) {
// We received a connection and need to pass it to the appropriate
// worker. Get the worker for this connection's source IP and pass
// it the connection.
var remote = connection.remoteAddress;
var local = connection.localAddress;
var ip = (remote+local).match( /[0-9]+/g )[0].replace(/,/g, '');
var wIndex = ip % num_processes;
var worker = workers[wIndex];
worker.send('sticky-session:connection', connection);
});

direct (non-tcp) connection to redis from nodejs

hello all
I looked at the at the redis-node-client source (relevant part is shown bellow) and I see that it connects to redis via the 'net' package, which is TCP based.
line 370
exports.createClient = function (port, host, options) {
var port = port || exports.DEFAULT_PORT;
var host = host || exports.DEFAULT_HOST;
var client = new Client(net.createConnection(port, host), options);
client.port = port;
client.host = host;
return client;
};
I was wondering if there's a more direct client for redis, preferably via domain-sockets or something of that sort. Im using redis localy, as cache, without going over the wire so its unnecessary to encode/decode messages with TCP headers...
thank you
Unix Domain Socket support appears to have landed in Redis as of Nov 4th.
http://code.google.com/p/redis/issues/detail?id=231
To connect to a Unix Domain Socket, you need to supply the pathname to net.createConnection. Maybe something like this in redis-node-client:
exports.createSocketClient = function (path, options) {
var client = new Client(net.createConnection(path), options);
client.path = path;
return client;
};

Resources