Unable to communicate between actors in Akka.Cluster - c#

I am having some problems in communicating between actors in Cluster.
My test project has this structure below.
TestJob [C# Console Project]
TestJobService.cs
TestJobActor
MainProject [C# Console Project] //Note: I configured this service as a seed node. I didn't use lighthouse.
MainService
JobManagerActor
Note: I don't want to put actors in Shared project or Main project. The actors that are supposed to do a test job should be under "TestJob" project.
I already followed this article http://getakka.net/docs/clustering/cluster-overview and video. I did enable Akka.Cluster based on the article. I am able to run both console projects but when I tried to "tell" from JobManagerActor to TestJobActor, it doesn't work. No error but doesn't work.
I have this config in MainProject.
actor {
provider = "Akka.Cluster.ClusterActorRefProvider, Akka.Cluster"
deployment {
/TestJobAActor {
router = consistent-hashing-group
routees.paths = ["/user/TestJobAActor"]
virtual-nodes-factor = 8
cluster {
enabled = on
max-nr-of-instances-per-node = 2
allow-local-routees = off
use-role = backend
}
}
}
}
Here is the code that I use for sending the message.
var backendRouter = Context.ActorOf(Props.Empty.WithRouter(new ClusterRouterGroup(new ConsistentHashingGroup("/user/TestJobAActor"),new ClusterRouterGroupSettings(10, false, "backend", ImmutableHashSet.Create("/user/TestJobAActor")))));
backendRouter.Tell("Yo yo!");
What am I missing? Thanks in advance.
Note: My test project with similar structure can be found here https://github.com/michaelsync/APMDemo . (VS2015 project)
One more question: Can we still use the actor selection when using cluster?
var actorSelection = Context.ActorSelection("akka.tcp://MyBackendProcessingSystem#127.0.0.1:2553/user/BackEndJobAActor"); //This can come from Model
actorSelection.Tell("Yo yo!");

No worries!
I managed to fix it myself. You can see the fixes in my temp repo https://github.com/michaelsync/APMDemo/tree/allinoneproject.
The problem was that I didn't know I need to use IConsistentHashable for sending message in consistent-route. I keep on sending the string and didn't work.
local route was off.

Related

SAM card authentication failed

I should modify an existent software to write some data in Smart Cards. Today we are generating keys with an HSM. Now our client is requesting us to do that with a SAM card.
Now, I modified the software, and it works fine when debugging attached to VS. When I try to run the app outside VS, SAM authentication fails.
The situation is: we should use a C++ library in order to generate the APDU commands for the SAM cards, and this library is delivered to us by our client, so we have a black box. The SAM cards are also delivered by our client. I received also a CLI app that do the same operations than the DLL.
I developed a wrapper for the DLL and another one for the CLI app. When I run my application using the CLI wrapper it works fine when debugging and when I run it outside VS (installed app). When I try to run it using the DLL, it works fine when debugging on VS, but SAM authentication fails when I run it outside VS.
In both cases the C# code is the same (DLL wrapper or CLI wrapper) and only changes the running environment (debugging under VS or direct run from Windows). The library is loading correctly, apparently all its dependencies also, so I don't understand where is the problem.
public bool AuthenticateOnSamCard(PCSCReader reader, string transportKey)
{
// Step 1
var apduStep1 = SAMHandlerCommandExecutor.AuthStep1();
reader.SCard.Connect(reader.SCard.ReaderName, SCARD_SHARE_MODE.Shared, SCARD_PROTOCOL.Tx);
var response = reader.Exchange(apduStep1); //-> Auth step
var dataStep1 = SAMHandlerCommandExecutor.GetData(response);
if (dataStep1[0][0] != 1)
{
reader.SCard.Disconnect();
return false;
}
// Step 2
var apduStep2 = SAMHandlerCommandExecutor.AuthStep2(transportKey, dataStep1[1]);
response = reader.Exchange(apduStep2[0]); //-> Auth step 2
var dataStep2 = SAMHandlerCommandExecutor.GetData(response);
if (dataStep2[0][0] != 1)
{
reader.SCard.Disconnect();
return false;
}
// Step 3
var apduStep3 = SAMHandlerCommandExecutor.AuthStep3(transportKey, dataStep2[1], apduStep2);
response = reader.Exchange(apduStep3);
if (SAMHandlerCommandExecutor.Verify(response))
{
Console.WriteLine($"Sam Authentication OK");
Program.Logger.Info($"Sam Authentication OK");
return true;
}
return false;
}
Any suggestion?

Post Journal Entries to EPICOR 905 using C#

I'm trying to connect to Epicor905 and post a journal entry programmatically.
I found the below code which connects to Epicor. However, I am unable to locate any info on accessing the GL Journal Entry module. I'm fairly new to C# and just want someone to point me in the right direction logically/technically. I understand that the core of it is working with DLLs and the business objects. But beyond that I am clueless. Here is the code I found to connect to EPICOR:
using Ice.Core;
using Erp.Common;
try
{
Session obj = new Session("manager", "manager", Session.LicenseType.Default, #"C:\Epicor\E10Pilot.sysconfig");
if (obj != null)
{
MessageBox.Show("Sesion valida");
obj.Dispose();
obj = null;
}
}
catch (Exception error)
{
MessageBox.Show(error.Message);
}
The easiest way to identify the calls required is to start client tracing and run through the process you wish to automate in the UI. This will record the calls that the UI makes for your particular process. You should then be able to replicate them in your code.
You will need to reference the contract assembly for each BO required from your client directory.
This will take some experimentation to identify the right calls but this is exactly how the CSG team in Epicor would approach this.

Dynamics CRM/Dynamics 365 Apply solution upgrade programmatically

There is a set of rules that should be applied while moving solutions from one instance to another, so there is an idea to use a custom tool that will make all changes, export and import solutions to another instance. The question is next:
How could "solution upgrade applying" be implemented with C#?
Importing "as holding" easily could be done by setting (CRM 2016 SDK)
var import = new ImportSolutionRequest();
import.HoldingSolution = true;
this allows to have a holding solution in a target environment, but after some tests we still can't "Apply" this upgrade for the previously installed solution.
Thank you in advance.
After you have imported the holding solution you can upgrade it using a DeleteAndPromoteRequest.
A basic example:
public Guid UpgradeSolution(string solutionUniqueName, IOrganizationService service)
{
var request = new DeleteAndPromoteRequest
{
UniqueName = solutionUniqueName
};
var response = (DeleteAndPromoteResponse)service.Execute(request);
return response.SolutionId;
}
In the DeleteAndPromoteResponse the SolutionId property holds the Guid of the promoted solution.

NUnit is not failing test with dynamic keyword of .Net 4.0

I am using NUnit with Visual Studio Express Edition 2010 for C#, Now, normally test works fine. But whenever I try to use Massive.cs, which is open source api to access database. Test fails from that file only. Now, if I run the application, api is working fine. I have created a different library file to access data base.
I seriously don't understand the error. It is just giving error that object reference is not set to an object. But if I run the code, it works fine. I am using dynamic keyword as shown in link of api above. Does that making problem with NUnit ?
Is there any other way to test in this type of Scenarios?
Here are the further details of the code,
Test class is like this
dynamic item = new Item();
item.Insert(new { Name = "Maggi", Description = "Its 2 Min Nuddles", IsDelete = false });
var items = item.All();
Assert.AreEqual("Maggi", items.FirstOrDefault().Name);
Now, I have put test here. Which gives error like shown in image,
Now if I run code in console application, then code is working fine, code snippet is given below
dynamic item = new Item();
item.Insert(new { Name = "Maggi", Description = "Its 2 Min Nuddles", IsDelete = false });
var result = item.All();
foreach (var i in result)
{
Console.WriteLine(i.Name + i.Description);
}
Console.Read();
Here, code is working and same thing is not working with NUnit Test. Please have a look and help me out. Please let me know if any further information is needed from my side.
Most probable explanation is that you haven't set up your connection string in the test project.
If you are using NUnit, just put it in app.config of your test project.
Solved... There is a issue with NUnit Testing. It was not taking config file pefectly. So, I made two changes. Changes I have done in Project setting.
First change is to change Application Base to bin\debug just give application base as this and then config file to .config to .exe.config and things are up and running. :)

C# Waiting for other services to start

I'm writing a Windows service that relies on other services, how should I wait for the other services to start?
Thanks
In addition to what other answers have alredy pointed out, if one of those services is SQL Server you will need to ensure that the specific database is available as well as the SQL Server service itself.
I use a function similar to the following:
public class DbStatus
{
public static bool DbOnline()
{
const int MaxRetries = 10;
int count = 0;
while (count < MaxRetries)
{
try
{
// Just access the database. any cheap query is ok since we don't care about the result.
return true;
}
catch (Exception ex)
{
Thread.Sleep(30000);
count++;
}
}
return false;
}
}
I think you shoud this line
installer.ServicesDependedOn = new string [] { "DependenceService" };
like this:
using (ServiceProcessInstaller processInstaller = new ServiceProcessInstaller())
{
processInstaller.Account = ServiceAccount.LocalSystem;
processInstaller.Username = null;
processInstaller.Password = null;
using (ServiceInstaller installer = new ServiceInstaller())
{
installer.DisplayName = "yourservice.";
installer.StartType = ServiceStartMode.Automatic;
installer.ServiceName = "YourService";
installer.ServicesDependedOn = new string [] { "DependenceService" };
this.Installers.Add(processInstaller);
this.Installers.Add(installer);
}
}
good luck
You need to specify the dependencies. You can do this in your Installer class.
Further clarification
You should be using an Installer class as a Custom Action in your setup project to install your service. If you aren't, post a comment and I'll update this answer with steps on how to do that.
Inside the designer for your Installer class you should see two components: a serviceInstaller and a serviceProcessInstaller. I don't remember which off of the top of my head, but one of these has a property that allows you to specify a multiline string that lists the service names of your service's dependencies.
As others here said, you should use the ServiceInstaller Class, but you don't need a full blowned setup project.
You can do a quick instalation using InstallUtil.exe, a command-line utility that comes with the .NET Framework.
Do you have control over the other services?
If yes have them start you, if not I guess you have to start anyway and monitor yourself what is going on.
It is possible to register yourself with WMI to get notifyied when other processes are started - there is a question about it.
In your service project, add a project installer as described here. One of the properties of your ProjectInstaller will be ServicesDependedOn. When you add services to that array of strings (you can do that through the IDE), they will be required to be started before your service will start. If they are not started the SCM will try and start them.

Categories

Resources