I'm working with Azure Blob Storage and C#. I need to delete a blob using the API REST, but I get the 403 Forbidden error. I'm using the same function to generate the authentication header for create a new blob, but it works for put but doesn't it for delete. This is my code:
public bool DeleteBlob(string containerName, string fileName)
{
string blobName = fileName;
string method = "DELETE";
string requestUri = $"https://{_accountName}.blob.core.windows.net/{containerName}/{blobName}";
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUri);
string now = DateTime.UtcNow.ToString("R", CultureInfo.InvariantCulture);
request.Method = method;
request.Headers.Add("x-ms-version", "2020-10-02");
request.Headers.Add("x-ms-date", now);
request.Headers.Add("x-ms-delete-snapshots", "include");
request.Headers.Add("Authorization", AuthorizationHeader("DELETE", request, containerName, blobName));
bool result = false;
using (HttpWebResponse resp = (HttpWebResponse)request.GetResponse())
{
if (resp.StatusCode != HttpStatusCode.Accepted && resp.StatusCode != HttpStatusCode.OK)
{
throw new Exception(resp.StatusDescription);
}
result = true;
}
return result;
}
private string AuthorizationHeader(string method, HttpWebRequest request, string containerName, string blobName)
{
string urlResource = $"/{_accountName}/{containerName}/{blobName}";
string stringToSign = $"{method}\n\n\n{request.ContentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{GetCanonicalizedHeaders(request)}{GetCanonicalizedResource(request.RequestUri, _accountName)}";
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(_accountKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return string.Format("{0} {1}:{2}", "SharedKey", _accountName, signature);
}
private string GetAuthorizationHeader(string method, HttpWebRequest request, string now, string containerName, string blobName)
{
string urlResource = $"/{_accountName}/{containerName}/{blobName}";
var canonicalizedStringToBuild = string.Format("{0}\n{1}", now, $"/{_accountName}/" + urlResource);
string signature;
using (var hmac = new HMACSHA256(Convert.FromBase64String(_accountKey)))
{
byte[] dataToHmac = Encoding.UTF8.GetBytes(canonicalizedStringToBuild);
signature = Convert.ToBase64String(hmac.ComputeHash(dataToHmac));
}
return string.Format($"{_accountName}:" + signature);
}
private string GetCanonicalizedHeaders(HttpWebRequest request)
{
ArrayList headerNameList = new ArrayList();
StringBuilder sb = new StringBuilder();
foreach (string headerName in request.Headers.Keys)
{
if (headerName.ToLowerInvariant().StartsWith("x-ms-", StringComparison.Ordinal))
{
headerNameList.Add(headerName.ToLowerInvariant());
}
}
headerNameList.Sort();
foreach (string headerName in headerNameList)
{
StringBuilder builder = new StringBuilder(headerName);
string separator = ":";
foreach (string headerValue in GetHeaderValues(request.Headers, headerName))
{
string trimmedValue = headerValue.Replace("\r\n", String.Empty);
builder.Append(separator);
builder.Append(trimmedValue);
separator = ",";
}
sb.Append(builder.ToString());
sb.Append("\n");
}
return sb.ToString();
}
private string GetCanonicalizedResource(Uri address, string accountName)
{
StringBuilder str = new StringBuilder();
StringBuilder builder = new StringBuilder("/");
builder.Append(accountName);
builder.Append(address.AbsolutePath);
str.Append(builder.ToString());
NameValueCollection values2 = new NameValueCollection();
if (address.Query.Length > 0)
{
string query = address.Query.Remove(0, 1);
var queryParts = query.Split('&');
foreach (var queryPart in queryParts)
{
var parts = queryPart.Split('=');
values2.Add(parts[0], parts[1]);
}
ArrayList list2 = new ArrayList(values2.AllKeys);
list2.Sort();
foreach (string str3 in list2)
{
StringBuilder builder3 = new StringBuilder(string.Empty);
builder3.Append(str3);
builder3.Append(":");
builder3.Append(values2[str3]);
str.Append("\n");
str.Append(builder3.ToString());
}
}
return str.ToString();
}
Could anyone tell me what I'm doing wrong? As I commented for create a new blob working fine, but not for deletion. I don't know if the authentication header is different for delete (I know the method name is different) I have not found much information about that.
Thannks.
The reason your delete operation is failing with 403 error is because in your stringToSign you're assigning content length as 0 whereas it should be an empty string.
Please change your AuthorizationHeader method code to the code mentioned below and your delete blob operation should work just fine:
private string AuthorizationHeader(string method, HttpWebRequest request, string containerName, string blobName)
{
string urlResource = $"/{_accountName}/{containerName}/{blobName}";
var contentLength = request.ContentLength == 0 ? "" : request.ContentLength.ToString();
string stringToSign = $"{method}\n\n\n{contentLength}\n\n{request.ContentType}\n\n\n\n\n\n\n{GetCanonicalizedHeaders(request)}{GetCanonicalizedResource(request.RequestUri, _accountName)}";
HMACSHA256 hmac = new HMACSHA256(Convert.FromBase64String(_accountKey));
string signature = Convert.ToBase64String(hmac.ComputeHash(Encoding.UTF8.GetBytes(stringToSign)));
return string.Format("{0} {1}:{2}", "SharedKey", _accountName, signature);
}
What I have done above is set the content length value to an empty string if the content length is 0.
From this link (emphasis mine):
In the current version, the Content-Length field must be an empty
string if the content length of the request is zero. In version
2014-02-14 and earlier, the content length was included even if zero.
I would like to ask how to fetch all doc from solr collection using solrJ.
I have written one code but getting error
Exception in thread "main" org.apache.solr.client.solrj.SolrServerException: No collection param specified on request and no default collection has been set.
String zkHostString = "linux152:2181,linuxUL:2181,linux170:2181/solr";
CloudSolrClient server = new CloudSolrClient(zkHostString);
SolrQuery parameters = new SolrQuery();
public void cursorMark() throws IOException, SolrServerException {
SolrQuery parameters = new SolrQuery();
QueryResponse response = new QueryResponse();
response = server.query(parameters);
parameters.set("q",":");
parameters.set("qt","/select");
parameters.setParam("wt","json");
parameters.set("collection", "RetailDev_Protocol");
int fetchSize = 2;
parameters.setRows(fetchSize);
String cursorMark = CursorMarkParams.CURSOR_MARK_START;
boolean done = false;
while (! done) {
parameters.set(CursorMarkParams.CURSOR_MARK_PARAM, cursorMark);
long offset = 0;
long totalResults = response.getResults().getNumFound();
while (offset < totalResults)
{
parameters.setStart((int) offset);
try {
for (SolrDocument doc : server.query(parameters).getResults())
{
log.info((String) doc.getFieldValue("title"));
}
} catch (SolrServerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
offset += fetchSize;
}
String nextCursorMark = (response).getNextCursorMark();
}
SolrDocumentList list = response.getResults();
System.out.println(list.toString());
}
You need to set your collection in the following way:
server.setDefaultCollection("<MY_COLLECTION");
otherwise you get the error that you specified in your question.
i am facing a issue on getting JObject, my app is working in emulator and it is not working in device. because the string is not properly converting to JObject.
E/JSON 1111﹕ parsing data {"success":1,"projects":[{"thumbimg":"http:\/\/spvdigi.com\/diyaphp\/images\/lab.png","duration":"3 mins","updated_at":"0000-00-00 00:00:00","keywords":"law,white sheet,pen,pencil,mini bulbs,","materials":"pen,pencil,ball,worksheet","description":"about the law bla bla","subject":"science","target":"k2","created_at":"2015-08-14 14:24:54","pid":"1","rating":"4","procedure":"procedure about this project"},{"thumbimg":"http:\/\/spvdigi.com\/diyaphp\/images\/lab.png","duration":"3 mins","updated_at":"0000-00-00 00:00:00","keywords":"pen,pencil,color pencil,chart,sticks","materials":"pen,pencil,color pencil,chart,sticks,etc","description":"about description of the project","subject":"science","target":"k3","created_at":"2015-08-14 14:25:16",
"pid":"2","rating":"3","procedure":"about description of the procedure"},{"thumbimg":"http:\/\/spvdigi.com\/diyaphp\/images\/lab.png","duration":"5 mins","updated_at":"0000-00-00 00:00:00","keywords":"pen,pencil,wire,chart,sticks","materials":"pen,pencil,color pencil,chart,sticks,eraser","description":"about description of the project","subject":"english","target":"k4","created_at":"2015-08-14 14:25:21",
....
"pid":"8","rating":"3","procedure":"about description of the procedure"}]}
the above is the output of the jsonObject, the below is the correct result showing in emulator
{"projects":[{"pid":"1","target":"k2","subject":"science","description":"about the law bla bla","duration":"3 mins","materials":"pen,pencil,ball,worksheet","procedure":"procedure about this project","keywords":"law,white sheet,pen,pencil,mini bulbs,","thumbimg":"http:\/\/spvdigi.com\/diyaphp\/images\/lab.png","rating":"4","created_at":"2015-08-14 14:24:54","updated_at":"0000-00-00 00:00:00"},{"pid":"2","target":"k3","subject":"science","description":"about description of the project","duration":"3 mins","materials":"pen,pencil,color pencil,chart,sticks,etc","procedure":"about description of the procedure","keywords":"pen,pencil,color pencil,chart,sticks","thumbimg":"http:\/\/spvdigi.com\/diyaphp\/images\/lab.png","rating":"3","created_at":"2015-08-14 14:25:16","updated_at":"0000-00-00 00:00:00"},
...
{"pid":"8","target":"k3","subject":"english","description":"to learn english tenses","duration":"3 mins","materials":"white sheet,pen,pencil,eraser","procedure":"about description of the procedure","keywords":"english,grammer,tenses","thumbimg":"http:\/\/spvdigi.com\/diyaphp\/images\/lab.png","rating":"3","created_at":"2015-08-18 06:45:28","updated_at":"0000-00-00 00:00:00"}],"success":1}
this is my jsonparse class code:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
static String jboolean = "0";
static JSONArray jarr =null;
// constructor
public JSONParser() {
}
// function get json from url
// by making HTTP POST or GET mehtod
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 10000);
HttpConnectionParams.setSoTimeout(httpParameters, 10000 + 12000);
DefaultHttpClient httpClient = new DefaultHttpClient(new BasicHttpParams());
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-type","application/json");
httpPost.setParams(httpParameters);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
Log.e("Buffer 11", "Error converting result " + e.toString());
} catch (ClientProtocolException e) {
e.printStackTrace();
Log.e("Buffer 22", "Error converting result " + e.toString());
} catch (IOException e) {
e.printStackTrace();
Log.e("Buffer 33", "Error converting result " + e.toString());
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
//Log.e("JSON 1111 ", "parsing data " + json.toString());
} catch (Exception e) {
Log.e("Buffer Error????", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
Log.e("JSON 1111 ", "parsing data " + jObj.toString());
} catch (JSONException e) {
Log.e("JSON Parser44", "Error parsing data " + e.toString());
}
return jObj;
/// This JObj is not properly getting the json string???
// return JSON String
}
}
Is there any issues on the above code? i am facing a issue on getting JObject, my app is working in emulator and it is not working in device. because the string is not properly converting to JObject.
one of my junior code is not sending excel file as attachment . It is sending file like
------=_Part_0_2066339629.1374147892060
Content-Type: text/plain; name="Service_Change_Alert_Thu Jul 18 17:14:50 IST 2013.xlsx"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="Service_Change_Alert_Thu Jul 18 17:14:50 IST 2013.xlsx"
UEsDBBQACAAIANqJ8kIAAAAAAAAAAAAAAAARAAAAZG9jUHJvcHMvY29yZS54bWytkV1LwzAUhu/7
K0Lu2yTr1BHaDlEGguLADsW7kB7bYvNBEu3892bdrCheennyPu/D4aRY79WA3sH53ugSs4xiBFqa
ptdtiXf1Jl3hdZUkhTQOts5YcKEHj2JL+xJ3IVhOiJcdKOGzGOuYvBinRIija4kV8lW0QBaUnhMF
QTQiCHKwpXbW4aOPS/vvykbOSvvmhknQSAIDKNDBE5Yx8s0GcMr/WZiSmdz7fqbGcczGfOLiRow8
3d0+TMunvfZBaAm4ShAqTnYuHYgADYoOHj4slPgrecyvrusNrhaU5Sm9SNmqZowvl/yMPhfkV//k
function is following
public void sendSeviceabilityMail(List<OctpinSaveBean> datalist)
throws MessagingException {
Session session = null;
Map<String, String> utilsMap = ApplicationBean.utilsProperties;
if (utilsMap == null || utilsMap.size() == 0)
utilsMap = ApplicationBean.getUtilsPropertyFileValues();
smtpHost = utilsMap.get("SMTPHost");
to = utilsMap.get("To");
try {
if (smtpHost != null && to != null) {
Date date = new Date();
XSSFWorkbook updateDataBook =
updatedServiceabilityExcel(datalist);
Properties props = System.getProperties();
props.put("mail.smtp.host", smtpHost);
props.put("To", to);
session = Session.getInstance(props, null);
String str = "strstr";
Multipart multipart = new MimeMultipart();
BodyPart messageBodyPart1 = new MimeBodyPart();
messageBodyPart1.setContent(str, "text/html");
BodyPart messageBodyPart = new MimeBodyPart();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
updateDataBook.write(baos);
byte[] bytes = baos.toByteArray();
DataSource ds = new ByteArrayDataSource(bytes,
"application/vnd.ms-excel");
DataHandler dh = new DataHandler(ds);
messageBodyPart.setDataHandler(dh);
String fileName = "Service_Change_Alert_" + date+".xlsx";
messageBodyPart.setFileName(fileName);
messageBodyPart.setHeader("Content-disposition", "attachment;
filename=\"" + fileName + "\"");
multipart.addBodyPart(messageBodyPart1);
multipart.addBodyPart(messageBodyPart);
if (to != null && to.length() > 0) {
MimeMessage msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("tech_noida
<tech_noida#xyz.com>"));
String[] toArray = to.split(",");
InternetAddress[] address = new
InternetAddress[toArray.length];
for (int i = 0; i < toArray.length; i++) {
address[i] = new InternetAddress(toArray[i]);
}
msg.setRecipients(Message.RecipientType.TO, address);
msg.setSubject("Updated Serviceability Alert!!!");
msg.setContent(multipart);
msg.setSentDate(date);
try {
Transport.send(msg);
logger.info("Mail has been sent about the updated serviceability alert to :" + to);
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
The problem is not related to POI, but with JavaMail (plus the way different email clients handles the specs and malformed emails). Try this:
Multipart multipart = new MimeMultipart();
MimeBodyPart html = new MimeBodyPart();
// Use actual html not "strstr"
html.setContent("<html><body><h1>Hi</h1></body></html>", "text/html");
multipart.addBodyPart(html);
// ...
// Joop Eggen suggestion to avoid spaces in the file name
String fileName = "Service_Change_Alert_"
+ new SimpleDateFormat("yyyy-MM-dd_HH:mm").format(date) + ".xlsx";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
updateDataBook.write(baos);
byte[] poiBytes = baos.toByteArray();
// Can be followed by the DataSource / DataHandler stuff if you really need it
MimeBodyPart attachment = new MimeBodyPart();
attachment.setFileName(filename);
attachment.setContent(poiBytes, "application/vnd.ms-excel");
//attachment.setDataHandler(dh);
attachment.setDisposition(MimeBodyPart.ATTACHMENT);
multipart.addBodyPart(attachment);
Update:
Also don't forget to call saveChanges to update the headers before sending the message.
msg.saveChanges();
See this answer for further details.
I tried to connect to the Foursquare webservice to parse look for some locations, but my program couldn't connect with Foursquare webservice. Here is my code:
public class GetLocation
{
public static void main (String [] args ) throws IOException
{
//Set up for output locations in a .txt file
String fileNameOut = "locations.txt" ;
FileOutputStream fos = new FileOutputStream( fileNameOut );
PrintStream ps = new PrintStream(fos);
String client_id = "Y2LZCJTR4LJBXZOXAB3F22VOLAV3GXRS5TSXRXXXXXXXXXXX";
String client_secret = "PJY2QM4CLZITAUMGOQCM2QYTOKATTCH3VXXXXXXXXXXX";
double latitude = 33.823712;
double longtitude = -117.958931;
String restaurantName = "Cafe Casse Croute";
String V = "20121205";
String API_URL = "http://api.foursquare.com/v2/venues/search?ll=";
String queryStatement = latitude+","+longtitude+"&match="+restaurantName;
try {
String url = (API_URL+queryStatement+"&client_id="+client_id+"&client_secret="+client_secret + "&v="+V);
URL url = new URL(sURL);
URLConnection httpc = url.openConnection();
//HttpURLConnection httpc = (HttpURLConnection) url.openConnection();
httpc.setDoInput(true);
httpc.connect();
BufferedReader in = new BufferedReader(new InputStreamReader(httpc.getInputStream()));
String inputLine = "";
String content="";
while ((inputLine = in.readLine()) != null){
content=content+inputLine;
}
in.close();
return content;
} catch (Exception e) {
return ("Exception: " + e.getMessage());
}
}
}
I also try to use URLConnection httpc = (URLConnection) url.openConnection();
but it does not connect to the FoureSquare Service.
Is there other way to connect to the FoureSquare Service ?