Devices are not registered in azure push notification hub in xamarin forms - azure

I am trying to register device token with tag in azure push notification hub in development mode but in azure portal it shows 0 active devices registered, when I check with notification hub it will show one registration is occur.
Here is my sample code:
App delegate:
var deviceTokenDes = deviceToken.Description;
if (!string.IsNullOrWhiteSpace(deviceTokenDes))
{
deviceTokenDes = deviceTokenDes.Trim('<');
deviceTokenDes = deviceTokenDes.Trim('>');
deviceTokenDes = deviceTokenDes.Replace(" ", "");
DeviceToken = deviceTokenDes.Trim('<');
DeviceToken = deviceTokenDes.Trim('>');
DeviceToken = deviceTokenDes.Replace(" ", "");
}
Hub = new SBNotificationHub(myapp.ListenConnectionString, myapp.NotificationHubName);
Login view model:
var tags = new List<string> { userId };
AppDelegate.Hub?.UnregisterAllAsync(AppDelegate.DeviceToken, error =>
{
if (error != null)
{
Console.WriteLine("Error calling Unregister: {0}", error);
}
AppDelegate.Hub.RegisterNativeAsync(AppDelegate.DeviceToken, new NSSet(tags.ToArray()), errorCallback =>
{
if (errorCallback != null)
{
Console.WriteLine("RegisterNativeAsync error: " + errorCallback.ToString());
}
});
I have registered device token with tag after user successfully login in to the application. Can you please suggest idea on.

This is all we do in our AppDelegate class.
public override async void RegisteredForRemoteNotifications(UIApplication application, NSData deviceToken)
{
bool ShouldComplete = true;
// Validate if we have already got a registration
try
{
string validation = NSUserDefaults.StandardUserDefaults.StringForKey("InitialTagRegistration");
if (validation.Contains("Completed"))
{
ShouldComplete = false;
}
}
catch (Exception genEx)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[EXCEPTION] - Exception has been hit! - Message: " + genEx.Message + " | Source: " + genEx);
}
Hub = new SBNotificationHub(ConfigurableSettings.NotificationHubConnectionString, ConfigurableSettings.NotificationHubPathName);
ApplicationState.SetValue("NotificationHub", Hub);
// Get previous device token
NSData oldDeviceToken = await ApplicationSettings.RetrieveDeviceToken();
// If the token has changed unregister the old token and save the new token to UserDefaults.
if (oldDeviceToken != null)
{
if (oldDeviceToken.ToString() != deviceToken.ToString())
{
try
{
Hub.UnregisterAllAsync(oldDeviceToken, (error) =>
{
//check for errors in unregistration process.
if (error != null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + error + " | Source: " + "Unregistering old device token against the notification hub.");
//exit out of the code here because we can't keep our hub clean without being able to remove the device from our registration list.
return;
}
else
{
ShouldComplete = true;
}
});
}
catch (Exception genEx)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + genEx.Message + " | Source: " + genEx + Environment.NewLine + Environment.NewLine);
}
}
}
else
{
// Store current device token
bool res = await ApplicationSettings.CacheDeviceToken(deviceToken);
}
// Check if we need to perform our initial registrations
if (ShouldComplete)
{
NSSet RegisteredTags = await ApplicationSettings.RetrieveUserTags();
if (RegisteredTags == null)
{
RegisteredTags = new NSSet("AppleDevice");
}
//Register the device against the notification hub keeping the details accurate at all times.
Hub.RegisterNativeAsync(deviceToken, RegisteredTags, (errorCallback) =>
{
if (errorCallback != null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + errorCallback + " | Source: " + "Registering device token against the notification hub.");
}
else
{
if (deviceToken != null)
{
NSUserDefaults.StandardUserDefaults.SetString("Completed", "InitialTagRegistration");
NSUserDefaults.StandardUserDefaults.Synchronize();
}
}
});
}
}
The long and short of it is that you don't need to do anything to the device token before passing it up to the azure notification hub. That's what solved the problem for us, ours has been running in an active application for months now without any issues. Hope this helps.
EDIT: in order to update the tags when a user logs in, we store the device token for use later on, and when the user logs in we use the following method in a seperate class to facilitate updating the tags:
public static async Task<bool> UpdateTags(StaffProfile user)
{
//Get the instance of the Notification hub
SBNotificationHub UpdateHub = new SBNotificationHub(ConfigurableSettings.NotificationHubConnectionString, ConfigurableSettings.NotificationHubPathName);
//Grab the current device token that was stored during the start up process.
NSData CurrentDeviceToken = await ApplicationSettings.RetrieveDeviceToken();
//Get and create the tags we want to use.
string EmailTag = string.Empty;
string StoreTag = string.Empty;
string OrganisationTag = "AppleDevice:OrgTag";
string GenericTag = "AppleDevice:StaffTag";
if (!string.IsNullOrWhiteSpace(user.Email))
{
EmailTag = user.Email;
//Remove unwanted spaces and symbols.
EmailTag = EmailTag.Replace(" ", "");
EmailTag = string.Format("AppleDevice:{0}", EmailTag);
}
if (!string.IsNullOrWhiteSpace(user.Store?.Name))
{
StoreTag = user.Store.Name;
//Remove unwanted space.
StoreTag = StoreTag.Replace(" ", "");
StoreTag = string.Format("AppleDevice:{0}", StoreTag);
}
//Create array of strings to the currently fixed size of 3 items.
NSString[] TagArray = new NSString[4];
//Only add in the tags that contain data.
if (!string.IsNullOrEmpty(EmailTag)) { TagArray[0] = (NSString)EmailTag; }
if (!string.IsNullOrEmpty(StoreTag)) { TagArray[1] = (NSString)StoreTag; }
if (!string.IsNullOrEmpty(OrganisationTag)) { TagArray[2] = (NSString)OrganisationTag; }
if (!string.IsNullOrEmpty(GenericTag)) { TagArray[3] = (NSString)GenericTag; }
NSSet tags = new NSSet(TagArray);
// Store our tags into settings
ApplicationSettings.CacheUserTags(tags);
try
{
if (CurrentDeviceToken == null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: Device token is empty." + Environment.NewLine + Environment.NewLine);
}
else
{
UpdateHub.RegisterNativeAsync(CurrentDeviceToken, tags, (error) =>
{
//check for errors in unregistration process.
if (error != null)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + error + " | Source: " + "Registering against hub with new tags." + Environment.NewLine + Environment.NewLine);
// Lets do this so that we can force the initial registration to take place again.
NSUserDefaults.StandardUserDefaults.SetString("Failed", "InitialTagRegistration");
NSUserDefaults.StandardUserDefaults.Synchronize();
}
else
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[INFORMATION] - Message: Successful Registration - Source: Registering against hub with new tags." + Environment.NewLine + Environment.NewLine);
}
});
}
}
catch (Exception genEx)
{
ApplicationLog.AppendFile(DateTime.Now.ToString() + " : " + "[PNS EXCEPTION] - Exception has been hit! - Message: " + genEx.Message + " | Source: " + genEx + Environment.NewLine + Environment.NewLine);
}
return await Task.FromResult(true);
}

