Different results when making a Corda query via API and inside a flow - blockchain

I’m getting some strange behaviour. When I update a state with a list of partner ids - other nodes - and and read the state afterwards it seems that via rpcOps.vaultQueryBy I can see the updated - or unconsumed - state with the updated list of partners, but if I do same query via serviceHub.vaultService.queryBy it looks like the state’s parner list hasn’t changed at all.
If I get all states in the flow - also the consumed - it looks like there has not been a change, but via API all updates into partners list are visible. Is this some sort of a bug I have encountered or am I just not understanding something?
We're using Corda 4.0.
Via API
var servicestates = rpcOps.vaultQueryBy<ServiceState>().states.map { it.state.data }
var services = getServices().filter {
it.linearId == UniqueIdentifier.fromString(serviceId)
}.single()
Inside flow
val serviceStateAndRef = serviceHub.vaultService.queryBy<ServiceState>(
QueryCriteria.LinearStateQueryCriteria(linearId = listOf(serviceLinearId))
).states.single()

#Ashutosh Meher You got it near enough. The problem was in a previous flow, where, when creating a new partner state the command call for contract, there was only the caller listed.
So
Command(ServiceContract.Commands.AddPartner(),listOf(ourIdentity.owningKey))
had to be edited to include necessary other parties.
Command(ServiceContract.Commands.AddPartner(),updatedServiceState.participants.map { it.owningKey })
That resulted the other node not to see the change. It was right under my eyes all the time... ;)

Related

How to get all goals triggered during Sitecore session in commitDataSet Analytics pipeline?

I have an Analytics pipeline added just before the standard one in section to delete duplicate triggered pageevents before submitting all to database so I can have unique triggered events as there seems to be a bug on android/ios devices that triggers several events within few seconds interval.
In this custom pipeline I need to get the list of all goals/events the current user triggered in his session so I can compare with the values in dataset obtained from args parameter and delete the ones already triggered.
The args.DataSet.Tables["PageEvents"] only returns the set to be submitted to database and that doesn't help since it is changing each time this pipeline runs. I also tried Sitecore.Analytics.Tracker.Visitor.DataSet but I get a null value for these properties.
Does anyone knows a way how to get a list with all goals the user triggered so far in his session without requesting it directly to the database ?
Some code:
public class CommitUniqueAnalytics : CommitDataSetProcessor
{
public override void Process(CommitDataSetArgs args)
{
Assert.ArgumentNotNull(args, "args");
var table = args.DataSet.Tables["PageEvents"];
if (table != null)
{
//Sitecore.Analytics.Tracker.Visitor.DataSet.PageEvents - this list always empty
...........
}
}
}
I had a similar question.
In Sitecore 7.5 I found that this worked:
Tracker.Current.Session.Interaction.Pages.SelectMany(x=>x.PageEvents)
However I'm a little worried that this will be inefficient if the Pages collection is very large.

Sitecore 7 Analytics increase engagement value programatically

