Shutdown mongoDb server with c# driver 2.2.3 - c#

With previous version of C# drivers (1.x) I could do :
var client = new MongoClient(settings);
var server = client.GetServer();
server.Shutdown();
How can I do this with driver version 2.2.3 ?
Update
Well the best I could find is something like this :
try
{
var client = new MongoClient(settings);
var adminDatabase = client.GetDatabase("admin");
var cmd = new BsonDocument("shutdown", 1);
adminDatabase.RunCommand<BsonDocument>(cmd);
}
catch (MongoConnectionException e)
{
if (!(e.InnerException is EndOfStreamException))
{
throw;
}
}
but I dont really like this, the Try/catch etc ...

They told me at the Google Groups Page that is because it should never be used from most applications.
Craig Wilson mentioned that shutdown is simply a command that can be send using
db.RunCommand("{shutdown: 1}")
So it isn't anymore available in the API .net Version 2.0.0 and above.

This is the best that I could find after some intensive searching today. I am using the MongoDB C# driver 2.2. There are no special credentials to my mongod instance, it is all default settings. I would imagine this code would change a bit if there are special login credentials for the admin database.
// Connecting. 1 DB for actual usage, 1 for running the shutdown command
Client = new MongoClient("mongodb://127.0.0.1:27017");
Database = Client.GetDatabase(DBName);
AdminDatabase = Client.GetDatabase("admin");
// Shutting down the DB "cleanly"
AdminDatabase.RunCommandAsync<BsonDocument>(new JsonCommand<BsonDocument>("{shutdown: 1}"));
From what I can tell by watching the mongod instance in a command prompt my application successfully connects, writes, reads, and then shuts down the mongod instance with dbexit: rc: 0 which from what I can tell means it shutdown correctly, I faintly remember seeing dbexit: rc: 12 when shutting down that way I was before (don't even ask).

Related

Simple console app in C# .NET CORE 3.1 to test a local DynamoDB table running in Docker

Folks,
I have created a very simple console application in C# .NET 3.1 based on the following example:
https://www.c-sharpcorner.com/article/access-amazon-dynamodb-locally-in-net-core-console-application/
There is nothing proprietary about this example. It's super simple. Here is the code:
using System;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DocumentModel;
using System.Threading.Tasks;
namespace Dynamodb
{
class Program
{
static async Task Main(string[] args)
{
var clientConfig = new AmazonDynamoDBConfig();
clientConfig.ServiceURL = "http://localhost:8000";
AmazonDynamoDBClient client = null;
try
{
client = new AmazonDynamoDBClient(clientConfig);
}
catch (Exception ex)
{
throw ex;
}
var tableName = "Token";
var hash = "{\"tenant_id\":\"c86f34aa-85c1-42ae-af67-9b0428231033\"}";
var range = "{}";
var table = Table.LoadTable(client, tableName);
var filter = new QueryFilter("range", QueryOperator.Equal, range);
var search = table.Query(hash, filter);
var set = await search.GetNextSetAsync();
}
}
}
The problem I am having is that it breaks when I new up the client. The error I get is:
"Invalid region endpoint provided."
I have tried setting the Region, configuring from the appsettings.json, injecting environment variables, etc. None of that worked. I tried .NET CORE 5.0. Nope.
To cut to the chase. The AWS NUGET packages are the latest available. I am running DynamoDB from Docker using the latest WSL 2 on a windows 10. The docker command line looks like this:
docker run -d -p 8000:8000 amazon/dynamodb-local -jar DynamoDBLocal.jar -sharedDb
I can access my table using AWS CLI from within BASH and from a simple windows DOS prompt on port 8000. I can connect to localhost:8000 inside of NoSQL Workbench and see my table and its data.
I have also tried using the DynamoDB service from the latest LOCALSTACK docker image. I could not figure out how to easily override it to enable SharedDb. I am not convinced that it matters. However, I had to use SharedDb to see my DynamoDB table in the NoSQL Workbench tool. So, I focused on the AWS Docker image for DynamoDB.
Anyway, I have exhausted my investigation into this after two days of searching for answers. I had the same experience on yet another machine just to double check. I am convinced this is not a fluke.
I am only interested in answers if you have encountered this problem and know how to overcome it. I find it inconceivable that having reproduced the problem on two different machines that this is a unique problem. In the meantime I will use POSTGRES SQL. It's not my preference, but I have commitments to deliver.

Programatically Added MSMQ Queues Different From Manual Creation

We are in the process of migrating an app from a Server 2008 set of servers to Server 2016, and since this app has ~75 private MSMQ queues, I wrote a very basic C# utility (just a console app) to get the list from our production server and recreate them on the new 2016 server via the following:
//connect to the specified server to pull all existings queues
var queues = MessageQueue.GetPrivateQueuesByMachine("[production server name]");
var acl = new AccessControlList();
acl.Add(new AccessControlEntry
{
EntryType = AccessControlEntryType.Allow,
GenericAccessRights = GenericAccessRights.All,
StandardAccessRights = StandardAccessRights.All,
Trustee = new Trustee("Everyone")
});
acl.Add(new AccessControlEntry
{
EntryType = AccessControlEntryType.Allow,
GenericAccessRights = GenericAccessRights.All,
StandardAccessRights = StandardAccessRights.All,
Trustee = new Trustee("Network Service")
});
foreach (var queue in queues)
{
var newQueue = MessageQueue.Create($".\\{queue.QueueName}", true);
newQueue.SetPermissions(acl);
newQueue.Label = queue.QueueName;
}
When I start running our web app on the new server and execute an action that places a message on the queue, it fails with System.Messaging.MessageQueueException: Access to Message Queuing system is denied, despite the Everyone ACL entry that is confirmed added to the queue.
The really strange part I'm running into though, is if I delete the queue in question and recreate it manually on the server with the same Everyone has full control permissions, the code works successfully. I've compared the properties of an auto-generated queue to a manually created one and everything is 100% identical, so it makes zero sense why this would occur.
Any suggestions? I'm at a loss, but trying not to have to create all of these queues manually if I can avoid it.
After a lot of back and forth testing, I reached out to Microsoft Support and one of their engineers has confirmed there's a bug of some kind on the .Net side with creating queues. We confirmed everything was identical, but the only time permissions worked was if the queue was created manually via the Computer Management snap-in. Creating it in code, regardless of permissions, caused it to not work correctly for multiple accounts.
Hopefully this helps anyone else trying to do this!

MongoDB server State is disconnected

I am using MongoDb server installed on VM Ubuntu 14 on Azure, and I use this
tutroial, with last version. I add the port of mongo 27017 too.
And I connect to it directly and add Database with some collections.
I use the mongoDb .Net Driver on VS2015 in C# with version 2.0.1 (using link)
and try to connect to the Mongo Server, but the state of the server is disconnected
var client = new MongoClient("mongodb://name.cloudapp.net:27017");
var state = client.Cluster.Description.State;
MessageBox.Show(state.ToString());
I used it before the same steps and nothing happen, just I don't know where is the problem
Try this please. I think this may work. Just have to add one line to enumerate all databases.
var client = new MongoClient("mongodb://name.cloudapp.net:27017");
var databases = client.ListDatabases();
var state = client.Cluster.Description.State;
MessageBox.Show(state.ToString());
This answer explains better.

Mongo C# driver try reconnect on connection failure

Is there a common way to recover from a connection error in MongoDB with the C# driver?
Currently, my Windows service shuts down if MongoDB is turned off. I currently have my app structured like this at the start of my Windows service:
//Set up connections for Mongo
var con = new MongoConnectionStringBuilder(ConfigurationManager.ConnectionStrings["MongoDB"].ConnectionString);
var client = new MongoClient(con.ToString());
var server = client.GetServer();
var db = server.GetDatabase(con.DatabaseName);
I then inject the db object into my repositories.
I'm trying to find something like an event handler or a condition I could listen to in my whole application to prevent from crashing the entire service should mongo go down for some reason.
As suggested by the driver document, the MongoClient is added to manage Replica Set stuff, which earlier or later you will need. To avoid mass code refactoring then, you need to make better use of it now.
The MongoClient, which is thread-safe, have implemented the failover logic among replica set nodes already. It's supposed to be singleton along with your application domain. Thus you can inject the MongoClient, other than db (which is not even thread safe).
So always retry the GetServer() and GetDatabase() from MongoClient, and try/catch the exceptions produced by them would finally give you the available db object when MongoDB is online again.
The point is, MongoDB will not notify the clients about its online, so there's no such event to notify you, either. You'll have to keep trying in your client side until it's ok. And to avoid the exceptions to bring down your service, you'll have to catch them.
EDIT: I am wrong about the thread-safety according to the document. However, it doesn't change the fact you shouldn't store MongoDatabase for future migration to replica set.
In addition to yaoxing answer, wanted to do show code piece to solve this issue.
var client = new MongoClient(connString);
var server = client.GetServer();
while (server.State == MongoServerState.Disconnected)
{
Thread.Sleep(1000);
try
{
server.Reconnect();
}
catch (Exception ex)
{
Debug.WriteLine("Failed to connect mongodb {0} Attempt Count: {1}",
ex, server.ConnectionAttempt);
}
}

How to Programatically Start IIS 6.0 SMTP Virtual Server?

I would like to know how to programatically restart IIS 6.0 SMTP server.
The SMTP server I have setup crashes every now and then. I don't notice it for a couple days, but that is by far way too late to do anything about it.
I want to set up a scheduled task every 30 minutes or so to test if the SMTP server is running, and if its not, the Scheduled task with automatically start it back up.
I have found a way to check if the SMTP server is up and running, but I have not figured out how to restart the process if it crashes.
That way is posted here: Testing SMTP server is running via C#
Any help would be brilliant!
Thank you.
Im developing the Console application in C# to check if its running or not, so any code examples would be great too.
A ServiceController can help you, as it has start and stop methods. Look at the sample in the msdn page.
Another sample is taken from the ServiceControllerStatus Enumeration is nearly what you need (just replace the service name).
ServiceController sc = new ServiceController("Telnet");
Console.WriteLine("The Telnet service status is currently set to {0}",
sc.Status.ToString());
if ((sc.Status.Equals(ServiceControllerStatus.Stopped)) ||
(sc.Status.Equals(ServiceControllerStatus.StopPending)))
{
// Start the service if the current status is stopped.
Console.WriteLine("Starting the Telnet service...");
sc.Start();
}
else
{
// Stop the service if its status is not set to "Stopped".
Console.WriteLine("Stopping the Telnet service...");
sc.Stop();
}
// Refresh and display the current service status.
sc.Refresh();
Console.WriteLine("The Telnet service status is now set to {0}.",
sc.Status.ToString());
Maybe I'm missing something, or something changed, but when you install SMTP service on Windows 2012R2, there is no dedicated service for it. So, for recent version of Windows the advice above won't work.
Luckily there's a way to do it much easier. Powershell:
([ADSI]'IIS://LOCALHOST/SMTPSVC/1').Start() #to start
([ADSI]'IIS://LOCALHOST/SMTPSVC/1').Stop() #to ... you guess
The weirdest thing is that you control smtp service through AD, but it works.
And of course this should be run elevated.
If you have several virtual SMTP servers, you may need to identify your server by index or by some property (e.g. .ConnectionTimeout) first.
in c# you can write:
enum StatusVirtualServerSMTP
{
Started = 2,
Stopped = 4
}
DirectoryEntry dir = new DirectoryEntry("IIS://localhost/SMTPSVC/1");
if (Convert.ToInt32(dir.Properties["SERVERSTATE"].Value) == (int)StatusVirtualServerSMTP.Stopped)
{
dir.Properties["SERVERSTATE"].Value = (int)StatusVirtualServerSMTP.Started;
dir.CommitChanges();
}

Categories