I have tried with fallowing code but i didn't receive any notification. At first time when i send test notification in azure notification hub it will shows one success but didn't receive notification, after second time onward it shows 0 passed and 0 failed.
According to your description, I would recommend you could communicate with APNs directly to check whether you could get the error response to narrow this issue. Here are some useful tutorials, you could refer to them and troubleshoot your issue as follows:
Official documentation:Communicating with APNs
Knuff, a debug application for Apple Push Notification Service (APNs)
PushSharp, a server-side library for sending notification to iOS/OSX (APNS), Android/Chrome (GCM), Windows/Windows Phone, Amazon (ADM) and Blackberry devices. For how to configure and send Apple Push Notifications, you could refer to here.

Related

Workflow C# string function error in Docusign

I have an code issue in docusign.
In my calculation step I have created and input and output code.
When I run the template and checking the "incoming data" xml in the workflow I have an error message displayed:
<In_80_stackTrace>Exception: at ADEXS.DynamicCode.DynamicClassD_3447d8ccd49f4631b91c31df53e249e7.DynamicMethodD_dcb572b7876d400683579290c5918f06(DynamicContext _context)</In_80_stackTrace>
I don't know how to fix this that it will show only the
logError("In_80_error", "Data node //CategoryName is missing");
when no data is in the node.
Below are the details - my input code:
//In_80 - ESP_CategoryName_Description
string In_80 = "";
{
try
{
if (incomingDataRoot.SelectSingleNode("//CategoryName[node()]").InnerText == null)
{
logError("In_80_error", "Data node //CategoryName is missing");
}
else if (incomingDataRoot.SelectSingleNode("//CategoryName[node()]").InnerText != null)
{
In_80 = incomingDataRoot.SelectSingleNode("//CategoryName[node()]").InnerText;
}
}
catch (Exception e)
{
//logError("In_80_error", "Exception: Message:" + e.Message +" Inner Exception: "+ e.InnerException +" StackTrace: "+ e.StackTrace +" Source: "+ e.Source +" Data: "+ e.Data);
logError("In_80_stackTrace", "Exception: " + e.StackTrace);
}
}
Here is the output code:
//OUT_92 - ESP_CategoryName_Description
var OUT_92 = In_80;
if (In_80 == "")
{
logError("OUT_92_error", "Error reading In_80");
} else {
XmlElement elem = incomingDataRoot.OwnerDocument.CreateElement("OUT_92");
string p_category = "";
int i = 1;
foreach (char item in In_80)
{
if (Char.IsLetter(item))
{
if (i == 1)
{
p_category += item.ToString().ToUpper();
}
else
{
p_category += item.ToString().ToLower();
}
i++;
}
else
{
if (item == ' ')
{
i = 1;
}
p_category += item.ToString();
}
}
OUT_92 = p_category;
elem.InnerText = OUT_92.ToString();
elem.SetAttribute("Name", "ESP_CategoryName_Description");
incomingDataRoot.SelectSingleNode("/Root/Params/TemplateFieldData/Calculation_Results").AppendChild(elem);
}
In incoming data OUT part I'm getting
<OUT_92_error>Error reading In_80</OUT_92_error>
where I assume that its because something is wrong with the input code part?
Thank you for your help!

