couchbase lite xamarin pull replication with sync-gateway - c#

I want to pull documents with username attribute
as user1 for user1 like that for each user only attribute with their name.
This is my replication code.
private void setupreplication(){
Console.WriteLine ("Setting up replication");
Uri Server = new Uri("http://192.168.1.213:4984/aussie-coins-syncgw/");
var pull = _db.CreatePullReplication (Server);
var push = _db.CreatePushReplication (Server);
pull.Filter = "byUser";
pull.FilterParams = new Dictionary<string, object> { {"type", "user1"} };
pull.Continuous = true;
push.Continuous = true;
pull.Start();
push.Start();
}
This is my set filter code
_couchBaseLiteLocal.SetFilter("byUser", (revision, filterParams) =>
{
var typeParam = filterParams["type"].ToString();
return (typeParam != null) && typeParam.Equals("user1");
});
With the above code generic pull itself not working.
I just tried to do as given in the documentation.
I do not understand how the setfilter function works to filter data from server. It would be great if someone help in understanding how setfilter works and to make the above code working
Thanks in advance.

The filter function in pull replications can indeed return the specific documents you are interested in. But it's not very efficient, the filter function will run on all the documents on the remote database to determine which ones to pull, every time a pull replication is started.
Instead Sync Gateway introduces the concept of a sync function that incrementally routes and computes access control rules on documents. That way, when starting the pull replication, it's fast and straightforward for Sync Gateway to return the specific documents the user has access to.
You can specify individual channels in a pull replication from Sync Gateway if needed. But the thing to remember is that filtered pull replication between Sync Gateway and Couchbase Lite is not based on filter functions. It's based on the sync function and channel based filtering if needed.
In a P2P scenario (replications between two Couchbase Lite instances), the filter function model is used.

Related

need to create subdomains in Azure DNS from ASP.NET Core dynamically

I need to create subdomains in Azure DNS from ASP.NET Core dynamically so that the users who needs to create their own subdomains can do it as we see in most of the web apps out there like wix, etc..
Could anyone please detail the right steps well explained?
Thanks.
There is a management SDK for Azure, which you can use inside your ASP.NET Core application.
Create DNS zones and record sets using the .NET SDK - this is detailed full tutorial for this.
Code will be similar to this, though you will probably use CNAMEs instead of A records
// Create record set parameters
var recordSetParams = new RecordSet();
recordSetParams.TTL = 3600;
// Add records to the record set parameter object. In this case, we'll add a record of type 'A'
recordSetParams.ARecords = new List<ARecord>();
recordSetParams.ARecords.Add(new ARecord("1.2.3.4"));
// Add metadata to the record set. Similar to Azure Resource Manager tags, this is optional and you can add multiple metadata name/value pairs
recordSetParams.Metadata = new Dictionary<string, string>();
recordSetParams.Metadata.Add("user", "Mary");
// Create the actual record set in Azure DNS
// Note: no ETAG checks specified, will overwrite existing record set if one exists
var recordSet = await dnsClient.RecordSets.CreateOrUpdateAsync(resourceGroupName, zoneName, recordSetName, RecordType.A, recordSetParams);

CRM 2011 Xrm . audit records return system user instead of logged one

I created application using CRM 2011 SDK.
While retrieving audit record i use recommended code.
My code looks like this:
using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig))
{
_service = (IOrganizationService)_serviceProxy;
RetrieveRecordChangeHistoryRequest changeRequest = new RetrieveRecordChangeHistoryRequest();
changeRequest.Target = new EntityReference(Static.IncidnentsEntityName, new Guid(id));
RetrieveRecordChangeHistoryResponse changeResponse =
(RetrieveRecordChangeHistoryResponse)_service.Execute(changeRequest);
return changeResponse.AuditDetailCollection.AuditDetails.SelectMany(s => createAuditRecord(s)).ToList();
}
where createAuditRecord function just unpacks attributes. There is an attribute called userid, but it always returns system user, under which my app is calling CRM, but not the logged user.
While directly querying SQL ,I've found that there is an information about logged user.
Is there some way to extract this information without directly extracting data from DB?
I prefer to extract information directly from database if it's for external use or reports. It's much faster, you can do complexier queries and you will save a lot of time. There no plus value of using the SDK to read data other than being sure it gonna be supported in the next version and supported online.

Clarification on how to update (patch) objects using the Microsoft.Graph Client

