KafkaClient using Nodejs - javascript

Can u please explain the kafkaClient using Nodejs with using port 9092 not zookeeper port 2181.
var kafka = require('kafka-node'),
Producer = kafka.Producer,
KeyedMessage = kafka.KeyedMessage,
client = new kafka.Client(),
producer = new Producer(client),
km = new KeyedMessage('key', 'message'),
payloads = [
{ topic: 'topic1', messages: 'hi', partition: 0 },
{ topic: 'topic2', messages: ['hello', 'world', km] }
];
producer.on('ready', function () {
producer.send(payloads, function (err, data) {
console.log(data);
});
});
producer.on('error', function (err) {})

Newer Kafka clients no longer need to talk directly to zookeeper. They only need to talk to Kafka.

Using the new KafkaClient is basically how u use the old Client, but talking directly to kafka.
const kafka = require('kafka-node');
let kafkaHost = '172.30.33.181:9092';
const Consumer = kafka.Consumer;
const client = new kafka.KafkaClient({kafkaHost: kafkaHost});
const consumer = new Consumer(
client,
[
{ topic: 'myTopic' },
],
{
autoCommit: false,
fromOffset: 'latest'
}
);
consumer.on('message', function (message) {
console.log(message);
});
consumer.on('error', function (err) {
console.log('Error:',err);
});
consumer.on('offsetOutOfRange', function (err) {
console.log('offsetOutOfRange:',err);
});

Related

Not able to get Access Token from Google Api

