HazelCast .NET - Clear Maps dynamically - c#

I'm creating several maps to cache some info for my application.
When some events are triggered I want to clear those caches.
I have a list of all maps names I should clear but I couldn't find a way to dynamically get those maps in order to clear them. Basically I have:
var mapsNames = ["map-1", "map-2", "map-3"];
And I want a simple way of doing things like:
var client = HazelcastClient.NewHazelcastClient();
foreach (var name in mapsNames)
{
var map = client.GetMap(name);
map.Clear();
}
In the README.md we do have some examples like:
var client = HazelcastClient.NewHazelcastClient();
var personnelMap = client.GetMap("personnelMap");
personnelMap.Put("Alice", "IT");
personnelMap.Put("Bob", "IT");
personnelMap.Put("Clark", "IT");
Console.WriteLine("Added IT personnel. Logging all known personnel");
foreach(var entry in personnelMap.entrySet())
{
Console.WriteLine("{0} is in {1} department", entry.Key, entry.Value );
}
client.Shutdown();
That indicates we should have a method GetMap that is non-generic but I couldn't find it. The only one avaiable is GetMap<TKey, TValue>. Are the docs wrong? Is there a way to get a Map by its name without using some ugly reflection?
Thanks in advance,

Did you try (ICollection<IDistributedObject> GetDistributedObjects()) https://github.com/hazelcast/hazelcast-csharp-client/blob/v3.12.1/Hazelcast.Net/Hazelcast.Client/HazelcastClient.cs#L230 ?
You can iterate through all the existing maps, and you can use https://github.com/hazelcast/hazelcast-csharp-client/blob/v3.12.1/Hazelcast.Net/Hazelcast.Core/IDistributedObject.cs#L53 to check is the distributed object is of type map service.

Related

Making object models in solution based on third party ElasticSearch solution

When you deal with JSON, it's really easy to make C# models. You either Paste special in Visual Studio, or you use one of the many available tools online.
ElasticSearch responses obviously are JSON, meaning, if you can get the responding JSON, you're good to go. However, if you just have a connection-string and simply want to "map" all the ElasticSearch objects into your C# code - how do you do it?
My question:
Is there a way to see all fields/data in an ElasticSearch instance, and then easily get the JSON, so you can get strongly typed models?
You can query elasticsearch for mappings. Mapping will contain all information you need to build model in C# (but you will still have to build it by hand I think). Example using database from your previous question:
var settings = new ConnectionSettings(new Uri("http://distribution.virk.dk/cvr-permanent"));
var client = new ElasticClient(settings);
// get mappings for all indexes and types
var mappings = client.GetMapping<JObject>(c => c.AllIndices().AllTypes());
foreach (var indexMapping in mappings.Indices) {
Console.WriteLine($"Index {indexMapping.Key.Name}"); // index name
foreach (var typeMapping in indexMapping.Value.Mappings) {
Console.WriteLine($"Type {typeMapping.Key.Name}"); // type name
foreach (var property in typeMapping.Value.Properties) {
// property name and type. There might be more useful info, check other properties of `typeMapping`
Console.WriteLine(property.Key.Name + ": " + property.Value.Type);
// some properties are themselves objects, so you need to go deeper
var subProperties = (property.Value as ObjectProperty)?.Properties;
if (subProperties != null) {
// here you can build recursive function to get also sub-properties
}
}
}
}

change key of hashtable, possible?