The following code is the only way I found so far to update an object using the Microsoft Graph Client Library
Scenario:
Load an exisiting object (an organization)
Modify a value (add entry in securityComplianceNotificationPhones)
Send the update
Code
var client = new GraphServiceClient(...);
var org = client.Organization["orgid"].Request().GetAsync().Result;
var secPhones = new List<string>(org.SecurityComplianceNotificationPhones);
secPhones.Add("12345");
var patchOrg = new Organization();
patchOrg.SecurityComplianceNotificationPhones = secPhones;
var orgReq = new OrganizationRequest(
client.Organization[org.Id].Request().RequestUrl,
client, new Option[] {});
orgReq.UpdateAsync(patchOrg).Wait();
I needed to use the patchOrg instance because of two things:
The Graph API documentation states
"In the request body, supply the values for relevant fields that
should be updated. Existing properties that are not included in the
request body will maintain their previous values or be recalculated
based on changes to other property values. For best performance you
shouldn't include existing values that haven't changed."
If you actually do include existing values that haven't changed
(i.e. assginedLicenses) the request fails, if those existing values
are readonly.
My question is: Is/will there be a more straightforward way of updating existing objects like for example in the Azure ActiveDirectory GraphClient? Just for comparison, the same scenario in Azure Active Directory Graph
var client = new ActiveDirectoryClient(...);
var org = client.TenantDetails.GetByObjectId("orgid").ExecuteAsync().Result;
org.SecurityComplianceNotificationPhones.Add("12345");
org.UpdateAsync().Wait();
The Graph client library model is slightly different from the older SDK model the AAD client library you linked. The older model passed around objects that tried to be a bit smarter and reason about which properties were changed, only sending those. One of the main drawbacks of this model was that the library made many more service calls in the background and had a much heavier payload in each call since ExecuteAsync() would often need to retrieve every object in the request builder chain. The newer library does require the developer to do more explicit reasoning about what data is being passed but also gives greater control over network calls and payload. Each model has its tradeoffs.
To accomplish what you want, here's the approach I would recommend instead of creating a second org object altogether:
var client = new GraphServiceClient(...);
var orgRequest = client.Organization["orgid"].Request();
var org = orgRequest.Select("securityComplianceNotificationPhones").GetAsync().Result;
var secPhones = new List<string>(org.SecurityComplianceNotificationPhones);
secPhones.Add("12345");
org.SecurityComplianceNotificationPhones = secPhones;
orgRequest.UpdateAsync(org).Wait();

Azure Mobile Services PullAsync() Not Filling Sync Table

So I have a remote table called Profile that has multiple entries made already. Now I'm trying to integrate offline capabilities into my application. As of right now I'm having issues with PushAsync and PullAsync methods in my code.
I would like to be able to copy all the data from my remote table into my local table just by calling PullAsync, and although it doesn't throw any exceptions it also doesn't populate my table. Here's an example of what I mean.
var db = new SQLiteConnection("syncstoreTEMP.db");
var store = new MobileServiceSQLiteStore("syncstoreTEMP.db");
store.DefineTable<Profile>();
MobileService.SyncContext.InitializeAsync(store).Wait();
var remoteValues = MobileService.GetTable<Profile>()
.ToListAsync()
.Result;
MobileService.GetSyncTable<Profile>()
.PullAsync(null, MobileService.GetSyncTable<Profile>().CreateQuery())
.Wait();
var localValues = MobileService.GetSyncTable<Profile>()
.ToListAsync()
.Result;
When I run this code remoteValues has a total length of 5, but localValues still shows 0 entries even after issuing a Pull from remote. How can I get the sync table to match my remote table?
It's strange that you're not getting any exceptions, but you seem to be creating two connections to your local store. You should not have the line for new SQLiteConnection, only the line that creates the MobileServiceSQLiteStore.
Here's a tutorial that walks through how to set things up: https://azure.microsoft.com/en-us/documentation/articles/mobile-services-xamarin-ios-get-started-offline-data/
I also recommend that you add a DelegatingHandler to your MobileServiceClient in order to log all of the requests and responses. Then you can see exactly what's going wrong. Here's a sample that shows this, and also includes a logging extension to the SQLite store so you can see exactly what is happening locally: https://github.com/paulbatum/FieldEngineerLite/blob/master/FieldEngineerLite.Client/FieldEngineerLite/Helpers/LoggingHelpers.cs

Finding Connection by UserId in SignalR