I am new to GTM+GA.I am trying to display google Analytics(GA4) reports on my webpage. I created Oauth Client Id in google cloud console and also done other settings in Google cloud console. Through javascript code i am trying to get access token from google Api and I am getting below exception.
After successful authentication I will integrate GA repots with my web page. Below is my javascript code for getting access token.
function main(propertyId = 'YOUR-GA4-PROPERTY-ID') {
propertyId = '347415282';
const {
OAuth2Client
} = require('google-auth-library');
const {
grpc
} = require('google-gax');
const http = require('http');
const url = require('url');
const open = require('open');
const destroyer = require('server-destroy');
const keys = require('./oauth2.keys.json');
const SCOPES = ['https://www.googleapis.com/auth/analytics.readonly'];
function getAnalyticsDataClient(authClient) {
const sslCreds = grpc.credentials.createSsl();
const credentials = grpc.credentials.combineChannelCredentials(
sslCreds,
grpc.credentials.createFromGoogleCredential(authClient));
return new BetaAnalyticsDataClient({
sslCreds: credentials,
});
}
function getOAuth2Client() {
return new Promise((resolve, reject) => {
const oAuth2Client = new OAuth2Client(
keys.web.client_id,
keys.web.client_secret,
'http://localhost:3000/oauth2callback');
const authorizeUrl = oAuth2Client.generateAuthUrl({
access_type: 'offline',
scope: SCOPES.join(' '),
});
const server = http
.createServer(async(req, res) => {
try {
if (req.url.indexOf('/oauth2callback') > -1) {
const qs = new url.URL(req.url, 'http://localhost:3000')
.searchParams;
const code = qs.get('code');
console.log(`Code is ${code}`);
res.end(
'Authentication successful! Please return to the console.');
server.destroy();
const r = await oAuth2Client.getToken(code);
oAuth2Client.setCredentials(r.tokens);
console.info('Tokens acquired.');
resolve(oAuth2Client);
}
} catch (e) {
reject(e);
}
})
.listen(3000, () => {
console.info(`Opening the browser with URL: ${authorizeUrl}`);
open(authorizeUrl, {
wait: false
}).then(cp => cp.unref());
});
destroyer(server);
});
}
async function runReport() {
const oAuth2Client = await getOAuth2Client();
const analyticsDataClient = getAnalyticsDataClient(oAuth2Client);
const[response] = await analyticsDataClient.runReport({
property: `properties/${propertyId}`,
dateRanges: [{
startDate: '2020-03-31',
endDate: 'today',
},
],
dimensions: [{
name: 'city',
},
],
metrics: [{
name: 'activeUsers',
},
],
});
console.log('Report result:');
response.rows.forEach(row => {
console.log(row.dimensionValues[0], row.metricValues[0]);
});
}
runReport();
process.on('unhandledRejection', err => {
console.error(err.message);
process.exitCode = 1;
});
main(...process.argv.slice(2));
Please let me know how to get rid off this issue.
Regards,
Prabhash

How do I reuse a RabbitMQ connection and channel outside of the "setup structure" with the amqp library?

I am trying to build a simple node.js client using the amqp library, that opens a single connection and then a single channel to a RabbitMQ server. I want to reuse the same connection and channel to send multiple messages. The main problem is, that I don't want to write my entire code inside the callback function of the ceateChannel() function.
How do I reuse the channel outside of the callback function and make sure the callback function has finished before I use the channel?
I've tried both the callback way and the promise way but I can't make either of them work. When using the callback method I run into the described problem.
When using promises, I have the problem that I can't keep a reference of the connection and channel outside of the .then() function because the passed variables get destroyed after setting up the connection and channel.
amqp.connect('amqp://localhost', (err, conn) => {
if (err !== null) return console.warn(err);
console.log('Created connection!');
conn.createChannel((err, ch) => {
if (err !== null) return console.warn(err);
console.log('Created channel!');
//this is where I would need to write the code that uses the variable "ch"
//but I want to move the code outside of this structure, while making sure
//this callback completes before I try using "ch"
});
});
amqp.connect('amqp://localhost').then((conn) => {
return conn.createChannel();
}).then((ch) => {
this.channel = ch;
return ch.assertQueue('', {}).then((ok) => {
return this.queueName = ok.queue;
});
}).catch(console.warn);
why you don't use async\await ?
const conn = await amqp.connect('amqp://localhost');
const ch = await conn.createChannel();
// after that you can use ch anywhere, don't forget to handle exceptions
Also if you use amqplib, don't forget to handle close and internal error events, for example like this:
conn.on('error', function (err) {
console.log('AMQP:Error:', err);
});
conn.on('close', () => {
console.log("AMQP:Closed");
});
Try with a class, like this:
RabbitConnection.js
const amqp = require('amqplib');
const RabbitSettings = {
protocol: 'amqp',
hostname: 'localhost',
port: 5672,
username: 'guest',
password: 'guest',
authMechanism: 'AMQPLAIN',
vhost: '/',
queue: 'test'
}
class RabbitConnection {
constructor() {
RabbitConnection.createConnection();
this.connection = null;
this.channel = null;
}
static getInstance() {
if (!RabbitConnection.instance) {
RabbitConnection.instance = new RabbitConnection();
}
return RabbitConnection.instance;
}
//create connection to rabbitmq
static async createConnection() {
try {
this.connection = await amqp.connect(`${RabbitSettings.protocol}://${RabbitSettings.username}:${RabbitSettings.password}#${RabbitSettings.hostname}:${RabbitSettings.port}${RabbitSettings.vhost}`);
this.channel = await this.connection.createChannel();
this.channel.assertQueue(RabbitSettings.queue);
console.log('Connection to RabbitMQ established');
} catch (error) {
console.log(error);
}
}
//send message to rabbitmq queue
static async sendMessage(message, queueName) {
try {
let msg = await this.channel.sendToQueue(queueName, Buffer.from(message));
console.log('Message sent to RabbitMQ');
return msg;
} catch (error) {
console.log(error);
}
}
}
module.exports = { RabbitConnection };
ServerExpress.js
const express = require('express');
const { RabbitConnection } = require('./RabbitConnection');
const serverUp = () => {
const app = express();
app.get('/', (req, res) => {
RabbitConnection.sendMessage('Hello World', 'test');
res.send('Hello World!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
};
module.exports = { serverUp };
index.js
const { RabbitConnection } = require("./RabbitConnection");
const { serverUp } = require("./ServerExpress");
serverUp();
RabbitConnection.getInstance();

PostgreSql results printing to console but not displaying in browser

I'm trying to get some data from a pg database to my api endpoint , I can print the results to the console but I can't get them to display in the browser with res.send. I'm guessing the problem is with global and local scope however I've not been able to figure it out. I'm using ES6 but transpiling with babel. Here's a snippet.
app.get('/', (request, response) => {
const { Pool, Client } = require('pg');
const config = {
user: '',
host: '',
database: '',
password: '',
port: ,
}
const pool = new Pool(config);
const client = new Client(config);
let whole = [];
client.connect();
const text = "SELECT * FROM entries where id='1'";
client.query(text)
.then(res => {
console.log(res.rows[0]);
whole.push(res.rows[0]);
})
.catch(e => console.error(e.stack));
response.send(whole);
client.end;
});
This logs to the console
{ id: 1, title: 'First title', body: 'beautiful body' }
However the browser only displays []
This is what babel transpiles it to which is the script I run in node.
var whole = [];
client.connect();
var text = "SELECT * FROM entries where id='1'";
client.query(text).then(function (res) {
console.log(res.rows[0]);
whole.push(res.rows[0]);
}).catch(function (e) {
return console.error(e.stack);
});
response.send(whole);
client.end;
response.send is called outside of the async promise .then resolver, and is therefore executed before you push the row data into the array. Moving response.send into the promise resolver should fix it.
client.query(text).then(res => {
whole.push(res.rows[0]);
client.end();
response.send(whole);
}).catch((e) => {
console.error(e.stack);
});
Alternatively, you can use async/await depending on your babel version and presets/plugins.
const { Client } = require("pg");
const config = {...};
const queryText = "SELECT * FROM entries where id='1'";
app.get("/", async (request, response) => {
const client = new Client(config);
await client.connect();
try {
const queryResponse = await client.query(queryText);
// Send response without pushing to array
response.send(queryResponse.rows[0]);
client.end();
} catch (e) {
console.error(e.stack);
}
});

Ember includedCommands: HTTPS request does not fetch

I am writing an ember includedCommand for fetching and updating the app/index.html file - which uses NodeJS https and fs module to replace the indexFile by calling a function BuildIndexFile, where I am facing a weird issue -
When I perform command ember server --update-index - I can see the BuildIndexFile is being called and the https request is made to the remote server which downloads the file and gets written by fs.writeFileSync in app/index.html.
But when I perform ember update-index which is an included command, I can see BuildIndexFile has been called, and it reaches till console.log('Fetching index.html'); and I believe it is calling https.request... but it closes from there, I have no idea why the call didn't go through, when I debugged using node --inspect-brk ./node_modules/.bin/ember update-index I can see the https is available on the file, but not executing.
I am attaching my sample code available as a in-repo-addon available at lib/hello/index.js -
/* eslint-env node */
'use strict';
const parseArgs = require('minimist');
const watchman = require('fb-watchman');
let client = new watchman.Client();
client.capabilityCheck({optional: [], required: ['relative_root']}, function (error, response) {
if (error) {
console.log(error);
}
console.log('Watchman', response);
});
const ServeCommand = require('ember-cli/lib/commands/serve');
const ARGS = parseArgs(process.argv.slice(2));
const fs = require('fs');
const https = require('https');
module.exports = {
name: 'hello',
isDevelopingAddon() {
return true;
},
includedCommands: function() {
var self = this;
return {
hello: ServeCommand.extend({
name: 'hello',
description: 'A test command that says hello',
availableOptions: ServeCommand.prototype.availableOptions.concat([{
name: 'updateindex',
type: String
}]),
run: function(commandOptions, rawArgs) {
console.log(commandOptions, rawArgs);
if (commandOptions['updateindex']) {
console.log('Update Index')
}
const sampleHelloPromise = sampleHello();
const servePromise = this._super.run.apply(this, arguments);
return Promise.all([sampleHelloPromise, servePromise]);
}
}),
updateIndex: {
name: 'update-index',
description: 'Update Index File',
availableOptions: [{
name: 'index-file',
type: String
}],
run: function(commandOptions, rawArgs) {
BuildIndexFile(self.project.root, 'https://yahoo.com', {});
}
}
}
},
preBuild: function(result) {
let self = this;
if (ARGS['update-index']) {
BuildIndexFile(self.project.root, 'https://google.com', {}).then(function() {
delete ARGS['update-index'];
})
.catch(function(e) {
console.log(e);
});;
}
}
};
async function sampleHello() {
return await new Promise(resolve => {
setTimeout(() => resolve('hello'), 2000);
})
}
const BuildIndexFile = (rootPath, target, headers) => {
try {
debugger;
const indexFile = `${rootPath}/app/index.html`;
let noIndexFile = !fs.existsSync(indexFile);
return new Promise(function (resolve, reject) {
let options = {
hostname: target.replace(/^http(?:s):\/\//i, ''),
port: 443,
method: 'GET'
};
let dataContent = '';
console.log('Fetching index.html');
var request = https.request(options, function(response) {
response.on('data', function(d) {
dataContent += d;
});
response.on('end', function() {
fs.writeFileSync(indexFile, dataContent);
return resolve();
});
});
request.on('error', function(e) {
console.log(e);
return reject(`Error: Creating Index File`);
});
request.end();
});
} catch(e) {
throw e;
}
}

How to create consumer for kafka topic?

I have topic created on kafka server now i am creating consumer to read topic messages from server, but i dont see any data when i try to consume message using consumer.on('message') , Any idea what is implemented wrong in below code , Do i need to set offset ?
consumer.js
var kafka = require('kafka-node');
var config = require('./config.js');
var zk = require('node-zookeeper-client');
var kafkaConn = config.kafkaCon.dit;
var HighLevelConsumer = kafka.HighLevelConsumer;
var Client = kafka.Client;
function start() {
topics = [{
topic: 'test-1'
}];
var groupId = 'push';
var clientId = "consumer-" + Math.floor(Math.random() * 10000);
var options = {
autoCommit: true,
fetchMaxWaitMs: 100,
fetchMaxBytes: 10 * 1024 * 1024,
groupId: groupId
};
console.log("Started consumer: ", clientId);
var consumer_client = new kafka.Client(kafkaConn, clientId);
var client = new Client(consumer_client.connectionString, clientId);
var consumer = new HighLevelConsumer(client, topics, options);
consumer.on('message', function(message) {
var topic = message.topic;
console.log('Message', topic);
});
};
start();
const Kafka = require("node-rdkafka");
const kafkaConf = {
"group.id": "cloudkarafka-example",
"metadata.broker.list": ["localhost:9092"],
"socket.keepalive.enable": true,
//"security.protocol": "SASL_SSL",
//"sasl.mechanisms": "SCRAM-SHA-256",
//"sasl.username": process.env.CLOUDKARAFKA_USERNAME,
//"sasl.password": process.env.CLOUDKARAFKA_PASSWORD,
"debug": "generic,broker,security",
'enable.auto.commit': false,
};
//const prefix = process.env.CLOUDKARAFKA_USERNAME;
const topics = ['topicName'];
const consumer = new Kafka.KafkaConsumer(kafkaConf, {
"auto.offset.reset": "beginning"
});
consumer.on("error", function(err) {
console.error(err);
});
consumer.on("ready", function(arg) {
console.log(`Consumer ${arg.name} ready`);
consumer.subscribe(topics);
consumer.consume();
});
consumer.on("data", function(m) {
console.log(m.value.toString());
});
consumer.on("disconnected", function(arg) {
process.exit();
});
consumer.on('event.error', function(err) {
console.error(err);
process.exit(1);
});
consumer.on('event.log', function(log) {
console.log(log);
});
consumer.connect();
A Kafka Consumer can be written with the kafka-node npm module. For my use case, my consumer was a separate Express server which listened to events and stored them in a database.
import kafka from "kafka-node"
const client = new kafka.Client("http://localhost:2181");
const topics = [
{
topic: "webevents.dev"
}
];
const options = {
autoCommit: true,
fetchMaxWaitMs: 1000,
fetchMaxBytes: 1024 * 1024,
encoding: "buffer"
};
const consumer = new kafka.HighLevelConsumer(client, topics, options);
consumer.on("message", function(message) {
// Read string into a buffer.
var buf = new Buffer(message.value, "binary");
var decodedMessage = JSON.parse(buf.toString());
//Events is a Sequelize Model Object.
return Events.create({
id: decodedMessage.id,
type: decodedMessage.type,
userId: decodedMessage.userId,
sessionId: decodedMessage.sessionId,
data: JSON.stringify(decodedMessage.data),
createdAt: new Date()
});
});
consumer.on("error", function(err) {
console.log("error", err);
});
process.on("SIGINT", function() {
consumer.close(true, function() {
process.exit();
});
});
more info in https://nodewebapps.com/2017/11/04/getting-started-with-nodejs-and-kafka/

Categories

Resources