send compressed message using avro - rpc

I have a POJO which in need to send to another end-poind (some server).
I have decided it do it using avro.
So far I have created my Avro schema and generated my DataFileWriter:
GenericRecord user1 = new GenericData.Record(schema);
user1.put("name", "Jenny");
user1.put("favorite_color", "green");
GenericRecord user2 = new GenericData.Record(schema);
user2.put("name", "Kevin");
user2.put("favorite_color", "red");
DatumWriter<GenericRecord> datumWriter = new GenericDatumWriter<GenericRecord>(schema);
DataFileWriter<GenericRecord> dataFileWriter = new DataFileWriter<GenericRecord>(datumWriter);
dataFileWriter.create(schema, schemaFile);
dataFileWriter.append(user1);
dataFileWriter.append(user2);
This is what I have so far and I'm missing the following:
I would like to compress the data before sending it, I rather doing it using snappy, how should I combine it with my code?
UPDATE:
Added these lines:
// use snappy compression
CodecFactory codecFactory = CodecFactory.snappyCodec();
dataFileWriter.setCodec(codecFactory);
But I'm not sure yet if it does the job.

Using this:
public byte[] serialize(T objectToSerialize) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
DatumWriter<T> reflectDatumWriter = new ReflectDatumWriter<T>(avroSchema);
DataFileWriter<T> fileWriter = null;
try {
fileWriter = new DataFileWriter<T>(reflectDatumWriter);
fileWriter.setCodec(CodecFactory.snappyCodec());
fileWriter.create(avroSchema, out);
fileWriter.append(objectToSerialize);
fileWriter.close();
} catch (Exception e) {
LOG.error(e);
return null;
}
return out.toByteArray();
}

Related

OpenXml Cannot Read or Write To Azure Blob Storage with FileMode or FileAccess value is invalid for the stream

We are working with DocumentFormat.OpenXml.WordDocument and opening a template of a Wordfile inside the Azure Blob, writing to it and saving it. There are two issues:
During the opening of the Document
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(streamToWrite, true))
Here the issue is like this ->
DocumentFormat.OpenXml.Packaging.OpenXmlPackageException: 'The stream was not opened for writing.'
If I replaces the IsEditable=trueto false, the issue will go. But the another issue occurs subsequently during the reading of the stream, after the changing the texts.
// Writing the changed document using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.OpenOrCreate)))
The Error is like this-> System.ArgumentException: 'Stream was not writable.'
Final Code is like this, which is referred from this link : -https://learn.microsoft.com/en-us/office/open-xml/how-to-search-and-replace-text-in-a-document-part
public async Task<IActionResult> UpdateDocumentAsync([FromBody] ProcessingQuery query)
{
BlobClient readblob = new BlobClient(new Uri("https://XXXXXX/docxviewer/outputviewer/blob.docx?sp=racwd"));
using (HttpClient client = new HttpClient())
{
using (Stream streamToWrite = await client.GetStreamAsync(readblob.Uri))
{
try
{
using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(streamToWrite, false))
{
string docText = null;
using (StreamReader sr = new StreamReader(wordDoc.MainDocumentPart.GetStream()))
{
docText = sr.ReadToEnd();
}
//Writing of Single Queries this will become dictionary key-value pair
Regex regexText1 = new Regex("{first_name}");
docText = regexText1.Replace(docText, query?.first_Name);
Regex regexText2 = new Regex("{last_name}");
docText = regexText2.Replace(docText, query?.last_Name);
Regex regexText3 = new Regex("{phone}");
docText = regexText2.Replace(docText, query?.phone);
// Writing the changed document
using (StreamWriter sw = new StreamWriter(wordDoc.MainDocumentPart.GetStream(FileMode.OpenOrCreate)))
{
sw.Write(docText);
sw.Flush();
sw.Close();
}
wordDoc.Close();
}
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
streamToWrite.Close();
}
}
return Ok(readblob);
}
Please help us on this codes with relevant codes and documents. If there is any issue in blob storage token Kindly help us in that too.. :)

BufferedReader is sometimes empty