The remote server returned an error: (401) Unauthorized - CSOM - OAuth - after specific time

I am trying to get permissions assigned to each document from the document library using csom in console application. Console app is running fine for almost one hour and post that I get error : "The remote server returned an error: (401) Unauthorized."
I registered an app in SharePoint and I'm using Client ID & Client Secret Key to generate Client Context. Here is the code to get the client context
public static ClientContext getClientContext()
{
ClientContext ctx = null;
try
{
ctx = new AuthenticationManager().GetAppOnlyAuthenticatedContext(SiteUrl, ClientId, ClientSecret);
ctx.RequestTimeout = 6000000;
ctx.ExecutingWebRequest += delegate (object sender, WebRequestEventArgs e)
{
e.WebRequestExecutor.WebRequest.UserAgent = "NONISV|Contoso|GovernanceCheck/1.0";
};
}
catch (Exception ex)
{
WriteLog("Method-getClientContext, Error - " + ex.Message);
}
return ctx;
}
Here is the code which is getting all the assignments assigned to document in document library.
static StringBuilder excelData = new StringBuilder();
static void ProcessWebnLists()
{
try
{
string[] lists = { "ABC", "XYZ", "DEF", "GHI"};
foreach (string strList in lists)
{
using (var ctx = getClientContext())
{
if (ctx != null)
{
Web web = ctx.Site.RootWeb;
ListCollection listCollection = web.Lists;
ctx.Load(web);
ctx.Load(listCollection);
ctx.ExecuteQuery();
List list = web.Lists.GetByTitle(strList);
ctx.Load(list);
ctx.ExecuteQuery();
Console.WriteLine("List Name:{0}", list.Title);
var query = new CamlQuery { ViewXml = "<View/>" };
var items = list.GetItems(query);
ctx.Load(items);
ctx.ExecuteQuery();
foreach (var item in items)
{
var itemAssignments = item.RoleAssignments;
ctx.Load(item, i => i.DisplayName);
ctx.Load(itemAssignments);
ctx.ExecuteQuery();
Console.WriteLine(item.DisplayName);
string groupNames = "";
foreach (var assignment in itemAssignments)
{
try
{
ctx.Load(assignment.Member);
ctx.ExecuteQuery();
groupNames += "[" + assignment.Member.Title.Replace(",", " ") + "] ";
Console.WriteLine($"--> {assignment.Member.Title}");
}
catch (Exception e)
{
WriteLog("Method-ProcessWebnLists, List-" + list.Title + ", Document Title - " + item.DisplayName + ", Error : " + e.Message);
WriteLog("Method-ProcessWebnLists, StackTrace : " + e.StackTrace);
}
}
excelData.AppendFormat("{0},{1},ITEM,{2}", list.Title, (item.DisplayName).Replace(",", " "), groupNames);
excelData.AppendLine();
}
}
excelData.AppendLine();
}
}
}
catch (Exception ex)
{
WriteLog("Method-ProcessWebnLists, Error : " + ex.Message);
WriteLog("Method-ProcessWebnLists, StackTrace : " + ex.StackTrace.ToString());
}
}
Can anyone suggest what else I am missing in this or what kind of changes do I need to make to avoid this error?
The process is taking too much time so I want my application to keep running for couple of hours.
Thanks in advance!
Is there a reason why getClientContext() is inside the foreach loop?
I encountered this error before.
I added this to solve mine.
public static void ExecuteQueryWithIncrementalRetry(this ClientContext context, int retryCount, int delay)
{
int retryAttempts = 0;
int backoffInterval = delay;
if (retryCount <= 0)
throw new ArgumentException("Provide a retry count greater than zero.");
if (delay <= 0)
throw new ArgumentException("Provide a delay greater than zero.");
while (retryAttempts < retryCount)
{
try
{
context.ExecuteQuery();
return;
}
catch (WebException wex)
{
var response = wex.Response as HttpWebResponse;
if (response != null && response.StatusCode == (HttpStatusCode)429)
{
Console.WriteLine(string.Format("CSOM request exceeded usage limits. Sleeping for {0} seconds before retrying.", backoffInterval));
//Add delay.
System.Threading.Thread.Sleep(backoffInterval);
//Add to retry count and increase delay.
retryAttempts++;
backoffInterval = backoffInterval * 2;
}
else
{
throw;
}
}
}
throw new MaximumRetryAttemptedException(string.Format("Maximum retry attempts {0}, have been attempted.", retryCount));
}
Basically, this code backs off for a certain time/interval before executing another query, to prevent throttling.
So instead of using ctx.ExecuteQuery(), use ctx.ExecuteQueryWithIncrementalRetry(5, 1000);
Further explanation here
https://learn.microsoft.com/en-us/sharepoint/dev/general-development/how-to-avoid-getting-throttled-or-blocked-in-sharepoint-online