I just wonder if it's possible to change the key of a hashtable? And if so, how do i do it?
Here is the keys of my hashtable which i got by doing this:
var param = selectedGroup.Parameters.Keys;
so what i want to do is basically just change the key.
selectedGroup.Parameters.Keys[i].Value = newKey;
how do i do that?
I guess i have to move all the values beloning to that key somehow.
i tried to make a new hashtable like this
var parameters = new Tacton.Configurator.ObjectModel.SequencedHashtable<Tacton.Configurator.ObjectModel.Parameter>();
for (int i = 1; i < selectedGroup.Parameters.Count + 1; i++)
{
var para = result.Xml.SelectNodes("/session/view/parameters/param[" + i + "]/field")[0].InnerText + result.Xml.SelectNodes("/session/view/parameters/param[" + i + "]/desc-frags/frag[2]/#name")[0].Value;
var param = selectedGroup.Parameters[i];
parameters.Add(para, param);
}
but then i got the following error:
Unable to cast object of type 'Named`1[Tacton.Configurator.ObjectModel.Parameter,Tacton.Configurator.ObjectModel.Parameter]' to type 'Tacton.Configurator.ObjectModel.Parameter'.
i basically want the same hashtable as selectedGroup.Parameters but i want to change the keys from
handsender_part_qty_multifieldITM_HANDSENDER_N002592U00U01 to
handsender_part_qty_multifieldITM_HANDSENDER_N002592-00-01
this is what selectedGroup.Parameters[i] looks like:
In most versions of "hashtables", there is no way of changing the key of an entry. This is because the key's hash value is very important. Changing key almost always changes the hash value and the entries would have to be moved around identically as if you removed old entry and re-added new entry with new key.
This is why, usually, there is no way of 'editing' the key. Instead, typical hashtables force you to expicitely remove and then add the entry back. Look at the classical .Net's Dictionary for an example of that.
Now, as for your piece of code, this is a pure guesswork. I couldn't find anything related to Tacton/SequencedHashtable on the internet, so I couldn't review its API, so from my point of view, there may be furry dragons inside and yourhash.Add(foo) may format your harddrive just for fun.
However, basing on your requirement:
i basically want the same hashtable as selectedGroup.Parameters but i want to change the keys from handsender_part_qty_multifieldITM_HANDSENDER_N002592U00U01 to handsender_part_qty_multifieldITM_HANDSENDER_N002592-00-01
and on the "general idea of a hashtable" and on the assumption that this hashtable has some reasonable API that is designed so a typical .Net developer wouldn't bite his hands off using it, please try some typical things:
var parameters = new SequencedHashtable<Parameter>();
foreach(var par in selectedGroup.Parameters)
{
var newname = par.Name.Replace("U", "-");
// try changing the parameter's name:
par.Name = newname;
parameters.Add(par);
}
or
...
// try adding the parameter under new name:
par.Name = newname;
parameters.Add(newname, par);
...
or
...
// try cloning the parameter with new name:
var newpar = new Parameter(newname, par.config1, par.option2, par.foobar3, ...)
parameters.Add(newpar);
...
This is just a sketch. You may need to find the correct overload of 'Add' method. Maybe you will need to use 'Insert' instead. It may turn out that the hashtable doesn't support adding - then check its constructors. Maybe there's some constructor that takes a List of Parameters?
var parameters = new List<Parameter>(); <---- INTO a temporary list
foreach(var par in selectedGroup.Parameters)
{
var newpar = ..par or clone of par..
....edits, fixes to the newpar
parameters.Add(newpar);
}
var myNewParams = new SequencedHashtable<Parameter>( parameters );
etc. Unfortunatelly, most of the job is on your side - you have to review hte hashtable's API, you have to check if/how to edit the param's name, and/or how to clone the parameter so that all bits are preserved.
...or if you could point out where I/We can read the docs, then maybe someone will look at them. I have not found them, sorry.

C#, Generics, Type and NHibernate

I'm learning the power of generics in C# in conjunction with NHibernate. I'd like to attempt the following in the pasted code.
In an attempt to do some post processing of N number of NHibernate objects I worked on a utility method leveraging generics to make it applicable to all NHibernate mapping classes we use now, or in the future. It works but I need to hard code each call for each mapping class. This is a pain and will need continuing updating as our schema and mappings change over time.
I do have an ever up-to-date list of all mapping classes by string name through the NHibernate mappings I generate on the fly. If there was a way to use this list of string names to call my generics based method, I'd be super happy.
Can anyone tell me if this is possible? Do I need to find another route?
Thanks so much in advance!!!
public static void ProcessSomeItems()
{
// *************************************************************
// As of now I have to list all classes as such to be processed
// It works but I have to update manually when new mapping classes are created
// *************************************************************
NHibDoSomethingUtil<AspnetMembership>();
NHibDoSomethingUtil<AspnetProfile>();
NHibDoSomethingUtil<AspnetRole>();
NHibDoSomethingUtil<AspnetUser>();
// and so forth...
// I have a up-to-date list of all mappings from "HbmMapping" and can get a list of all in the
// list form as below
List<string> mappingNames = new List<string>();
foreach (string mappingName in mappingNames)
{
Type theType = Type.GetType(mappingName);
// I know I'm getting Types and Generics classes and so forth all jumbled but
// how in the heck would I do something like the below?
NHibDoSomethingUtil<theType>(); // Obviously doesn't compile ;-)
}
}
// Generic method
public static void NHibDoSomethingUtil<T>() where T : class
{
using (ISession session = sourceDBSessionFactory.OpenSession())
{
foreach (dynamic item in new List<T>(session.QueryOver<T>().List()))
{
// Process item;
}
}
}
ecsousa gave great input and I was able to accomplish what I needed with something like the following.
foreach (HbmClass mappingClass in mapping.Items)
{
Console.WriteLine(" -- Discovered Mapping: " + mappingClass.Name);
Type mappingClassType = Type.GetType(mappingClass.Name);
var genericMethod = typeof(Migration).GetMethod("NHibDoSomethingUtil");
var method = genericMethod.MakeGenericMethod(mappingClassType);
method.Invoke(null, null);
}
You will need to use Reflection in order to accomplish this. Instead of directly calling NHibDoSomethingUtil, try this:
var genericMethod = typeof(TheClassName).GetMethod("NHibDoSomethingUtil");
var method = genericMethod.MakeGenericMethod(theType);
method.Invoke(null, null);
Note that you have to replace TheClassName by the class containing both methods.
Keep in mind the this kind of code is slow, and you should use it very carefully.

