Initialize MongoClient with MongoClientSettings in C# - c#

I'm trying to initialize the MongoClient from the Mongo 2.0 driver as follows:
MongoClientSettings settings = new MongoClientSettings();
settings.WaitQueueSize = int.MaxValue;
settings.WaitQueueuTimeout = new TimeSpan(0,2,0);
settings.MinConnectionPoolSize = 1;
settings.MaxConnectionPoolSize = 25;
settings.Server = new MongoServerAddress("mongodb://localhost");
client = new MongoClient(settings)
However, when I now try to insert a document with this code:
db = client.GetDatabase("local");
col = db.GetCollection<BsonDocument>(collectionName);
col.InsertOneAsync(new BsonDocument().Add(new BsonElement("id",BsonValue.Create(1)))).Wait();
It doesn't do anything. It doesn't get inserted, and no error message (although after a while a first chance exception of System.Timeout appears in the output). If I initialize the client with
client = new MongoClient("mongodb://localhost")
It does work and uploads the document as intended.
I want the client to be able to handle a very high write throughput, so I tried these settings first. Did I set some of the settings wrong or is there a different problem?
EDIT: After some more testing, it is indeed a System.Timeout exception I'm getting.

I could reproduce the problem, only in my error message, there is some much more helpful information buried somewhere in about 40 lines of text:
No such host is known
It turns out that MongoServerAddress only expects the hostname, not the protocol:
settings.Server = new MongoServerAddress("localhost");

Related

OPC UA Certificate key doesn't meet minimum length requirement

I am using the OPCFoundation/UA-.NETStandard components (version 1.4.371.60) to communicate with an OPC Server in one of our products for testing purposes. The whole system is in-house and on a separate network segment so security is not an issue in this case.
Recently a new problem has arisen with certain product versions so that I cannot connect.
I always connect with SecurityMode=none & SecurityPolicy=none. The error now is OpcException: Certificate validation failed with error code 0x8114000 and the description says that the minimum length requirement of 2048 was not met.
I have used UaExpert to connect to the same server and that is successful but I have no idea which library it uses.
I have tried overriding the following attributes but with no success.
application.ApplicationConfiguration.SecurityConfiguration.AutoAcceptUntrustedCertificates = true;
application.ApplicationConfiguration.SecurityConfiguration.MinimumCertificateKeySize = 1024;
application.ApplicationConfiguration.SecurityConfiguration.RejectSHA1SignedCertificates = false;
Am I missing something? Can I override and ignore this error somehow?
What you tried looks good.
Maybe there is a *.config.xml file somewhere that override the MinimumCertificateKeySize value to the current default value.
Another solution will be to create a new certificate for the OPC UA Server to be sure it is not using a deprecated key size ;)
I have managed to get it working as I want. The problem was in the way I was initialising the components. I had created a new CertificateValidator and then set up the ApplicationConfiguration (including the MinimumCertificateKeySize). What I needed to do was to Update the validator with the application configuration as it is the validator which needs to know the min cert size.
var certificateValidator = new CertificateValidator();
certificateValidator.CertificateValidation += (sender, eventArgs) =>
{
// handle event
};
// Build the application configuration
var applicationConfiguration = new ApplicationConfiguration
{
ApplicationUri = server.ToString(),
ApplicationName = "UaClientTest",
ApplicationType = ApplicationType.Client,
CertificateValidator = certificateValidator,
SecurityConfiguration = new SecurityConfiguration
{
AutoAcceptUntrustedCertificates = true,
MinimumCertificateKeySize=1024, /* Default is 2048 but steuerung only has 1024 */
RejectSHA1SignedCertificates=false
},
// more config here...
};
// IMPORTANT: update config in cert handling
certificateValidator.Update(applicationConfiguration);

C# OpenTelemetry against Jaeger works in Simple but not Batch

