Downloading files without fileDownloadActionListener - oracle-adf

To download a file without using fileDownloadActionListener I add a button on a page:
<af:commandButton text="Download" id="cb1" partialSubmit="true" actionListener="#{bean.downloadListener}"/>
and in the action listener I write the following:
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.redirect("http://download-server/file");
fc.responseComplete();
The problem is, after the first download the button stops responding to clicks.
I've also tried writing the data to the response stream like this:
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset();
ec.setResponseContentType("application/xls");
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"report.xls\"");
OutputStream out = ec.getResponseOutputStream();
// write the data
out.close();
fc.responseComplete();
and even getting an HttpServletResponse:
HttpServletResponse resp = (HttpServletResponse)ec.getResponse();
resp.addHeader("Content-Disposition", "attachment; filename=\"report.xls\"");
resp.addHeader("Content-Type", "application/xls");
OutputStream out = resp.getOutputStream();
// write the data
out.close();
fc.responseComplete();
but neither works.
What can I do to make it work?

I've implemented this using a bit of JavaScript:
final FacesContext fc = FacesContext.getCurrentInstance();
final ExtendedRenderKitService erks =
Service.getService(fc.getRenderKit(), ExtendedRenderKitService.class);
erks.addScript(fc, String.format("window.location = '%s';", escapeSingleQuotes(url)));
Or, instead of assigning window.location, download using an inline frame:
erks.addScript(
fc,
String.format("var downloadUrl = '%s';", escapeSingleQuotes(url)) +
"var frame = document.createElement('iframe');" +
"frame.setAttribute('src', downloadUrl);" +
"frame.style.border = '0';" +
"frame.style.clip = 'rect(0 0 0 0)';" +
"frame.style.width = '1px';" +
"frame.style.height = '1px';" +
"frame.style.margin = '-1px';" +
"frame.style.padding = '0';" +
"frame.style.position = 'absolute';" +
"document.body.appendChild(frame);"
);

Related

Mule - Salesforce connector - Retrieve job failed results bulk v2 - not returning failed data

I am querying Salesforce Bulk api failed results in Mule. But it doesn't fetch the data. It jus shows the record id and error message. But if i check in workbench, it shows the id, error, datacolumns(a,b,c)
How to get those details..Is there any other way to get the bulk api v2 failed results in Mule
doing simple Transformation before logging
%dw 2.0
output application/json
---
payload
Debug Log :
On workbench, I get the actual data.
please share your thoughts why i don't see those data
#RestResource(urlMapping='/bulkapi/failures')
global without sharing class RestGetBulkAPIResults
{
#HttpGet
global static void getFailedRecords()
{
RestRequest req = RestContext.request;
RestResponse res = RestContext.response;
res.addHeader('Content-Type', 'application/json');
Http http = new Http();
HttpRequest httpReq = new HttpRequest();
HttpResponse httpRes = new HttpResponse();
httpReq.setMethod('GET');
httpReq.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId());
string path = '/services/data/v48.0/jobs/ingest/7502i000001fJG9AAM/failedResults/';
httpReq.setEndpoint(URL.getSalesforceBaseUrl().toExternalForm()+ path);
httpRes = http.send(httpReq);
string op = httpRes.getBody();
string[] rowList = op.split('\n');
string[] headers = rowList[0].split(',');
integer columnsCount = headers.size();
integer dataRowsCount = rowList.size();
string fullFormattedData = '[';
for(integer rowIndex =1; rowIndex < dataRowsCount; rowIndex++)
{
string[] rowData = rowList[rowIndex].split(',');
string rowJsonData ='{';
for(integer columnIndex=0; columnIndex < columnsCount; columnIndex++)
{
rowJsonData += headers[columnIndex] + ':' + rowData[columnIndex] + ',';
}
rowJsonData = rowJsonData.removeEnd(',');
rowJsonData += '}';
fullFormattedData += rowJsonData;
}
fullFormattedData += ']';
system.debug('resp' + httpRes.getBody());
res.responseBody = Blob.valueOf(fullFormattedData);
res.statusCode = 200;
}
}

How do i filter using a partial VM name (string) in vmware vSphere client REST API?