I am working on implementing sitecore DMS in 7.2 and I'm having one main issue for which I seem to be having a hard time finding an answer. I have some goals and events set up and I am attempting to set one off through the Analytics API. The event is being logged as being set off in the PageEventId database, but what I am trying to do is add Engagement Value to the current visit/visitor.
I'm looking to update the Value field in the Visits database for the current visit. Here is what I am currently using:
public static void triggerGoal(ID goal)
{
if (Tracker.IsActive && Tracker.CurrentPage != null)
{
Sitecore.Data.Items.Item goalToTrigger = Sitecore.Context.Database.GetItem(goal);
if (goalToTrigger != null)
{
Sitecore.Analytics.Data.Items.PageEventItem reg = new Sitecore.Analytics.Data.Items.PageEventItem(goalToTrigger);
Sitecore.Analytics.Data.DataAccess.DataSets.VisitorDataSet.PageEventsRow eventData =
Tracker.CurrentPage.Register(reg);
eventData.Data = goalToTrigger["Description"];
Tracker.Submit();
}
}
}
This updates the PageEventId database properly, noting that the event has been triggered, but this adds no Engagement Value to the Visits database, regardless of how many engagement points are assigned to the Goad that is being triggered.
I've tried various ways of getting the API to update this field, but nothing has worked for me so far. Here are a bunch of the different things I've tried:
Tracker.CurrentVisit.BeginEdit();
Tracker.CurrentVisit.Value += 3; //look up value here instead of hardcoding. Create new PageEventItem class to get field ID.
Tracker.CurrentVisit.AcceptChanges();
Tracker.CurrentVisit.EndEdit();
Tracker.CurrentVisit.Load();
Tracker.CurrentPage.BeginEdit();
Tracker.CurrentPage.Visit.Value += 3;
Tracker.CurrentPage.AcceptChanges();
Tracker.CurrentPage.EndEdit();
Tracker.Visitor.CurrentVisit.BeginEdit();
Tracker.Visitor.CurrentVisit.Value += 3;
Tracker.Visitor.CurrentVisit.AcceptChanges();
Tracker.Visitor.CurrentVisit.EndEdit();
Tracker.Visitor.CurrentVisit.Load();
Tracker.CurrentVisit.CurrentPage.Visit.BeginEdit();
Tracker.CurrentVisit.CurrentPage.Visit.Value += 3;
Tracker.CurrentVisit.CurrentPage.Visit.AcceptChanges();
Tracker.CurrentVisit.CurrentPage.Visit.EndEdit();
Tracker.CurrentVisit.CurrentPage.Visit.Load();
Tracker.CurrentVisit.CurrentPage.VisitorsRow.BeginEdit();
Tracker.CurrentVisit.CurrentPage.VisitorsRow.Value += 3;
Tracker.CurrentVisit.CurrentPage.VisitorsRow.AcceptChanges();
Tracker.CurrentVisit.CurrentPage.VisitorsRow.EndEdit();
I've used different combinations of using the AcceptChanges() and BeginEdit() EndEdit() and Load() functions, as I'm not completely sure what they each do, but either way, none of them update the Value field.
I am trying to avoid doing a custom SQL query to update this field, I'm trying to figure out how to do it through the built-in Sitecore Analytics API. Can anyone help me figure out how to update this field?
The following works fine for me, are you waiting long enough to see the value written for the visit?
if (Tracker.IsActive)
{
Tracker.CurrentVisit.Value += 3;
}
No need to BeginEdit, AcceptChanges, EndEdit, etc.
What you've done should work so long as you have set up your goal correctly in Sitecore. I like to mirror sitecore's default goals, and create goals of the "Page Event" template. Make sure that you've assigned the goal to your content item Analyze Tab -> Goals -> [select your goal from checkbox list]. If you're going to set the CurrentVisit value, I suggest using the line below to prevent hardcoding the engagement point values.
//This line will add points specified in Content Editor
Tracker.CurrentVisit.Value += int.Parse(reg.Points);
This document explains how to set up your goals the correct way. And if you follow it, your code will work the way you have it, reporting the value specified in the Content Editor without setting CurrentVisit.Value.
Sitecore SDN - Marketing Operations Cookbook

Microsoft Dynamics CRM - Pass Parameters from Web Service to IPlugins

We are building some plugins in Microsoft Dynamics CRM by inheriting from IPlugin. We have these configured so they fire whenever an Account is updated.
The problem is the plugins are calling our services, which causes our service to respond with an update. We are doing some pretty hacky things right now to prevent these cyclical updates from happening.
We were wondering if there was a way to pass a value to the IOrganizationService service (the web service) that a plugin can look at. Our other system could send a flag ("hey, don't bothing sending an update!") and the plugin could skip calling back.
Can we pass parameters from web service to the plugins?
Good idea could be usage of custom flag-field. For example you add bit field and call it CallFromExternalSystem. So when you make an update from your external system through IOranizationService you just fill this flag with true field and in plugin you can check condition that this field is present in fields list so you have no need to call external system endpoint again.
We decided the correct solution was to use the value found in IPluginExecutionContext.InputParameters["Target"]. In the case of an Update, this returns an Entity containing attributes for all the attributes that were updated.
We basically have a list of attribute names we cared about. We loop through names and see if any of them appear in the entity attribute list. If so, we send an update to our other system. The good news is, Dynamics CRM ignores updates where the values don't actually change, so trying to update a value to itself is no-op.
public void Execute(IServiceProvider serviceProvider)
{
IPluginExecutionContext context = serviceProvider.GetService(typeof(IPluginExecutionContext));
Entity entity = (Entity)context.InputParameters["Target"];
string[] fields = new string[] { "name", "statecode", "address1_line1" };
bool hasUpdates = fields.Where(f => entity.Attributes.Contains(f)).Any();
if (!hasUpdates)
{
return;
}
}

