Apache Thrift with nodejs example - node.js

I am trying to use Apache Thrift for passing messages between applications implemented in different languages. It is not necessarily used as RPC, but more for serializing/deserializing messages.
One application is in node.js. I am trying to figure out how Apache thrift works with node.js, but I can't find too much documentation and examples, except for one tiny one regarding Cassandra at:
https://github.com/apache/thrift/tree/trunk/lib/nodejs
Again, I don't need any procedures declared in the .thrift file, I only need to serialize a simple data structure like:
struct Notification {
1: string subject,
2: string message
}
Can anyone help me with an example?

I finally found the answer to this question, after wasting a lot of time just by looking at the library for nodejs.
//SERIALIZATION:
var buffer = new Buffer(notification);
var transport = new thrift.TFramedTransport(buffer);
var binaryProt = new thrift.TBinaryProtocol(transport);
notification.write(binaryProt);
At this point, the byte array can be found in the transport.outBuffers field:
var byteArray = transport.outBuffers;
For deserialization:
var tTransport = new thrift.TFramedTransport(byteArray);
var tProtocol = new thrift.TBinaryProtocol(tTransport);
var receivedNotif = new notification_type.Notification();
receivedNotif.read(tProtocol);
Also the following lines need to be added to the index.js file from the nodejs library for thrift:
exports.TFramedTransport = require('./transport').TFramedTransport;
exports.TBufferedTransport = require('./transport').TBufferedTransport;
exports.TBinaryProtocol = require('./protocol').TBinaryProtocol;
Plus there is also at least one bug in the nodejs library.

The above answer is wrong, because it tries to use outBuffers directly, which is an array of buffers. Here is a working example of using thrift with nodejs:
var util = require('util');
var thrift = require('thrift');
var Notification = require('./gen-nodejs/notification_types.js').Notification;
var TFramedTransport = require('thrift/lib/thrift/transport').TFramedTransport;
var TBufferedTransport = require('thrift/lib/thrift/transport').TBufferedTransport;
var TBinaryProtocol = require('thrift/lib/thrift/protocol').TBinaryProtocol;
var transport = new TFramedTransport(null, function(byteArray) {
// Flush puts a 4-byte header, which needs to be parsed/sliced.
byteArray = byteArray.slice(4);
// DESERIALIZATION:
var tTransport = new TFramedTransport(byteArray);
var tProtocol = new TBinaryProtocol(tTransport);
var receivedNotification = new Notification();
receivedUser.read(tProtocol);
console.log(util.inspect(receivedNotification, false, null));
});
var binaryProt = new TBinaryProtocol(transport);
// SERIALIZATION:
var notification = new Notification({"subject":"AAAA"});
console.log(util.inspect(notification, false, null));
notification.write(binaryProt);
transport.flush();

DigitalGhost is right, the previous example is wrong.
IMHO the outBuffers is a private property to the transport class and should not be accessed.

Related

How to serialize a YamlNode graph?