Good day!
i am trying to automate some actions to be done to VM's in my organisation.
The action to be done depends on the a substring in the VM name.
for eg, i would need to delete all VM's whose name starts with 'delete', etc.
I can use the below API to fetch the list of VM's:
GET https://{{vc}}/rest/vcenter/vm
However, this API can only fetch a maximum of 1000 VM's.
Is there any way i can filter and get only the list of VM's with the expected substring from this API?
from what i understand, appending filter.names.1 to the above API works but for that i need to input the exact and entire VM name.
is there a way where i can search for a list of VM's with partial text?
Apologies, i am a newbie to this.
thank you for your time!
Since vSphere API does not provide such capability to search by partial VM name there is a tricky way to do this.
I am using the search functionality in vSphere Client 6.7.0.
Prerequisite is to get the following cookies first:
VSPHERE-USERNAME
VSPHERE-CLIENT-SESSION-INDEX
VSPHERE-UI-JSESSIONID
You have to do three calls in order to get them:
1. GET "https://[URL]/ui/login" you will be forwarded to a new URL from where you can take "SAMLRequest token"
2. POST "https://[URL]/websso/SAML2/SSO/vsphere.local?SAMLRequest=[SAMLRequest token]", set as header "CastleAuthorization=Basic%20[credentials]" where credentials is the Base64 encoding of "User:Password". Get the value of "SAMLResponse" hidden field from the response.
3. POST "https://[URL]/ui/saml/websso/sso", set "SAMLResponse=[SAMLResponse value]", where "SAMLResponse value" you have it from the previous response. From this response you will get the cookies.
Once you have those three cookies, make a new call as you set the cookies
4. GET "https://[URL]/ui/search/quicksearch/?opId=0&query=[partial VM name]"
For example for this call "https://[URL]/ui/search/quicksearch/?opId=0&query=test"
you will get response like this:
[{
"icon": "vsphere-icon-vm",
"labelPlural": "Virtual Machines",
"label": "Virtual Machine",
"results": [{
"id": "urn:vmomi:VirtualMachine:vm-2153:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM1"
}, {
"id": "urn:vmomi:VirtualMachine:vm-3391:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM2"
}, {
"id": "urn:vmomi:VirtualMachine:vm-3438:103ac083-e314-47ea-942a-c685d9a4e6c9",
"type": "VirtualMachine",
"name": "TestVM3"
}
]
}
]
Below is my own vSphere Search Proxy Client written in C#:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
namespace VsphereSearchProxy
{
static class Program
{
const string VSPHERE_URL = "VSPHERE_URL";
static string VSPHERE_CRED_BASE64
{
get
{
var plainTextCred = Encoding.UTF8.GetBytes("USER:PASS");
return Convert.ToBase64String(plainTextCred);
}
}
static void Main(string[] args)
{
if (args.Length == 0)
{
Console.WriteLine("Expected one argument: Virtual Machine name");
return;
}
var vmName = args[0];
var vsphereUri = VSPHERE_URL.TrimEnd('/');
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = true;
//=================================================================
Console.WriteLine("\nStep 1\n");
var url1 = vsphereUri + "/ui/login";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url1);
request.Method = "GET";
request.KeepAlive = true;
request.AllowAutoRedirect = true;
var response = (HttpWebResponse)request.GetResponse();
var url2 = response.ResponseUri.AbsoluteUri;
Console.WriteLine("url2: " + url2);
WebHeaderCollection headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
//=================================================================
Console.WriteLine("\nStep 2\n");
request = (HttpWebRequest)WebRequest.Create(url2);
request.Method = "POST";
request.Headers.Add("Authorization: Basic " + VSPHERE_CRED_BASE64);
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = true;
request.AllowAutoRedirect = false;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("CastleAuthorization=Basic%20" + VSPHERE_CRED_BASE64);
streamWriter.Flush();
streamWriter.Close();
}
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Expected 200 OK, but got " + response.StatusCode);
}
headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
var responseString = "";
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
responseString = reader.ReadToEnd();
}
var SAMLResponse = "";
Match match = Regex.Match(responseString, "<input[^>]*type=\"hidden\"\\s+name=\"SAMLResponse\"[^>]*value=\"([^\"]*)\"");
if (match.Success)
{
SAMLResponse = match.Groups[1].Value;
SAMLResponse = SAMLResponse.Replace("\n", "");
//Console.WriteLine("SAMLResponse: " + SAMLResponse);
}
if (string.IsNullOrWhiteSpace(SAMLResponse))
{
throw new Exception("SAMLResponse is missing or blank");
}
//=================================================================
Console.WriteLine("\nStep 3\n");
var url3 = vsphereUri + "/ui/saml/websso/sso";
request = (HttpWebRequest)WebRequest.Create(url3);
request.Method = "POST";
request.Headers.Add("Authorization: Basic " + VSPHERE_CRED_BASE64);
request.ContentType = "application/x-www-form-urlencoded";
request.KeepAlive = true;
request.AllowAutoRedirect = false;
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
streamWriter.Write("SAMLResponse=" + HttpUtility.UrlEncode(SAMLResponse));
streamWriter.Flush();
streamWriter.Close();
}
response = (HttpWebResponse)request.GetResponse();
var cookies = response.Headers["Set-Cookie"];
Console.WriteLine("cookies: " + cookies);
headerCollection = response.Headers;
Console.WriteLine("\nResponse headers\n");
for (int i = 0; i < headerCollection.Count; i++)
{
Console.WriteLine("\t" + headerCollection.GetKey(i) + " = " + headerCollection.Get(i));
}
//=================================================================
Console.WriteLine("\nStep 4\n");
var url4 = vsphereUri + "/ui/search/quicksearch/?opId=:1&query=" + vmName;
request = (HttpWebRequest)WebRequest.Create(url4);
request.Method = "GET";
request.Headers.Add("Cookie: " + cookies);
request.KeepAlive = true;
request.AllowAutoRedirect = false;
response = (HttpWebResponse)request.GetResponse();
if (response.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Expected 200 OK, but got " + response.StatusCode);
}
var jsonResp = "";
using (Stream stream = response.GetResponseStream())
{
StreamReader reader = new StreamReader(stream, Encoding.UTF8);
jsonResp = reader.ReadToEnd();
}
Console.WriteLine(jsonResp);
}
}
}
Unfortunately the vSphere Automation API isn't setup to filter on partial names or even when using a wildcard. Some of the available filters may help you limit the output to be under the 1000 object limit (example: filter on specific clusters and/or folders).
Hopefully this is something that's added in a future release.