Have a pretty much working environment to use for tracing, OpenTelemetry against Jaeger Tracing.
I sort of read that Batch for process is the preferred way then Simple. How ever with in .Net Framework 4.8 Batch dose not seem to give any results being logged.
I did a capture of packet data with Wireshark. Nothing happens when running in Batch.
Is there something with this configuration that is missing to have this as ExportProcessorType.Batch instead of ExportProcessorType.Simple?
public TracerProvider GetTracerProvider(string host, int port)
{
BackendServiceResource = ResourceBuilder.CreateDefault()
.AddService(Process.GetCurrentProcess().ProcessName)
.AddAttributes(new[]
{
new KeyValuePair<string, object>("MachineName", Environment.MachineName),
new KeyValuePair<string, object>("UserName", Environment.UserName),
});
return Sdk.CreateTracerProviderBuilder()
.SetResourceBuilder(BackendServiceResource)
.SetSampler(new AlwaysOnSampler())
.SetErrorStatusOnException(true)
.AddSource(ActivitySource.Name)
.AddConsoleExporter()
.AddJaegerExporter(jeager =>
{
jeager.AgentHost = host;
jeager.AgentPort = port;
jeager.MaxPayloadSizeInBytes = 4096;
jeager.ExportProcessorType = ExportProcessorType.Simple;
jeager.BatchExportProcessorOptions = new BatchExportProcessorOptions<Activity>()
{
MaxQueueSize = 2048,
ScheduledDelayMilliseconds = 5000,
ExporterTimeoutMilliseconds = 30000,
MaxExportBatchSize = 512,
};
})
.Build();
}
Thought I post a solution for this sort of issue.
The reason for these problems is because in some cases as application can close down before the process is fully completed. A solution for this is using and making sure that all gets completed before all is valid for closure.
You can read more about it more here https://github.com/open-telemetry/opentelemetry-dotnet/issues/2758

How does the offset for a topic work in Kafka (Kafka_net)

I have a basic producer app and a consumer app. if I run both and have both start consuming on their respective topics, I have a great working system. My thought was that if I started the producer and sent a message that I would be able to then start the consumer and have it pick up that message. I was wrong.
Unless both are up and running, I lose messages (or they do not get consumed).
my consumer app looks like this for comsuming...
Uri uri = new Uri("http://localhost:9092");
KafkaOptions options = new KafkaOptions(uri);
BrokerRouter brokerRouter = new BrokerRouter(options);
Consumer consumer = new Consumer(new ConsumerOptions(receiveTopic, brokerRouter));
List<OffsetResponse> offset = consumer.GetTopicOffsetAsync(receiveTopic, 100000).Result;
IEnumerable<OffsetPosition> t = from x in offset select new OffsetPosition(x.PartitionId, x.Offsets.Max());
consumer.SetOffsetPosition(t.ToArray());
IEnumerable<KafkaNet.Protocol.Message> msgs = consumer.Consume();
foreach (KafkaNet.Protocol.Message msg in msgs)
{
do some stuff here based on the message received
}
unless I have the code between the lines, it starts at the beginning every time I start the application.
What is the proper way to manage topic offsets so messages are consumed after a disconnect happens?
If I run
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic chat-message-reply-XXX consumer-property fetch-size=40000000 --from-beginning
I can see the messages, but when I connect my application to that topic, the consumer.Consume() does not pick up the messages it has not already seen. I have tried this with and without runing the above bat file to see if that makes any difference. When I look at the consumer.SetOffsetPosition(t.ToArray()) call (t specifically) it shows that the offset is the count of all messages for the topic.
Please help,
Set auto.offset.reset configuration in your ConsumerOptions to earliest. When the consumer group starts the consume messages, it will consume from the latest offset because the default value for auto.offset.reset is latest.
But I looked at kafka-net API now, it does not have a AutoOffsetReset property, and it seems pretty insufficient with its configuration in consumers. It also lacks documentation with method summaries.
I would suggest you use Confluent .NET Kafka Nuget package because it is owned by Confluent itself.
Also, why are calling GetTopicOffsets and setting that offset back again in consumer. I think when you configure your consumer, you should just start reading messages with Consume().
Try this:
static void Main(string[] args)
{
var uri = new Uri("http://localhost:9092");
var kafkaOptions = new KafkaOptions(uri);
var brokerRouter = new BrokerRouter(kafkaOptions);
var consumerOptions = new ConsumerOptions(receivedTopic, brokerRouter);
var consumer = new Consumer(consumerOptions);
foreach (var msg in consumer.Consume())
{
var value = Encoding.UTF8.GetString(msg.Value);
// Process value here
}
}
In addition, enable logs in your KafkaOptions and ConsumerOptions, they will help you a lot:
var kafkaOptions = new KafkaOptions(uri)
{
Log = new ConsoleLog()
};
var consumerOptions = new ConsumerOptions(topic, brokerRouter)
{
Log = new ConsoleLog()
});
I switched over to use Confluent's C# .NET package and it now works.