Get a User Object by username field

I've looked around and cannot figure out how to get a different user by their user name, something tells me this is not possible am I correct? I want the user to be capable of using Game Center or Google Play and not just Facebook as an id. That means I can register anyone I want as a user and then find their friends (without having to use FB). Should I just make a separate Table to store this info?
I have attached code below for what should work, can anyone give some insight in either my code or on why I cannot get "bob". I have tested this code against another table and I can get the rows.
The code falls through properly and I do get to the foreach but there are no results to iterate through
I have also tried "_User" but get
ArgumentException: Use the class-specific query properties for class _User
Parameter name: className
Any help here would be great I would like to avoid making another Table just for searching and doing relationships to other tables.
private void getParseObjectTest()
{
var query = ParseObject.GetQuery("User").WhereEqualTo("username", "bob");
query.FindAsync().ContinueWith(user =>
{
if (user.IsCanceled || user.IsFaulted)
{
Debug.Log("Can't get the user.... " + user.Exception.Message);
}
else
{
Debug.Log("Return was success time to iterate");
IEnumerable<ParseObject> results = user.Result;
foreach (var result in results)
{
string str = result.Get<string>("email");
Debug.Log("email: " + str);
}
}
});
}
In Unity you must use ParseUser.Query instead of ParseObject.Query when querying users.
https://parse.com/docs/unity_guide#users-querying
And if you can't do what wbdev said (because there is another bug triggered by using generic ParseQuery objects), you can create the non-generic query with new ParseQuery<ParseObject>("_User").

Enumerate ALL properties of AD Object (even unset ones)

I'm trying to find several properties that aren't used anywhere in our AD environment. I don't care what the property name is as long as it isn't used.
I was attempting to do this in C# mainly so that I can explore those classes while I solved this problem, but can't seem to find a way to list all of the properties for an object. The DirectoryEntry.Properties returns a collection of set properties only (as far as I can tell).
So is it possible to view all the active (available) properties for an object or are you only able to view the ones that are currently set with a value somewhere?
EDIT: Current code...
using (var directoryObject = new DirectoryEntry("LDAP://CN=GroupCN,OU=groups,DC=domain,DC=com", "uid", "pass", AuthenticationTypes.ReadonlyServer)) {
foreach (var prop in directoryObject.Properties.PropertyNames) {
Console.WriteLine(prop.ToString() + " | " + directoryObject.Properties[prop.ToString()].Value.ToString());
}
}
Edit: Ok. So I missed the bit about all possible properties. So I will address that.
Since the DirectoryEntry object is an implementation of IDictionary, there really is no way to know what properties can be set. IDictionary will allow you to add as many custom properties as you would like to the object. The documentation for System.DirectoryServices.Property collection is here: http://msdn.microsoft.com/en-us/library/system.directoryservices.propertycollection(v=vs.100).aspx
The below will enumerate all the current properties of the results of an LDAP search. You could adapt this to find all the properties that are currently used on the objects returned in the search result.
foreach (SearchResult item in searchResultCollection)
{
foreach (string propKey in item.Properties.PropertyNames)
{
foreach (object property in item.Properties[propKey])
{
Console.WriteLine("{0} : {1}", propKey, property.ToString());
}
}
}

Categories