Exception in Service NOW attachment API invocation-- Premature end of chunk coded message body: closing chunk expected

I am using HttpClient to send POST multipart request, using the below code
String apiUrl = API_URL_DEV;
String name = API_USER_DEV;
String password = API_PASSWORD_DEV;
String authString = name + ":" + password;
String encoding = Base64.getEncoder().encodeToString(authString.getBytes());
apiUrl = "https://<servicenow host>/api/now/attachment/upload";
try {
Header header = new BasicHeader(HttpHeaders.CONTENT_TYPE, "multipart/form-data");
Header header2 = new BasicHeader(HttpHeaders.ACCEPT, "application/json");
Header header3 = new BasicHeader(HttpHeaders.AUTHORIZATION, "Basic " + encoding);
List<Header> headers = new ArrayList<Header>();
headers.add(header);
headers.add(header2);
headers.add(header3);
HttpHost proxy = new HttpHost("xxxx", 8080, "http");
CloseableHttpClient client = HttpClientBuilder.create()
.setDefaultHeaders(headers)
.setProxy(proxy)
.build();
HttpPost post = new HttpPost(apiUrl);
String textFileName = "C:/Heena_Code/Test.xlsx";
File file = new File(textFileName);
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
FileBody fileBody = new FileBody(file, ContentType.DEFAULT_BINARY);
StringBody stringBody1 = new StringBody("change_request", ContentType.MULTIPART_FORM_DATA);
StringBody stringBody2 = new StringBody("a81c6a1ddb2948d04af824f4059619a9", ContentType.MULTIPART_FORM_DATA);
builder.addPart("table_name", stringBody1);
builder.addPart("table_sys_id", stringBody2);
builder.addPart("uploadFile", fileBody);
HttpEntity entity = builder.build();
post.setEntity(entity);
// Execute HTTP Post Request
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = client.execute(post, responseHandler); -----> exception here
System.out.println(responseBody);
Getting exception
Severe: org.apache.http.ConnectionClosedException: Premature end of chunk coded message body: closing chunk expected
at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:263)
at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:222)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:183)
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:210)
at org.apache.http.impl.io.ChunkedInputStream.close(ChunkedInputStream.java:312)
at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:142)
at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228)
at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:172)
at org.apache.http.client.entity.LazyDecompressingInputStream.close(LazyDecompressingInputStream.java:97)
at org.apache.http.util.EntityUtils.consume(EntityUtils.java:90)
at org.apache.http.impl.client.AbstractResponseHandler.handleResponse(AbstractResponseHandler.java:69)
at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:66)
at org.apache.http.impl.client.BasicResponseHandler.handleResponse(BasicResponseHandler.java:52)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:223)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:165)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:140)
I changed my approach and used a MultiPartUtility class to fire request through HTTPUrlConnection passing two form fields in text/plain format and the file in application/octetstream format and binary encoding