I have a webpage that uses ajax polling to get stock market updates from the server. I'd like to use SignalR instead, but I'm having trouble understanding how/if it would work.
ok, it's not really stock market updates, but the analogy works.
The SignalR examples I've seen send messages to either the current connection, all connections, or groups. In my example the stock updates happen outside of the current connection, so there's no such thing as the 'current connection'. And a user's account is associated with a few stocks, so sending a stock notification to all connections or to groups doesn't work either. I need to be able to find a connection associated with a certain userId.
Here's a fake code example:
foreach(var stock in StockService.GetStocksWithBigNews())
{
var userIds = UserService.GetUserIdsThatCareAboutStock(stock);
var connections = /* find connections associated with user ids */;
foreach(var connection in connections)
{
connection.Send(...);
}
}
In this question on filtering connections, they mention that I could keep current connections in memory but (1) it's bad for scaling and (2) it's bad for multi node websites. Both of these points are critically important to our current application. That makes me think I'd have to send a message out to all nodes to find users connected to each node >> my brain explodes in confusion.
THE QUESTION
How do I find a connection for a specific user that is scalable? Am I thinking about this the wrong way?
I created a little project last night to learn this also. I used 1.0 alpha and it was Straight forward. I created a Hub and from there on it just worked :)
I my project i have N Compute Units(some servers processing work), when they start up they invoke the ComputeUnitRegister.
await HubProxy.Invoke("ComputeUnitReqisted", _ComputeGuid);
and every time they do something they call
HubProxy.Invoke("Running", _ComputeGuid);
where HubProxy is :
HubConnection Hub = new HubConnection(RoleEnvironment.IsAvailable ?
RoleEnvironment.GetConfigurationSettingValue("SignalREndPoint"):
"http://taskqueue.cloudapp.net/");
IHubProxy HubProxy = Hub.CreateHubProxy("ComputeUnits");
I used RoleEnviroment.IsAvailable because i can now run this as a Azure Role , a Console App or what ever in .NET 4.5. The Hub is placed in a MVC4 Website project and is started like this:
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(50);
RouteTable.Routes.MapHubs();
public class ComputeUnits : Hub
{
public Task Running(Guid MyGuid)
{
return Clients.Group(MyGuid.ToString()).ComputeUnitHeartBeat(MyGuid,
DateTime.UtcNow.ToEpochMilliseconds());
}
public Task ComputeUnitReqister(Guid MyGuid)
{
Groups.Add(Context.ConnectionId, "ComputeUnits").Wait();
return Clients.Others.ComputeUnitCameOnline(new { Guid = MyGuid,
HeartBeat = DateTime.UtcNow.ToEpochMilliseconds() });
}
public void SubscribeToHeartBeats(Guid MyGuid)
{
Groups.Add(Context.ConnectionId, MyGuid.ToString());
}
}
My clients are Javascript clients, that have methods for(let me know if you need to see the code for this also). But basicly they listhen for the ComputeUnitCameOnline and when its run they call on the server SubscribeToHeartBeats. This means that whenever the server compute unit is doing some work it will call Running, which will trigger a ComputeUnitHeartBeat on javascript clients.
I hope you can use this to see how Groups and Connections can be used. And last, its also scaled out over multiply azure roles by adding a few lines of code:
GlobalHost.HubPipeline.EnableAutoRejoiningGroups();
GlobalHost.DependencyResolver.UseServiceBus(
serviceBusConnectionString,
2,
3,
GetRoleInstanceNumber(),
topicPathPrefix /* the prefix applied to the name of each topic used */
);
You can get the connection string on the servicebus on azure, remember the Provider=SharedSecret. But when adding the nuget packaged the connectionstring syntax is also pasted into your web.config.
2 is how many topics to split it about. Topics can contain 1Gb of data, so depending on performance you can increase it.
3 is the number of nodes to split it out on. I used 3 because i have 2 Azure Instances, and my localhost. You can get the RoleNumber like this (note that i hard coded my localhost to 2).
private static int GetRoleInstanceNumber()
{
if (!RoleEnvironment.IsAvailable)
return 2;
var roleInstanceId = RoleEnvironment.CurrentRoleInstance.Id;
var li1 = roleInstanceId.LastIndexOf(".");
var li2 = roleInstanceId.LastIndexOf("_");
var roleInstanceNo = roleInstanceId.Substring(Math.Max(li1, li2) + 1);
return Int32.Parse(roleInstanceNo);
}
You can see it all live at : http://taskqueue.cloudapp.net/#/compute-units
When using SignalR, after a client has connected to the server they are served up a Connection ID (this is essential to providing real time communication). Yes this is stored in memory but SignalR also can be used in multi-node environments. You can use the Redis or even Sql Server backplane (more to come) for example. So long story short, we take care of your scale-out scenarios for you via backplanes/service bus' without you having to worry about it.

Categories