(WIN32: 1400 ERROR_INVALID_WINDOW_HANDLE) while Signing a CSR with a SmartCard

I am trying to generate a CSR from a smartcard using the CertEnroll::CX509CertificateRequestPkcs10 library. It works fine if I just run it at the beginning. However if I run the ADAL login flow before hand I get the following error.
CertEnroll::CX509CertificateRequestPkcs10::Encode: Invalid window handle. 0x80070578 (WIN32: 1400 ERROR_INVALID_WINDOW_HANDLE)
I looked into the error and it seems that it is cause when you call a window that no longer exist. Since I cant control what window the CertEnroll::CX509CertificateRequestPkcs10::Encode calls is there a way to clear the pointers or something to avoid this error?
for reference here is my enroll code
var request = new CX509CertificateRequestPkcs10();
request.Initialize(X509CertificateEnrollmentContext.ContextUser);
request.PrivateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_EXPORT_NONE;
request.PrivateKey.Length = 2048;
request.PrivateKey.ProviderName = "Microsoft Base Smart Card Crypto Provider";
request.PrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_SIGNING_FLAG;
request.PrivateKey.KeySpec = X509KeySpec.XCN_AT_KEYEXCHANGE;
request.PrivateKey.MachineContext = false;
if (!subjectName.StartsWith("CN="))
subjectName = $"CN={subjectName}";
var subjectEncoded = new CX500DistinguishedNameClass();
subjectEncoded.Encode(subjectName);
request.Subject = subjectEncoded;
request.Encode();
and here is my Authentication Code
result = authContext.AcquireTokenAsync(ResourceId, clientId, redirectUri, new PlatformParameters(PromptBehavior.Always));
result.Wait();
_userName = result.Result.UserInfo.DisplayableId;
return result.Result.AccessToken;
I was able to go around this by changing my Provider to the newer version and the KeySec to None (since this is required for the new Gen Storage provder):
request.PrivateKey.ProviderName = "Microsoft Smart Card Key Storage Provider";
request.PrivateKey.KeyUsage = X509PrivateKeyUsageFlags.XCN_NCRYPT_ALLOW_SIGNING_FLAG;
request.PrivateKey.KeySpec = X509KeySpec.XCN_AT_NONE;

Create security connection

I have win service that work with MQ.
But i want that it works using ssl channel and database with public/private keys(for that)
May you explain me how to do it.
P.S. I'm not very good at MQ
now i connect to MQ using this code
MQEnvironment.Hostname = ConfigurationManager.AppSettings["HostnameIN"];
MQEnvironment.Channel = ConfigurationManager.AppSettings["ChannelIN"];
MQEnvironment.Port = int.Parse(ConfigurationManager.AppSettings["PortIN"]);
Environment.SetEnvironmentVariable("MQCCSID", ConfigurationManager.AppSettings["MQCCSID"]);
var mqQueueManagerName = ConfigurationManager.AppSettings["QueueManagerNameIN"];
var mqQueueName = ConfigurationManager.AppSettings["QueueNameIN"];
const int openOptions = MQC.MQOO_BROWSE | MQC.MQOO_INPUT_AS_Q_DEF;
var qMgr = new MQQueueManager(mqQueueManagerName);
var getOptions = new MQGetMessageOptions();
and get all messages using this
using (var mqQueue = qMgr.AccessQueue(mqQueueName, openOptions))
{
try
{
//while (mqQueue.CurrentDepth>0)
while (true)
{
var message = new MQMessage();
//message.Version = 2;
getOptions.Options = MQC.MQGMO_WAIT | MQC.MQGMO_BROWSE_NEXT;
mqQueue.Get(message, getOptions);
mqMessages.Add(message);
}
}
In order to set up MQ to use SSL on the channel you're using, you don't need to make any application changes at all - you simply need to configure the channel you're using on the queue manager to require SSL. The libraries within the client, JVM, and the queue manager will handle establishing that secure connection for you. So in theory all you need to do is make the MQSC/MQ Explorer changes which will configure SSL on the channel.
Recommend you read the following page in the IBM knowledge center. It provides a number of scenarios for various methods of connecting a client securely to the queue manager:
http://www-01.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.sce.doc/q014220_.htm

Categories

Resources