I have Loader class where I load txt file into BufferedReader from resources and return this field. I use this method but it acts really strange(for me). When I don't put
String str = bufferReader.readLine(); after
bufferReader = new BufferedReader(fileReader);
(in Loader class) than bufferReader in another class is empty, and readLine() returns null. When I write that piece of code in Loader class, I can read each line from txt, except the 1. one which is read in Loader class. Also, I can't read last line if I dont put enter at the end.
public BufferedReader loadFromFileToBufferReader(String fileName) {
ClassLoader classLoader = getClass().getClassLoader();
System.out.print(getClass().getClassLoader().getResource("resources/" + fileName));
File file = new File(classLoader.getResource("resources/" + fileName).getFile());
BufferedReader bufferReader = null;
try (FileReader fileReader = new FileReader(file)) {
bufferReader = new BufferedReader(fileReader);
String str = bufferReader.readLine();
} catch (IOException e) {
System.err.println("Something went terribly wrong with file reading");
}
return bufferReader;
}
and usage:
public Database() {
productsInDatabse = new ArrayList<>();
codesList = new ArrayList<>();
loader = new LoadFromFile();
BufferedReader output = loader.loadFromFileToBufferReader("database.txt");
Product product;
String line;
String[] array;
try {
line = output.readLine();
while (line != null) {
You should paste your code here because it's hard to deduce all the possible causes of this without seeing the code on 100% but I am guessing you have it the same file open at the same time from multiple sources without closing it before from one? Could be literally millions of little things, just telling you how the same error happened to me.

Poi4Xpages - write file to document during postGeneration

as per a suggestion recently received from Stwissel, I am using the following code to convert a file to mime and attach to a notes document during the post generation process of POI4Xpages.
EDITED NEW CODE:
The following code attaches to document, but throws an error: 502 Bad Gateway - The server returned an invalid or incomplete response.
public void saveExcel(Workbook a, Document newDoc) throws NotesException, IOException{
newDoc.replaceItemValue("Form", "Provider");
// Create the stream
Session session = DominoUtils.getCurrentSession();
Stream stream = session.createStream();
// Write the workbook to a ByteArrayOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
a.write(bos);
// Convert the output stream to an input stream
InputStream is = new ByteArrayInputStream(bos.toByteArray());
stream.setContents(is);
MIMEEntity m = newDoc.createMIMEEntity("body");
MIMEHeader header = m.createHeader("content-disposition");
header.setHeaderVal("Mime attachment");
m.setContentFromBytes(stream, "application/vnd.ms-excel", MIMEEntity.ENC_IDENTITY_BINARY);
m.decodeContent();
newDoc.save(true, true);
}
ORIGINAL CODE:
var stream:NotesStream = session.createStream();
// Do not automatically convert MIME to rich text
session.setConvertMIME(false);
var doc:NotesDocument = database.createDocument();
doc.replaceItemValue("Form", "Provider");
var body:NotesMIMEEntity = doc.createMIMEEntity();
var header:NotesMIMEHeader = body.createHeader("Subject");
header.setHeaderVal("MIME attachment");
if (stream.open("c:\\notes\\data\\abc.xlsx", "binary")) {
if (stream.getBytes() != 0) {
body.setContentFromBytes(stream, "application/vnd.ms-excel",
NotesMIMEEntity.ENC_IDENTITY_BINARY);
} else requestScope.status = "File was not found.";
} else requestScope.status = "Could not open file.";
stream.close();
doc.save(true, true);
// Restore conversion
session.setConvertMIME(true);
However, this code is only attaching a file which is already stored on the server's local directory. How can I get this code to take the POI fileOutputStream and attach that?
It's a mix of what what Knut and I've commented about. The important part is that you'll use the write() method to pass the workbook data to an output stream.
// Create the stream
Stream stream = session.createStream();
// Write the workbook (you haven't clarified) to a ByteArrayOutputStream
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
// Convert the output stream to an input stream
InputStream is = new ByteArrayInputStream(bos.toByteArray());
stream.setContents(is);

Replace and delete PDF File

I am using the following piece of code to delete the old PDF and replace the old one with the new one but with no result. Is is possible to perform this operation on PDF files? As, throughout the net I see that these functions are used for .txt,.xls.doc...etc file types. Is there anything wrong with my code? Please help...
private void ListFieldNames(string s)
{
try
{
string pdfTemplate = #"z:\TEMP\PDF\PassportApplicationForm_Main_English_V1.0.pdf";
//var newFile = pdfTemplate;
string newFile = #"z:\TEMP\PDF\_PassportApplicationForm_Main_English_V1.0.pdf";
PdfReader pdfReader = new PdfReader(pdfTemplate);
for (int page = 1; page <= pdfReader.NumberOfPages; page++)
{
//ITextExtractionStrategy its = new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
PdfReader reader = new PdfReader((string)pdfTemplate);
//PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create));
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
{
AcroFields form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
//Replace Address Form field with my custom data
if (fieldKey.Contains("Surname"))
{
form.SetField(fieldKey, s);
}
}
// set form fields
//form.SetField("Address", s);
stamper.FormFlattening = true;
stamper.Close();
}
}
File.Copy(newFile, pdfTemplate);
File.Delete(pdfTemplate);
}
Everything looks good to me, just change:
File.Copy(newFile, pdfTemplate);
File.Delete(pdfTemplate);
change to:
File.Delete(pdfTemplate);
File.Copy(newFile, pdfTemplate);
You can't copy a file if a file already exists at its location with the same name as it.
Delete existing file first.

Merge memorystreams to one iText document

I have four MemoryStreams of data that I want to merge and then open the pdfDocument, without creating a single file.
It's possible to write them down to files and then merge them but that would be bad practice and that can also cause a few issues so I want to avoid that.
However, I can not find a way to merge the MemoryStreams with iText5 for .NET.
Right now, this is how I do it with files:
private static void ConcatenateDocuments()
{
var stream = new MemoryStream();
var readerFrontPage = new PdfReader(Folder + FrontPageName);
var readerDocA = new PdfReader(Folder + docA);
var readerDocB = new PdfReader(Folder + DocB);
var readerAppendix = new PdfReader(Folder + Appendix);
var pdfCopyFields = new PdfCopyFields(stream);
pdfCopyFields.AddDocument(readerFrontPage);
pdfCopyFields.AddDocument(readerDocA );
pdfCopyFields.AddDocument(readerDocB);
pdfCopyFields.AddDocument(readerAppendix);
pdfCopyFields.Close();
SavePdf(stream, FilenameReport);
}
Since I need to remove the use of files, I keep the MemoryStream's as the different parts are built from different resources. So I have references to these memorystreams.
How can this be done?
The error PDF header signature not found can be fixed in this case by setting the stream's Position back to 0. Since you're not getting the error Cannot access a closed Stream I'm assuming that you are already correctly setting the PdfWriter's CloseStream to false.
Below is a full working C# 2010 WinForm app targeting iTextSharp 5.1.1.0 that creates three PDFs in MemoryStreams and combines them. Since I don't have a web server handy I'm writing them to disk.
using System;
using System.Text;
using System.Windows.Forms;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Create three MemoryStreams
MemoryStream[] streams = { CreateDoc("Page 1"), CreateDoc("Page 2"), CreateDoc("Page 3") };
//I don't have a web server handy so I'm going to write my final MemoryStream to a byte array and then to disk
byte[] bytes;
//Create our final combined MemoryStream
using (MemoryStream finalStream = new MemoryStream())
{
//Create our copy object
PdfCopyFields copy = new PdfCopyFields(finalStream);
//Loop through each MemoryStream
foreach (MemoryStream ms in streams)
{
//Reset the position back to zero
ms.Position = 0;
//Add it to the copy object
copy.AddDocument(new PdfReader(ms));
//Clean up
ms.Dispose();
}
//Close the copy object
copy.Close();
//Get the raw bytes to save to disk
bytes = finalStream.ToArray();
}
//Write out the file to the desktop
string outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Combined.pdf");
using (FileStream fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None))
{
fs.Write(bytes, 0, bytes.Length);
}
this.Close();
}
/// <summary>
/// Helper method to create temporary documents
/// </summary>
private MemoryStream CreateDoc(string name)
{
MemoryStream ms = new MemoryStream();
using (Document doc = new Document(PageSize.LETTER))
{
using (PdfWriter writer = PdfWriter.GetInstance(doc, ms))
{
writer.CloseStream = false;
doc.Open();
doc.Add(new Paragraph(name));
doc.Close();
}
}
return ms;
}
}
}
While it seams the PdfReader can not take the stream, the array of the stream works.
var readerFrontPage = new PdfReader(streamFrontPage.ToArray());

Resources