SharePoint List item BRIEFLY appears as edited by 'System Account' after item.update

I have a shopping cart like application running on SharePoint 2007.
I'm running a very standard update procedure on a list item:
using (SPWeb web = site.OpenWeb())
{
web.AllowUnsafeUpdates = true;
SPList list = web.Lists["Quotes"];
SPListItem item = list.GetItemById(_id);
item["Title"] = _quotename;
item["RecipientName"] = _quotename;
item["RecipientEmail"] = recipientemail;
item["IsActive"] = true;
item.Update();
site.Dispose();
}
This item updates properly, however it briefly appears as modified by System Account. If I wait a second and refresh the page, it shows up again as modified by CurrentUser.
This is an issue because on Page_Load I am retrieving the item that is marked as Active AND is listed as Modified By the CurrentUser. This means as a user updates his list, when the PostBack finishes, it shows he has no active items.
Is it the web.AllowUnsafeUpdates? This is necessary because I was getting a security error before.
What am I missing?
First off, it's not AllowUnsafeUpdates. This simply allows modifying of items from your code.
It's a bit hard to tell what's going on without understanding more of the flow of your application. I would suggest though that using Modified By to associate an item to a user may not be a great idea. This means, as you have discovered, that any modification by the system or even potentially an administrator will break that link.
I would store the current user in a custom field. That should solve your problem and would be a safer design choice.
There could be some other code running in Event Receivers and updating the item. Because event recievers runs in context of system user account, and if you update item from event reciever, the modified field will show just that: the system account has modified the item.

Failing to fetch CategorizedFacebookType

I have an application which I developed about a year ago and I'm
fetching facebook accounts like this:
facebookClient = new DefaultFacebookClient(access_token);
Connection<CategorizedFacebookType> con = facebookClient.fetchConnection("me/accounts", CategorizedFacebookType.class);
fbAccounts = con.getData();
It worked fine until about a month ago, but now it returns the
fbAccounts list empty. Why is that?
I was hoping moving from restfb-1.6.2.jar to restfb-1.6.9.jar would
help but no luck, it comes up empty on both.
What am I missing?
EDIT, to provide the code for another error I have with this API. The following code used to work:
String id = page.getFbPageID(); // (a valid facebook page id)
FBInsightsDaily daily = new FBInsightsDaily(); // an object holding some insights values
try {
Parameter param = Parameter.with("asdf", "asdf"); // seems like the param is required
JsonObject allValues = facebookClient.executeMultiquery(createQueries(date, id), JsonObject.class, param);
daily.setPageActiveUsersDaily((Integer)(((JsonArray)allValues.opt("page_active_users_daily")).getJsonObject(0)).opt("value"));
...
This throws the following exception:
com.restfb.json.JsonException: JsonArray[0] not found.
at com.restfb.json.JsonArray.get(JsonArray.java:252)
at com.restfb.json.JsonArray.getJsonObject(JsonArray.java:341)
Again, this used to work fine but now throws this.
You need the manage_pages permission from the user to access their list of adminned pages - a year ago I'm not sure you did - check that you're obtaining that permission from your users
{edit}
Some of the insights metrics were also deprecated, the specific values you're checking may no longer exist - https://developers.facebook.com/docs/reference/fql/insights/ should have the details of what is available now
Try to check your queries manually in the Graph API Explorer to eliminate any issues in your code and hopefully get more detailed error messages that your SDK may be swallowing