Cannot send a content-body with this verb-type. error while getting response when trying to Upload file in Box Storage

When i am trying to upload files in Box Storage using api provided by Box but at response time i am getting this error
public static void UploadFileRequest(string FolderID, string accesstoken)
{
string boundary = string.Format("----------------------------{0}", DateTime.Now.Ticks.ToString("x"));
string filename="C:\\Users\\Administrator\\Desktop\\Text.txt";
HttpWebRequest httpWReq = (HttpWebRequest)WebRequest.Create("https://upload.box.com/api/2.0/files/content");
ASCIIEncoding encoding = new ASCIIEncoding();
string hh = "\"filename=#\"" + filename + "\" "+";"+"";
hh += "parent_id=\"" + FolderID + "\"";
string kj = string.Format(("filename=#" + filename));
byte[] data = encoding.GetBytes(hh);
httpWReq.Headers.Add("Authorization", "Bearer " + accesstoken);
httpWReq.ContentType = "application/json";
httpWReq.ContentLength = data.Length;
using (Stream stream = httpWReq.GetRequestStream())
{
stream.Write(data, 0, data.Length);
}
HttpWebResponse response = (HttpWebResponse)httpWReq.GetResponse();
string responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
}
Without knowing the Box API, I will assume that the upload should be a POST operation, so you will need to specify the correct HTTP method on your request, before sending it:
httpWReq.Method = "POST";
The Method property defaults to "GET", and GET operations does not normally have a body..
Here is the solution , as C# accepts bytes format and then any Upload is done , i was missing that .. hope it helps
private void UploadBoxFile(string Filename)
{
HttpWebRequest req = HttpWebRequest.Create("https://upload.box.com/api/2.0/files/content") as HttpWebRequest;
req.Method = "POST";
req.Headers.Add("Authorization", "Bearer < Access Token >");
req.ContentType = "multipart/form-data; boundary=\"d174f29b-6def-47db-8519-3da38b21b398\"";
string Content = GetFormatedData(Filename);
req.ContentLength = Content.Length;
using (Stream Writer = req.GetRequestStream())
{
Writer.Write(Encoding.UTF8.GetBytes(Content), 0, Content.Length);
}
req.GetResponse();
}
private string GetFormatedData(string Filename)
{
StringBuilder build = new StringBuilder();
string Id = "d174f29b-6def-47db-8519-3da38b21b398";
build.AppendLine("--" + Id);
build.AppendLine("Content-Disposition: form-data; filename=\"hello1.txt\"; name=\"filename\"");
build.AppendLine("Content-Type: application/octet-stream");
build.AppendLine();
string FileContent = "This is a sample text";
build.AppendLine(FileContent);
build.AppendLine("--" + Id);
build.AppendLine("Content-Disposition: form-data; name=\"folder_id\"");
build.AppendLine();
build.AppendLine("0");
build.AppendLine("--" + Id + "--");
return build.ToString();
}
Thanks..

Post data to web API

I've been trying to send data to a web API VIA post. But it doesn't seem to be sending it.
Here's how I do it.
var baseAddress = "http://192.168.0.103/vchatapi/api/Images?gsmNumber=" + profileNumberLbl.Content + "&content=" + base64 + "&contentType=image/" + contentType;
var http = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new System.Uri(baseAddress));
http.Accept = "application/json";
http.ContentType = "application/json";
http.Method = "POST";
This code works with get:
var baseAddress = "http://192.168.0.103/vchatapi/api/SendSMSVerificationCode?gsmNumber=" + areCode + mobile + "&udid=123456";
var http = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(new System.Uri(baseAddress));
http.Accept = "application/json";
http.ContentType = "application/json";
http.Method = "GET";
try
{
var response = http.GetResponse();
var stream = response.GetResponseStream();
var sr = new StreamReader(stream);
var content = sr.ReadToEnd();
verificationCode = verificationCode.FromJson(content);
if (!verificationCode.Equals(""))
{
MessageBox.Show(this, "Verification Code: " + verificationCode);
verificationTextBox.IsEnabled = true;
areaCodeCB.IsEnabled = false;
mobileNumberTB.IsEnabled = false;
}
else
{
MessageBox.Show(this, "Invalid Number");
}
}
catch (Exception ex)
{
MessageBox.Show(this, ex.Message);
}
Any ideas? Thanks!
Since you are doing a POST, you would be sending the content in the body of the request. You would need to get hold of the request's stream and write data to it. The following answer post has a very concise example:
https://stackoverflow.com/a/2551006/1184056

Resources