Azure - 403 error - Copying a large number of storage account blobs to another storage account on pay-as-you-go acct

I am getting a
403 Forbidden
error when copying a large number of block blobs from one storage account to another storage account (in a different region as a backup). After 100,000+ are copied I get a 403 Forbidden error.
I have seen answers talking about a Quota but I believe that is for free accounts. I have a client with a 578,000 files that I moved to Azure from local and that worked fine but I cannot make a copy to another storage account I set up to act as a backup (in case of deletions mostly).
I am using StartCopyAsync and then checking the Copystate status to verify the copy succeeded and retrying in my code but it appears to be failing on the StartCopyAsync.
The copy works fine until I have copied well over 100,000 of the files, then the error occurs. I am not sure what is causing that since the same code works fine for so many blobs first. I have added a log file that told me which file it failed on and I can open that file in Azure explorer.
I can post the code but right now, I am wondering if I am hitting some sort of quote/bandwidth issue I do not know about.
namespace BackupCloudContainers
{
class Program
{
static string privateconnectionstring = ConfigurationManager.AppSettings["StorageConnectionString"];
static string privatebackupconnectionstring = ConfigurationManager.AppSettings["BackupStorageConnectionString"];
static DateTime testdate = new DateTime(2017, 8, 28, 0, 0, 0);
static string destContainerName = "";
static void Main(string[] args)
{
try
{
//Console.WriteLine("Starting Backup at " + DateTime.Now.ToString("hh:mm:ss.ffff"));
Log("Starting Incremental Backup (everything since " + testdate.ToString("f") + ") at " + DateTime.Now.ToString("hh:mm:ss.ffff"));
Backup().GetAwaiter().GetResult();
// Console.WriteLine("Backup Created as " + destContainerName);
Log("Backup Created as " + destContainerName);
//Console.WriteLine("Backup ended at " + DateTime.Now.ToString("hh:mm:ss.ffff"));
Log("Backup ended at " + DateTime.Now.ToString("hh:mm:ss.ffff"));
Console.WriteLine("\n\nPress Enter to close. ");
Console.ReadLine();
}
catch (Exception e)
{
//Console.WriteLine("Exception - " + e.Message);
Log("Exception - " + e.Message);
if (e.InnerException != null)
{
//Console.WriteLine("Inner Exception - " + e.InnerException.Message);
Log("Inner Exception - " + e.InnerException.Message);
}
}
}
static async Task Backup()
{
CloudStorageAccount _storageAccount = CloudStorageAccount.Parse(privateconnectionstring);
CloudStorageAccount _storageBackupAccount = CloudStorageAccount.Parse(privatebackupconnectionstring);
CloudBlobClient blobClient = _storageAccount.CreateCloudBlobClient();
CloudBlobClient blobBackupClient = _storageBackupAccount.CreateCloudBlobClient();
foreach (var srcContainer in blobClient.ListContainers())
{
// skip any containers with a backup name
if (srcContainer.Name.IndexOf("-backup-") > -1)
{
continue;
}
var backupTimeInTicks = DateTime.UtcNow.Ticks;
//var destContainerName = srcContainer.Name + "-" + backupTimeInTicks;
var backupDateTime = DateTime.UtcNow.ToString("yyyyMMdd-hhmmssfff");
destContainerName = srcContainer.Name + "-backup-" + backupDateTime;
var destContainer = blobBackupClient.GetContainerReference(destContainerName);
// var destContainer = blobClient.GetContainerReference(destContainerName);
// assume it does not exist already,
// as that wouldn't make sense.
await destContainer.CreateAsync();
// ensure that the container is not accessible
// to the outside world,
// as we want all the backups to be internal.
BlobContainerPermissions destContainerPermissions = destContainer.GetPermissions();
if (destContainerPermissions.PublicAccess != BlobContainerPublicAccessType.Off)
{
destContainerPermissions.PublicAccess = BlobContainerPublicAccessType.Off;
await destContainer.SetPermissionsAsync(destContainerPermissions);
}
// copy src container to dest container,
// note that this is synchronous operation in reality,
// as I want to only add real metadata to container
// once all the blobs have been copied successfully.
await CopyContainers(srcContainer, destContainer);
await EnsureCopySucceeded(destContainer);
// ensure we have some metadata for the container
// as this will helps us to delete older containers
// on a later date.
await destContainer.FetchAttributesAsync();
var destContainerMetadata = destContainer.Metadata;
if (!destContainerMetadata.ContainsKey("BackupOf"))
{
string cname = srcContainer.Name.ToLowerInvariant();
destContainerMetadata.Add("BackupOf", cname);
destContainerMetadata.Add("CreatedAt", backupTimeInTicks.ToString());
destContainerMetadata.Add("CreatedDate", backupDateTime);
await destContainer.SetMetadataAsync();
//destContainer.SetMetadata();
}
}
// let's purge the older containers,
// if we already have multiple newer backups of them.
// why keep them around.
// just asking for trouble.
//var blobGroupedContainers = blobBackupClient.ListContainers()
// .Where(container => container.Metadata.ContainsKey("Backup-Of"))
// .Select(container => new
// {
// Container = container,
// BackupOf = container.Metadata["Backup-Of"],
// CreatedAt = new DateTime(long.Parse(container.Metadata["Created-At"]))
// }).GroupBy(arg => arg.BackupOf);
var blobGroupedContainers = blobClient.ListContainers()
.Where(container => container.Metadata.ContainsKey("BackupOf"))
.Select(container => new
{
Container = container,
BackupOf = container.Metadata["BackupOf"],
CreatedAt = new DateTime(long.Parse(container.Metadata["CreatedAt"]))
}).GroupBy(arg => arg.BackupOf);
// Remove the Delete for now
// foreach (var blobGroupedContainer in blobGroupedContainers)
// {
// var containersToDelete = blobGroupedContainer.Select(arg => new
// {
// Container = arg.Container,
// CreatedAt = new DateTime(arg.CreatedAt.Year, arg.CreatedAt.Month, arg.CreatedAt.Day)
// })
// .GroupBy(arg => arg.CreatedAt)
// .OrderByDescending(grouping => grouping.Key)
// .Skip(7) /* skip last 7 days worth of data */
// .SelectMany(grouping => grouping)
// .Select(arg => arg.Container);
//// Remove the Delete for now
// //foreach (var containerToDelete in containersToDelete)
// //{
// // await containerToDelete.DeleteIfExistsAsync();
// //}
// }
}
static async Task EnsureCopySucceeded(CloudBlobContainer destContainer)
{
bool pendingCopy = true;
var retryCountLookup = new Dictionary<string, int>();
while (pendingCopy)
{
pendingCopy = false;
var destBlobList = destContainer.ListBlobs(null, true, BlobListingDetails.Copy);
foreach (var dest in destBlobList)
{
var destBlob = dest as CloudBlob;
if (destBlob == null)
{
continue;
}
var blobIdentifier = destBlob.Name;
if (destBlob.CopyState.Status == CopyStatus.Aborted ||
destBlob.CopyState.Status == CopyStatus.Failed)
{
int retryCount;
if (retryCountLookup.TryGetValue(blobIdentifier, out retryCount))
{
if (retryCount > 4)
{
throw new Exception("[CRITICAL] Failed to copy '"
+ destBlob.CopyState.Source.AbsolutePath + "' to '"
+ destBlob.StorageUri + "' due to reason of: " +
destBlob.CopyState.StatusDescription);
}
retryCountLookup[blobIdentifier] = retryCount + 1;
}
else
{
retryCountLookup[blobIdentifier] = 1;
}
pendingCopy = true;
// restart the copy process for src and dest blobs.
// note we also have retry count protection,
// so if any of the blobs fail too much,
// we'll give up.
await destBlob.StartCopyAsync(destBlob.CopyState.Source);
}
else if (destBlob.CopyState.Status == CopyStatus.Pending)
{
pendingCopy = true;
}
}
Thread.Sleep(1000);
}
}
static async Task CopyContainers(
CloudBlobContainer srcContainer,
CloudBlobContainer destContainer)
{
// get the SAS token to use for all blobs
string blobToken = srcContainer.GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessStartTime = DateTime.Now.AddMinutes(-5),
SharedAccessExpiryTime = DateTime.Now.AddHours(3)
});
int ii = 0;
int cntr = 0;
int waitcntr = 0;
string sourceuri = "";
int datecntr = 0;
try
{
//Console.WriteLine(" container contains " + srcContainer.ListBlobs(null, true).Count().ToString());
Log(" container contains " + srcContainer.ListBlobs(null, true).Count().ToString());
foreach (var srcBlob in srcContainer.ListBlobs(null, true))
{
ii++;
//THIS IS FOR COUNTING Blobs that would be on the Incremental Backup
CloudBlob blob = (CloudBlob)srcBlob;
if (blob.Properties.LastModified > testdate)
{
datecntr++;
}
else
{
// We are only doing an Incremental Backup this time - so skip all other files
continue;
}
//if (ii > 2000)
//{
// //Console.WriteLine(" test run ended ");
// Log(" test run ended ");
// break;
//}
cntr++;
if (cntr > 999)
{
//Console.WriteLine(" " + ii.ToString() + " processed at " + DateTime.Now.ToString("hh:mm:ss"));
Log(" " + ii.ToString() + " processed at " + DateTime.Now.ToString("hh:mm:ss"));
//Log(" EnsureCopySucceeded - finished at " + DateTime.Now.ToString("hh:mm:ss"));
//await EnsureCopySucceeded(destContainer);
//Log(" EnsureCopySucceeded - finished at " + DateTime.Now.ToString("hh:mm:ss"));
cntr = 0;
}
waitcntr++;
if (waitcntr > 29999)
{
Log(" EnsureCopySucceeded (ii=" + ii.ToString() + "- started at " + DateTime.Now.ToString("hh:mm:ss"));
await EnsureCopySucceeded(destContainer);
Log(" EnsureCopySucceeded - finished at " + DateTime.Now.ToString("hh:mm:ss"));
waitcntr = 0;
}
var srcCloudBlob = srcBlob as CloudBlob;
if (srcCloudBlob == null)
{
continue;
}
CloudBlob destCloudBlob;
if (srcCloudBlob.Properties.BlobType == BlobType.BlockBlob)
{
destCloudBlob = destContainer.GetBlockBlobReference(srcCloudBlob.Name);
}
else
{
destCloudBlob = destContainer.GetPageBlobReference(srcCloudBlob.Name);
}
sourceuri = srcCloudBlob.Uri.AbsoluteUri + blobToken;
try
{
await destCloudBlob.StartCopyAsync(new Uri(srcCloudBlob.Uri.AbsoluteUri + blobToken));
}
catch (Exception e)
{
Log("Error at item " + ii.ToString() + " Source = " + sourceuri + " Message = " + e.Message + " Time = " + DateTime.Now.ToString("F") + "\r\n");
}
}
Log("Total Items checked = " + ii.ToString() + " backed up files = " + datecntr.ToString());
Log("TestDate = " + testdate.ToString("F") + " datecntr = " + datecntr.ToString());
}
catch (Exception e)
{
Log("Error at item " + ii.ToString());
Log(" Source = " + sourceuri);
Log(" Message = " + e.Message);
Log(" Time = " + DateTime.Now.ToString("F") + "\r\n");
//throw e;
}
}
static void Log(string logdata)
{
Console.WriteLine(logdata);
File.AppendAllText("c:\\junk\\dwlog.txt", logdata + "\r\n");
}
}
}
You mentioned that your code starts to fail after 3 hours. Well, the following lines of code are culprit for that:
string blobToken = srcContainer.GetSharedAccessSignature(new SharedAccessBlobPolicy()
{
Permissions = SharedAccessBlobPermissions.Read,
SharedAccessStartTime = DateTime.Now.AddMinutes(-5),
SharedAccessExpiryTime = DateTime.Now.AddHours(3)
});
If you notice, you are creating a shared access signature (SAS) that is valid for a duration of 3 hours and you're using this SAS for all blobs. Your code works as long as SAS is valid i.e. has not expired. Once the SAS expires, because now the SAS token is not authorized to perform the operation, you start getting 403 (Not Authorized) error.
My recommendation would be to create a SAS token that is valid for a longer duration. I would recommend a SAS token valid for 15 days because that's the maximum amount of time Azure Storage will try to copy your blob from one account to another.

