I'm using post and get request from Qualtrics api. They have sample code in java but I have a hard time to convert it into .net environment. The difficulity part is the download exported file(zip file). My question is how to implement the httpClient.execute in C#? I think in java it could hold the object without download into your physical drive and unzip the file....
Their sample code in java:
HttpGet statusGet = new HttpGet(fileUrl);
statusGet.setHeader("X-API-TOKEN", API_TOKEN);
HttpResponse response = httpClient.execute(statusGet);
// Extract exported file
ZipInputStream zs = new ZipInputStream(response.getEntity().getContent());
ZipEntry entry;
while ((entry = zs.getNextEntry()) != null)
{
FileOutputStream out = new FileOutputStream("./" + entry.getName());
IOUtils.copy(zs, out);
out.close();
}
}
Here's mine in c#:
using (var clientgetfile = new HttpClient())
{
clientgetfile.DefaultRequestHeaders.Accept.Clear();
clientgetfile.DefaultRequestHeaders.Add("X-API-TOKEN", "mytoken");
clientgetfile.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/zip"));
var response = clientgetfile.GetAsync(fileUrl);
DownloadFile = response.Result;
var byteArray = DownloadFile.Content.ReadAsStreamAsync().Result;
....
Related
How to upload a large(>4mb) file as an AppendBlob using Azure Storage Blob client library for Java?
I've successfully implemented the BlockBlob uploading with large files and it seems that the library internally handles the 4mb(?) limitation for single request and chunks the file into multiple requests.
Yet it seems that the library is not capable of doing the same for AppendBlob, so how can this chunking be done manually? Basically I think this requires to chunk an InputStream into smaller batches...
Using Azure Java SDK 12.14.1
Inspired by below answer in SO (related on doing this in C#):
c-sharp-azure-appendblob-appendblock-adding-a-file-larger-than-the-4mb-limit
... I ended up doing it like this in Java:
AppendBlobRequestConditions appendBlobRequestConditions = new AppendBlobRequestConditions()
.setLeaseId("myLeaseId");
try (InputStream input = new BufferedInputStream(
new FileInputStream(file));) {
byte[] buf = new byte[AppendBlobClient.MAX_APPEND_BLOCK_BYTES];
int bytesRead;
while ((bytesRead = input.read(buf)) > 0) {
if (bytesRead != buf.length) {
byte[] smallerData = new byte[bytesRead];
smallerData = Arrays.copyOf(buf, bytesRead);
buf = smallerData;
}
try (InputStream byteStream = new ByteArrayInputStream(buf);) {
appendBlobClient
.appendBlockWithResponse(byteStream, bytesRead,
null, appendBlobRequestConditions, null,
null);
}
}
}
Of course you need to do bunch of stuff before this, like make sure the AppendBlob exists, and if not then create it before trying to append any data.
All i am new to Jmeter and i am trying to create a rest api request that i can use to do some load test. I was able to authenticate and proceed to the next step of sending the post request.
Our Request is basically something like this
{"id" : 112, "someversion" : "2.0", "policyData" : "C:/TEMP/PGF/someinput.json" }
i was able to capture on the server what a sample request looks like. It seems that we are zipping and doing some base64 encoding before we send the request......
My main Question is how can i zip and encode this before posting so it can be similar to that format.
I have tried the following in jsr223 preprocessor:
import org.apache.commons.io.IOUtils;
import java.util.zip.GZIPOutputStream;
import org.apache.commons.codec.binary.Base64;
String bodyString = sampler.getArguments().getArgument(0).getValue();
byte [] requestBody = bodyString.getBytes();
ByteArrayOutputStream out = new ByteArrayOutputStream(requestBody.length);
GZIPOutputStream gzip = new GZIPOutputStream(out);
so in here i need to zip this. it seems it zipping and my request is as this:
I am thinking i just need to encode the policy data only and not the entire request ......
I need to do something like this in java and encrypt that file possibly before I send it in the request.
using (var cryptStream = new CryptoStream(streamWriter.BaseStream, new
ToBase64Transform(), CryptoStreamMode.Write, leaveOpen: true))
using (var gzipStream = new GZipStream(cryptStream,
CompressionMode.Compress))
using (var inputFile = new FileStream(requestData.policyData,
FileMode.Open, FileAccess.Read))
{
inputFile.CopyTo(gzipStream);
}
I think you need to:
Extract the path to file from the request body using JsonSlurper
GZip this file content
Encode the bytes array to Base64
Example code:
String bodyString = sampler.getArguments().getArgument(0).getValue();
File policyData = new File(new groovy.json.JsonSlurper().parseText(bodyString).policyData)
def fileStream = new ByteArrayOutputStream()
def gzipStream = new java.util.zip.GZIPOutputStream(fileStream)
gzipStream.write(policyData.bytes)
gzipStream.close()
def gzipped = fileStream.toByteArray()
fileStream.close()
log.info(gzipped.encodeBase64().toString())
More information on Groovy scripting in JMeter: Apache Groovy - Why and How You Should Use It
Thank you for your help... This is how i had initially solve my issue
String bodyString = sampler.getArguments().getArgument(0).getValue();
ByteArrayOutputStream rstBao = new ByteArrayOutputStream();
String JsonRequest = FileUtils.readFileToString(new
File("C:/TEMP/PGF/pgf_svc_input.json"));
GZIPOutputStream zos = new GZIPOutputStream(rstBao);
zos.write(JsonRequest.getBytes());
IOUtils.closeQuietly(zos);
byte[] bytes = rstBao.toByteArray();
//Here is where i am able to encode the bytes to base 64
Base64.encodeBase64String(bytes);
vars.put("postDataEncoded64",Base64.encodeBase64String(bytes));
log.info("khemlall this is the content"+ Base64.encodeBase64String(bytes));
log.info(vars.get("postDataEncoded64"));
rstBao.close()
In the body of my request i added the variable:
{
"id":"22351",
"pmmVersion":"2.0",
"policyData" : "${postDataEncoded64}"
}
Sample C# code:
static void UploadFile(string sasUrl, string filepath)
{
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("x-ms-version", Version);
client.DefaultRequestHeaders.Add("x-ms-client-request-id", SessionGuid);
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?><BlockList>");
foreach (byte[] chunk in GetFileChunks(filepath))
{
var blockid = GetHash(chunk);
HttpRequestMessage chunkMessage = new HttpRequestMessage()
{
Method = HttpMethod.Put,
RequestUri = new Uri(sasUrl + "&timeout=90&comp=block&blockid=" + WebUtility.UrlEncode(blockid)),
Content = new ByteArrayContent(chunk)
};
chunkMessage.Headers.Add("x-ms-blob-type", "BlockBlob");
chunkMessage.Content.Headers.Add("MD5-Content", blockid);
TimeAction("Uploading chunk " + blockid + " took {0} ms", () =>
{
var response = client.SendAsync(chunkMessage).Result;
});
sb.Append("<Latest>");
sb.Append(blockid);
sb.Append("</Latest>");
}
sb.Append("</BlockList>");
Trace.WriteLine(sb.ToString());
HttpRequestMessage commitMessage = new HttpRequestMessage()
{
Method = HttpMethod.Put,
RequestUri = new Uri(sasUrl + "&timeout=90&comp=blocklist"),
Content = new StringContent(sb.ToString())
};
TimeAction("Commiting the blocks took {0} ms", () =>
{
var commit = client.SendAsync(commitMessage).Result;
});
}
}
I am stuck at the point where I've to upload a file. Also want to know what the reason is to commit in given code?
my progress so far is :
public static void uploadFile(String sasUrl , String filepath , String sessionGuid)
{
File file = new File(filepath);
FileInputStream fileInputStream=null;
Response reply = new Response();
HttpClient client = HttpClientBuilder.create().build();
HttpPost request = new HttpPost(sasUrl);
request.setHeader("x-ms-version", "2013-08-15");
request.setHeader("x-ms-client-request-id", sessionGuid);
StringBuilder sb = new StringBuilder("<?xml version=\"1.0\" encoding=\"utf-8\"?><BlockList>");
}
}
Note: I cannot run the code multiple times as I cannot spam the server. Any suggestions will be appreciated
Referring to : https://msdn.microsoft.com/en-us/library/windows/hardware/dn800660(v=vs.85).aspx
According to the reference code in C#, it seems to be using the REST API Put Block List to upload a file as a block blob.
So you can refer to the REST API reference without refering to the C# sample to use httpclient to construct the request for uploading.
However, the simple way is using Azure Storage SDK for Java. To upload a file, you just need to use the class CloudBlockBlob to upload a file with the function upload(InputStream sourceStream, long length), please refer to the tutorial https://azure.microsoft.com/en-us/documentation/articles/storage-java-how-to-use-blob-storage/#upload-a-blob-into-a-container.
The sas url seems like https://myaccount.blob.core.windows.net/mycontainer/myblob?comp=blocklist&...
Here is the code as example.
URL sasUrl = new URL("<sas-url>");
try
{.
CloudBlockBlob blob = new CloudBlockBlob(sasUrl)
File source = new File(filePath);
blob.upload(new FileInputStream(source), source.length());
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
As reference, please see the javadocs for Azure Java Storage SDK.
I'm retrieving a PDF file from a web server java, returning a byte array.
Need save the PDF on the local machine using C #, but the file is saved completely in blank, I think it is because of the byte array format is different.
Here is my code:
StreamReader responseReader = new StreamReader(webStream);
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(URL);
request.Method = "GET";
request.ContentType = "application/pdf";
WebResponse webResponse = request.GetResponse();
Stream webStream = webResponse.GetResponseStream();
StreamReader responseReader = new StreamReader(webStream);
string response = responseReader.ReadToEnd();
responseReader.Close();
byte[] docByte = Encoding.ASCII.GetBytes(response);
File.WriteAllBytes(#"C:\file.pdf", docByte);
Any suggestions on how to save the PDF file normally?
Thank you for listening
// ...
Stream webStream = webResponse.GetResponseStream();
using (var stream = File.Create(#"C:\file.pdf"))
{
webStream.CopyTo(stream);
}
Why don't you do it simply with WebClient like this?
using System.Net;
using (WebClient webClient = new WebClient())
{
webClient.DownloadFile(URL, #"C:\file.pdf");
}
Google's official doc tells us :
The download URL for files looks something like this:
https://doc-04-20-docs.googleusercontent.com/docs/secure/m7an0emtau/WJm12345/YzI2Y2ExYWVm?h=16655626&e=download&gd=true
And it also tells us that a document entry xml is done like following :
<entry ...
...
<content type='application/zip' src='https://doc-0s-84-docs.googleusercontent.com/docs/securesc/4t...626&e=download&gd=true'/>
...
</entry>
But whatever I try with gdata java client library, I don't manage to retrieve that url. I tried all the .get*Link*() methods, and .getContent(). Does somebody met this issue and found the solution ? I've also tried to get the mediasource and work on its input stream.
The finality of that is to get the file's content (the file is binary with a custom format) back on my java application server (GAE) to send it to my client who can parse it and view it.
Cheers,
Ricola3D
Finally I found the solution by myself, it seems I was just using it wrong. Here is the code if someday somebody else needs !
URL entryUrl = new URL("https://docs.google.com/feeds/default/private/full/"+mydocumentid);
DocumentEntry mydocument = client.getEntry(entryUrl, DocumentEntry.class);
if (mydocument!=null) { // if we can read the document
MediaContent content = (MediaContent) mydocument.getContent();
//URL exportUrl = new URL(content.getUri()); // download url
MediaSource source = client.getMedia(content);
InputStream inStream = null;
OutputStream outStream = null;
try {
inStream = source.getInputStream();
outStream = resp.getOutputStream();
int c;
while ((c = inStream.read()) != -1) {
outStream.write(c); // copy the stream, by 1byte per 1byte is very slow !
}
} finally {
if (inStream != null) {
inStream.close();
}
if (outStream != null) {
outStream.flush();
outStream.close();
}
}