YamlDotNet seems to support serializing POC graphs, but I can't find an API that serializes an object graph made directly of YamlNode types. Is there a way to do this?
The trick is to pass the root node into a new YamlDocument and then to pass the document to YamlStream, which exposes a Save method.
var rootNode = new YamlMappingNode();
rootNode.Add("methods", methods);
var result = new YamlDocument(rootNode);
var resultStream = new YamlStream(result);
using var resultWriter = File.CreateText(#"d:\temp\scraped.yml");
resultStream.Save(resultWriter);

ServiceStack Raw Client query string

This should be simple, but I must be using the wrong key words to find the answer.
How can I output the raw query string that the jsonserviceclient is generating when sending a request to the server? I know I could use fiddler or something else to snoop the answer to this, but I'm interested if there is something like:
var client = new JsonServiceClient("http://myService:port/");
var request = new MyOperation
{
SomeDate = DateTime.Today
};
Console.Out.Writeline(client.AsQueryString(request));
You can use the Reverse Routing extension methods to see what urls different populated Request DTOs would generate, e.g:
var relativeUrl = new MyOperation { SomeDate = DateTime.Today }.ToGetUrl();
var absoluteUrl = new MyOperation { SomeDate = DateTime.Today }.ToAbsoluteUri();

Using node.js to display helpscout metrics

I am hoping someone can point me in the right direction.
I would like to use metrics-helpscout to bring back data that I can use for a dashboard. I am not having any luck. This is also my first time using node.js so I apologize in advance.
Here is what I have tried so far.
Following the instructions on github I used npm to install segmentio/metrics, metrics-helpscout and metrics-express.
I created a file called metrics.js and added this...
var Metrics = require('metrics');
var expressMetrics = require('metrics-express');
var helpscout = require('metrics-helpscout');
var express = require('metrics-express/node_modules/express');
var app = express();
console.log('start' );
var zzz = Metrics()
.every('1m', helpscout('myapi-key', ['my-mailbox-id']))
.on('helpscout active tickets', function (metric) {
console.log('helpscout update:' + metric.latest() );
});
var xxx = Metrics()
.every('1m', helpscout('myapi-key', ['my-mailbox-id']));
var date = new Date();
var val = 3;
var key = 'test';
var ddd = Metrics().set(key, val, date);
app.use('/', expressMetrics(xxx))
.listen(7002);
I then started the file by running node metrics.js
I opened a browser and hit the url and port and I just got back
[]
On the metrics express page example i used the var xxx. I thought I would get back a list of all the supported metrics. I then tested just using my var ddd and it did return my value. I am sure I am missing something or a lot.
Any help is appreciated.
Just in case it matters I am using ArchLinux.
Welp I figured it out. I generated a new API key and it worked.

How to retrieve all settings with OrmLiteAppSettings in one call?

I'm using the TextFileSettings and OrmLiteAppSettings together via MultiAppSettings, but would prefer to pre-read all the database settings in one call versus on demand, is there a way to do that, so that everything is in memory?
Below is the relevant code:
OracleDialect.Provider.NamingStrategy = new OrmLiteNamingStrategyBase();
OracleDialect.Provider.StringSerializer = new JsonStringSerializer();
var fileSettings = new TextFileSettings(ConfigUtils.GetAppSetting("PathToSecuredFile"));
var dbFactory = new OrmLiteConnectionFactory(fileSettings.GetString("LeadDbConfigKey"), OracleOrmLiteDialectProvider.Instance);
var dbSettings = new OrmLiteAppSettings(dbFactory);
var multiSettings = new MultiAppSettings(fileSettings, dbSettings);
container.Register<IAppSettings>(c => multiSettings);
Thank you,
Stephen
To preload all db App Settings you can just read the entire ConfigSetting db table into a .NET Dictionary and wrap it in DictionarySettings, e.g:
using (db = dbFactory.Open())
{
var allDbSettings = db.Dictionary<string,string>(
db.From<ConfigSetting>().Select(x => new { x.Id, x.Value}));
var multiSettings = new MultiAppSettings(
fileSettings,
new DictionarySettings(allDbSettings));
}

streaming iText pdf directly to lotus email using xpages

i'm trying to stream a newly generated pdf (using itext) directly to the body of lotus notes email as an attachment. but i'm getting following error while setting body of the email from bytes
"com.ibm.jscript.types.GeneratedWrapperObject$StaticField incompatible with com.ibm.jscript.types.FBSValue"
following is my completed code(placed in a button of an xpage). Any help would be greatly appreciated
session.setConvertMIME(false);
outputStream:java.io.ByteArrayOutputStream = new java.io.ByteArrayOutputStream();
writePdf(outputStream);
var bytes = outputStream.toByteArray();
var inputStream:java.io.ByteArrayInputStream = new java.io.ByteArrayInputStream(bytes);
var db:NotesDatabase= session.getDatabase("","mail.box")
if (!db.isOpen()) {
print ("No mailbox!")
}
else
{
var doc:NotesDocument=db.createDocument()
doc.replaceItemValue("Form","Memo")
doc.replaceItemValue("From",context.getUser().getCommonName())
doc.replaceItemValue("Principal",context.getUser().getCommonName())
doc.replaceItemValue("SendTo","a#b.com");
doc.replaceItemValue("Recipients","a#b.com");
doc.replaceItemValue("CopyTo","a#b.com");
doc.replaceItemValue("INetFrom","b#c.com");
var strFileName="temp.pdf"
var body:NotesMIMEEntity = doc.createMIMEEntity('Body');
var hdr:NotesMIMEHeader = body.createHeader("Subject");
hdr.setHeaderValAndParams("Subject")
hdr=body.createHeader("MIME-Version")
hdr.setHeaderValAndParams("1.0")
body.setPreamble("multipart message in MIME")
var child1:NotesMIMEEntity= body.createChildEntity()
hdr = child1.createHeader("Content-Disposition")
hdr.setHeaderValAndParams('attachment; filename="test.pdf"')
var stream:NotesStream = session.createStream();
stream.setContents(inputStream)
child1.setContentFromBytes(stream, "application/pdf", body.ENC_IDENTITY_BINARY)
child1.encodeContent(body.ENC_BASE64)
doc.closeMIMEEntities(true,"Body")
doc.save(true, true);
// Restore conversion
session.setConvertMIME(true);
}
function writePdf(outputStream) {
var document:com.itextpdf.text.Document = new com.itextpdf.text.Document();
var writer = com.itextpdf.text.pdf.PdfWriter.getInstance(document,outputStream);
document.open();
document.addTitle("Test PDF");
document.addSubject("Testing email PDF");
document.addKeywords("iText, email");
document.addAuthor("Author");
document.addCreator("Creator");
var passChunk:com.itextpdf.text.Chunk = new com.itextpdf.text.Chunk("Hello");
document.add(new com.itextpdf.text.Paragraph(passChunk));
document.close();
}
you probably would be better off writing a small Java wrapper class.
For starters you need:
var stream:NotesStream = session.createStream();
stream.setContents(inputStream);
stream.setPosition(0);
so the stream is at the beginning.
Update:
Also you have:
var bytes = outputStream.toByteArray();
var inputStream:java.io.ByteArrayInputStream = new java.io.ByteArrayInputStream(bytes);
stream.setContents(inputStream);
where I would write:
var bytes = outputStream.toByteArray();
stream.write(bytes);
Still, make a helper in Java.
Note: iText is GPL licenced. Unless the application you build is internal use only, you either need to buy a commercial license or GPL your code as well. Look at Apache PDFBox for an alternative

Resources