Why am I unable to list all my accounts with this code?

This is my first foray into Google Analytics. I created a service account and downloaded the p12 file from the developer console.
This code works, but in an incomplete way.
I have two accounts, but the code below just returns one account from the list.
How do I get all my accounts listed?
private static ServiceAccountCredential Run2()
{
const string keyfilePath = "file.p12";
const string serviceAccountMail = "notarealemailaddress#developer.gserviceaccount.com";
var certificate = new X509Certificate2(keyfilePath, "notasecret", X509KeyStorageFlags.Exportable);
var credential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(serviceAccountMail)
{
Scopes = new[] { AnalyticsService.Scope.Analytics, AnalyticsService.Scope.AnalyticsReadonly, AnalyticsService.Scope.AnalyticsProvision }
}.FromCertificate(certificate));
return credential;
}
static void Main()
{
var cr = Run2();
var service = new AnalyticsService(new BaseClientService.Initializer()
{
HttpClientInitializer = cr,
ApplicationName = "Analytics API Sample"
});
var request = service.Management.Accounts.List();
request.MaxResults = 20;
var result = request.Execute();
foreach (var item in result.Items)
{
Console.WriteLine("Account Name: {0} {1} {2}", item.Name, item.Kind, item.Id);
}
}
This is what I ended up doing. The service account that Google creates needs to be added to every account that you need to access. I figured this from reading the documentation.
https://developers.google.com/analytics/devguides/config/mgmt/v3/quickstart/service-py
Try this out
ManagementResource.AccountSummariesResource.ListRequest list = service.Management.AccountSummaries.List();
list.MaxResults = 1000; // Maximum number of Account Summaries to return per request.
AccountSummaries feed = list.Execute();
List allRows = new List();
//// Loop through until we arrive at an empty page
while (feed.Items != null)
{
allRows.AddRange(feed.Items);
// We will know we are on the last page when the next page token is
// null.
// If this is the case, break.
if (feed.NextLink == null)
{
break;
}
// Prepare the next page of results
list.StartIndex = feed.StartIndex + list.MaxResults;
// Execute and process the next page request
feed = list.Execute();
}
feed.Items = allRows;
//Get account summary and display them.
foreach (AccountSummary account in feed.Items)
{
// Account
Console.WriteLine("Account: " + account.Name + "(" + account.Id + ")");
foreach (WebPropertySummary wp in account.WebProperties)
{
// Web Properties within that account
Console.WriteLine("\tWeb Property: " + wp.Name + "(" + wp.Id + ")");
//Don't forget to check its not null. Believe it or not it could be.
if (wp.Profiles != null)
{
foreach (ProfileSummary profile in wp.Profiles)
{
// Profiles with in that web property.
Console.WriteLine("\t\tProfile: " + profile.Name + "(" + profile.Id + ")");
}
}
}
}
Reference: http://www.daimto.com/googleanalytics-management-csharp/
http://www.daimto.com/googleAnalytics-authentication-csharp/

not able to read J2ME PIM contact details

I want to read contact details like firstname , lastname, mobile no, telephone , fax, address, synchronization and UID details using PIM apis in Nokia S60 sdk.
But , I am getting only Contact.TEL and Contact.EMAIL value, none of the other values I am getting , although, I am able to see other fields like first name, last name in the emulator contact details.
I have configures all the required permission .
ContactList addressbook = (ContactList) (PIM.getInstance().openPIMList(
PIM.CONTACT_LIST, PIM.READ_ONLY));
Contact contact = null;
Enumeration items = addressbook.items();
while (items.hasMoreElements()) {
String name = "";
String telephone = "";
String mobile = "";
String email = "";
String InternetTelephone = "";
String Company = "";
String JobTitle = "";
String Synchronisation = "";
String UID = "";
String LastModified = "";
String contactRow = "";
System.out.println("\n *** NEW ITEM ***");
contact = (Contact) (items.nextElement());
System.out.println(" * contact : " + contact.toString());
try {
name = contact.getString(Contact.FORMATTED_NAME, 0);
System.out.println("Name = " + name);
} catch (Exception ex) {
System.out.println(" Name error "+ ex.getMessage());
}
try {
mobile = contact.getString(Contact.ATTR_MOBILE, 0);
System.out.println("Name = " + name);
} catch (Exception ex) {
System.out.println(" Name error "+ ex.getMessage());
}
try
{ telephone = contact.getString(Contact.TEL, 0);
System.out.println("Telephone = " + contact.getString(115, 0)); //field 115: Telephone
} catch (Exception ex) {
System.out.println(" Telephone error "+ ex.getMessage());
}
try
{
email = contact.getString(Contact.EMAIL, 0);
System.out.println("E-mail = " + contact.getString(103, 0));
} catch (Exception ex) {
System.out.println(" E-mail error "+ ex.getMessage());
}
try
{
UID = contact.getString(Contact.UID, 0);
System.out.println(" UID " + UID );
} catch (Exception ex) {
System.out.println(" UID error "+ ex.getMessage());
}
try
{
LastModified = contact.getString(114, 0);
System.out.println(" Last modified " + contact.getString(114, 0));
} catch (Exception ex) {
System.out.println(" Last modified error "+ ex.getMessage());
}
looking forward your valuable suggestions.
Thanks in advance.
some sapmles from Nokia .... !
http://www.developer.nokia.com/Community/Wiki/How_to_read_contacts_using_JSR_75

Resources