Latency timeout using CosmosDB from Android Xamarin - mongodb

I am developing an app using Xamarin using Visual Studio for Mac.
I am writing C# to target both iOS and Android.
We are also using CosmosDB on Microsoft Azure.
The problem comes about when trying to get Android to access CosmosDB. Please note that I am using the Mongo API for Cosmos.
The error message I get in Android is as follows:
A timeout occured after 30000ms selecting a server using
CompositeServerSelector{ Selectors = ReadPreferenceServerSelector{
ReadPreference = { Mode : Primary } }, LatencyLimitingServerSelector{
AllowedLatencyRange = 00:00:00.0150000 } }. Client view of cluster
state is { ClusterId : "2", ConnectionMode : "ReplicaSet", Type :
"ReplicaSet", State : "Disconnected", Servers : [{ ServerId: "{
ClusterId : 2, EndPoint :
"Unspecified/aspire-cosmosdb.documents.azure.com:10255" }", EndPoint:
"Unspecified/aspire-cosmosdb.documents.azure.com:10255", State:
"Disconnected", Type: "Unknown" }] }.
This is my code:
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using MongoDB.Driver;
string dsn = "mongodb://myusername:mypassword#mycosmosname.documents.azure.com:10255/?ssl=true&replicaSet=globaldb";
string databaseName = "mydatabasename";
Debug.WriteLine("Initializing Cosmos DB!");
MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(dsn));
settings.SslSettings = new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
var mongoClient = new MongoClient(settings);
var db = mongoClient.GetDatabase(databaseName);
var databases = (await mongoClient.ListDatabasesAsync()).ToList();
foreach (var d in databases)
{
Debug.WriteLine(d.AsBsonDocument);
}
This works 100% fine on xamarin.ios. Connects everytime. The code is pretty much copy and paste from the CosmosDB Quick start on the Azure Portal. I have also taken this code and put it in a C# Console app and it ALSO works. However, same code doesn't work on Android. Why?
I've tried this both on the Android simulator and a real Android device and both times get this 30 second timeout. I've also enabled the Internet permission on Android, but no joy. Please help!
I've referenced the latest packages via Nuget at the time of writing:
MongoDB.Driver -2.4.4
MongoDB.Driver.Core - 2.4.4
MongoDB.Bson - 2.4.4
Note: I have obfuscated the personal details from the dsn but it should show you the rough format of it. The actual dsn is a direct copy and paste of the cosmosdb dsn connection string from the Azure portal.

Okay so after a LOT of headbanging, the solution is fairly simple.
CosmosDB ONLY supports TLS 1.2.
Go into your Droid project settings (Right click on project > Options) and go to Android Build > SSL/TLS Implementation.
Mine was set to 'default'. I guess 'default' at the time of writing does not support TLS 1.2. At least not on Xamarin for the Mac anyway. This is quite a gotcha. Switch it over to Native TLS 1.2+ and magically it just works! Now able to connect to CosmosDB via Android.

Related

AWS Personalize - HPO - solutionConfig

I have incorporated the solutionConfig as part of HPO in AWS personlaize service.
solutionConfig = {
"optimizationObjective": {
"itemAttribute": "ITEM_WEIGHT",
"objectiveSensitivity": "HIGH"
},
I am getting the following error
Unknown parameter in solutionConfig: "optimizationObjective", must be one of: eventValueThreshold, hpoConfig, algorithmHyperParameters, featureTransformationParameters, autoMLConfig]
It looks like you may be using a version of the AWS SDK that does not include support for the optimizationObjective parameter of the solution config. Check to make sure that you're using the latest version of the AWS SDK.

Setup Apereo Cas Management integrated with CAS server

I want to install Apero Cas Management (verison 6.0) and integrate it with Cas Server (version 6.0).
I have installed following these step:
Step 1: I installed Cas Server
I checked it with REST API. It worked.
My server stays at http://203.162.141.7:8080
And this is configuration of my Cas server. I put this config at /etc/cas/config. Here is my file cas.properties file
cas.server.name=http://203.162.141.7:8080
cas.server.prefix=${cas.server.name}/cas
logging.config: file:/etc/cas/config/log4j2.xml
server.port=8080
server.ssl.enabled=false
cas.serviceRegistry.initFromJson=false
cas.serviceRegistry.json.location=file:/etc/cas/services-repo
cas.authn.oauth.grants.resourceOwner.requireServiceHeader=true
cas.authn.oauth.userProfileViewType=NESTED
cas.authn.policy.requiredHandlerAuthenticationPolicyEnabled=false
cas.authn.attributeRepository.stub.attributes.email=casuser#example.org
#REST API JSON
cas.rest.attributeName=email
cas.rest.attributeValue=.+example.*
Step 2: I installed Cas-management-overlay
I put my cas-management-overlay's config file a /etc/cas/config too. Here is my management.properties file
cas.server.name=http://203.162.141.7:8080
cas.server.prefix=${cas.server.name}/cas
mgmt.serverName=http://203.162.141.7:8088
mgmt.adminRoles[0]=ROLE_ADMIN
mgmt.userPropertiesFile=file:/etc/cas/config/users.json
server.port=8088
server.ssl.enabled=false
logging.config=file:/etc/cas/config/log4j2-management.xml
And my here is users.json file
{
"casuser" : {
"#class" : "org.apereo.cas.mgmt.authz.json.UserAuthorizationDefinition",
"roles" : [ "ROLE_ADMIN" ]
}
}
Then I run ./build.sh, and it shows me that
Finally, I access this link to open cas-management http://203.162.141.7:8088/cas-management, but the it redirects to this url http://203.162.141.7:8080/cas/login?service=http%3A%2F%2F203.162.141.7%3A8088%2Fcas-management%2F and shows this error below
I don't know where I have gone wrong.
I think since you haven't told the management webapp about the location of the service registry, it can't add itself as a registered service.
Manually add a registered service for http://203.162.141.7:8088/cas-management and you should be able to log in to the management app at that point.
Here is my answer for cas-management register file name /etc/cas/services-repo/casManagement-1.json
{
"#class" : "org.apereo.cas.services.RegexRegisteredService",
"serviceId":"^https://domain:8088/cas-management.+",
"name" : "casManagement",
"id" : 1,
"evaluationOrder" : 1,
"allowedAttributes":["cn","mail"]
}

Unable to download embedded MongoDB, behind proxy, using automatic configuration script

I have a Spring Boot project, built using Maven, where I intend to use embedded mongo db. I am using Eclipse on Windows 7.
I am behind a proxy that uses automatic configuration script, as I have observed in the Connection tab of Internet Options.
I am getting the following exception when I try to run the application.
java.io.IOException: Could not open inputStream for https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip
at de.flapdoodle.embed.process.store.Downloader.downloadInputStream(Downloader.java:131) ~[de.flapdoodle.embed.process-2.0.1.jar:na]
at de.flapdoodle.embed.process.store.Downloader.download(Downloader.java:69) ~[de.flapdoodle.embed.process-2.0.1.jar:na]
....
MongoDB gets downloaded just fine, when I hit the following URL in my web browser:
https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip
This leads me to believe that probably I'm missing some configuration in my Eclipse or may be the maven project itself.
Please help me to find the right configuration.
What worked for me on a windows machine:
Download the zip file (https://downloads.mongodb.org/win32/mongodb-win32-i386-3.2.2.zip)
manually and put it (not unpack) into this folder:
C:\Users\<Username>\.embedmongo\win32\
Indeed the problem is about your proxy (a corporate one I guess).
If the proxy do not require authentication, you can solve your problem easily just by adding the appropriate -Dhttp.proxyHost=... and -Dhttp.proxyPort=... (or/and the same with "https.[...]") as JVM arguments in your eclipse junit Runner, as suggested here : https://github.com/learning-spring-boot/learning-spring-boot-2nd-edition-code/issues/2
One solution to your problem is to do the following.
Download MongoDB and place it on a ftp server which is inside your corporate network (for which you would not need proxy).
Then write a configuration in your project like this
#Bean
#ConditionalOnProperty("mongo.proxy")
public IRuntimeConfig embeddedMongoRuntimeConfig() {
final Command command = Command.MongoD;
final IRuntimeConfig runtimeConfig = new RuntimeConfigBuilder()
.defaults(command)
.artifactStore(new ExtractedArtifactStoreBuilder()
.defaults(command)
.download(new DownloadConfigBuilder()
.defaultsForCommand(command)
.downloadPath("your-ftp-path")
.build())
.build())
.build();
return runtimeConfig;
}
With the property mongo.proxy you can control whether Spring Boot downloads MongoDB from your ftp server or from outside. If it is set to true then it downloads from the ftp server. If not then it tries to download from the internet.
The easiest way seems to me to customize the default configuration:
#Bean
DownloadConfigBuilderCustomizer mongoProxyCustomizer() {
return configBuilder -> {
configBuilder.proxyFactory(new HttpProxyFactory(host, port));
};
}
Got the same issue (with Spring Boot 2.6.1 the spring.mongodb.embedded.version property is mandatory).
To configure the proxy, I've added the configuration bean by myself:
#Value("${spring.mongodb.embedded.proxy.domain}")
private String proxyDomain;
#Value("${spring.mongodb.embedded.proxy.port}")
private Integer proxyPort;
#Bean
RuntimeConfig embeddedMongoRuntimeConfig(ObjectProvider<DownloadConfigBuilderCustomizer> downloadConfigBuilderCustomizers) {
Logger logger = LoggerFactory.getLogger(this.getClass().getPackage().getName() + ".EmbeddedMongo");
ProcessOutput processOutput = new ProcessOutput(Processors.logTo(logger, Slf4jLevel.INFO), Processors.logTo(logger, Slf4jLevel.ERROR), Processors.named("[console>]", Processors.logTo(logger, Slf4jLevel.DEBUG)));
return Defaults.runtimeConfigFor(Command.MongoD, logger).processOutput(processOutput).artifactStore(this.getArtifactStore(logger, downloadConfigBuilderCustomizers.orderedStream())).isDaemonProcess(false).build();
}
private ExtractedArtifactStore getArtifactStore(Logger logger, Stream<DownloadConfigBuilderCustomizer> downloadConfigBuilderCustomizers) {
de.flapdoodle.embed.process.config.store.ImmutableDownloadConfig.Builder downloadConfigBuilder = Defaults.downloadConfigFor(Command.MongoD);
downloadConfigBuilder.progressListener(new Slf4jProgressListener(logger));
downloadConfigBuilderCustomizers.forEach((customizer) -> {
customizer.customize(downloadConfigBuilder);
});
DownloadConfig downloadConfig = downloadConfigBuilder
.proxyFactory(new HttpProxyFactory(proxyDomain, proxyPort)) // <--- HERE
.build();
return Defaults.extractedArtifactStoreFor(Command.MongoD).withDownloadConfig(downloadConfig);
}
In my case, I had to add the HTTPS corporate proxy to Intellij Run Configuration.
Https because it was trying to download:
https://downloads.mongodb.org/win32/mongodb-win32-x86_64-4.0.2.zip
application.properties:
spring.data.mongodb.database=test
spring.data.mongodb.port=27017
spring.mongodb.embedded.version=4.0.2
Please keep in mind this is a (DEV) setup.

authentication with Xamarin. Android and Microsoft.Azure.Mobile.Client Microsoft provider error

I had a code that worked unlit few days ago: this is an xamarin.android activity code
[Activity(Label = "AuthSample", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
Button login;
//Mobile Service Client reference
private MobileServiceClient client;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Create the Mobile Service Client instance, using the provided
// Mobile Service URL and key
client = new MobileServiceClient("https://XXXXXXX.azurewebsites.net");
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
login = FindViewById<Button>(Resource.Id.buttonLoginUser);
login.Click += onLoginClick;
}
private async void onLoginClick(object sender, EventArgs e)
{
// Load data only after authentication succeeds.
if (await Authenticate())
{
}
}
// Define a authenticated user.
private MobileServiceUser user;
private async Task<bool> Authenticate()
{
var success = false;
try
{
// Sign in with Microsoft login using a server-managed flow.
user = await client.LoginAsync(this,
MobileServiceAuthenticationProvider.MicrosoftAccount);
CreateAndShowDialog(string.Format("you are now logged in - {0}",
user.UserId), "Logged in!");
success = true;
}
catch (Exception ex)
{
CreateAndShowDialog(ex, "Authentication failed");
}
return success;
}
private void CreateAndShowDialog(Exception exception, String title)
{
CreateAndShowDialog(exception.Message, title);
}
private void CreateAndShowDialog(string message, string title)
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.SetMessage(message);
builder.SetTitle(title);
builder.Create().Show();
}
}
i did all the instruction in the tutorial.
the LoginAsync redirect me to the Microsoft login page, i am able to authenticate and after a successful authentication i get this error : "the page cannot be displayed because an internal server error has occured"
i am working with 3.1 azure sdk version
According to your description, I assumed that you could follow the steps below to troubleshoot this issue.
For Node.js backend
You could leverage App Service Editor or kudu for create the iisnode.yml file under root folder (D:\home\site\wwwroot) if not exists. Then add the following settings for enable logging to debug a Node.js web app in azure app service:
loggingEnabled: true
logDirectory: iisnode
Additionally, here is a similar issue about enable node.js logging, you could refer to it. Also, for more details about kudu and app service editor, you could refer to here.
For C# backend
you could edit App_Start\Startup.MobileApp.cs file and configure the IncludeErrorDetailPolicy as follows for capturing the error details:
HttpConfiguration config = new HttpConfiguration();
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
For a simple way, you could access https://{your-app-name}.azurewebsites.net/.auth/login/{provider-name} via the browser, then check the detailed error message for locating the specific error.
UPDATE:
Based on your address, I checked your app and found I could log with my Microsoft Account via the browser. Then I checked with your table endpoint and found the follow error:
https://{your-app-name}.azurewebsites.net/tables/todoitem?ZUMO-API-VERSION=2.0.0
message: "An error has occurred.",
exceptionMessage: "A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 52 - Unable to locate a Local Database Runtime installation. Verify that SQL Server Express is properly installed and that the Local Database Runtime feature is enabled.)",
exceptionType: "System.Data.SqlClient.SqlException",
As I known, when following the quickstart to create the data store for your backend, downloading the C# backend, then deploy the backend to moible app. At this point, your created connection string via azure portal would not be exposed to your ASP.NET application, and the default connection string would use the localdb, you need to edit the Web.config file before deploying to azure mobile app as follows:
<connectionStrings>
<add name="MS_TableConnectionString" connectionString="Data Source=tcp:{your-sqlserver-name}.database.windows.net,1433;Initial Catalog={db-name};User ID={user-id};Password={password}" providerName="System.Data.SqlClient" />
</connectionStrings>
Or configure the connection string when deploy your app to azure mobile app via VS as follows:
It seems that there was a problem in azure or in Microsoft authentication.
after two days of frustration everything just started to work again!!

Debugging a crashing language server

I apologize if I'm a bit low on details here, but the main issue is actually trying to find the problem with my code. I'm updating an older extension of my own that was based on the Language Server example (https://code.visualstudio.com/docs/extensions/example-language-server). I've run into an issue where when I run the client part of my code using F5, and the debug window fires, I get:
The CSSLint Language Client server crashed 5 times in the last 3 minutes. The server will not be restarted.
Ok... so... here's the thing. The problems view in my extension client code shows nothing. DevTools for that Code window shows nothing.
The problems view for my server code shows nothing. DevTools, ditto.
For the Extension Developer Host instance, DevTools does show this:
messageService.ts:126 The CSSLint Language Client server crashed 5 times in the last 3 minutes. The server will not be restarted.e.doShow # messageService.ts:126
But I can't dig into the details to find a bug. So the question is - assuming that my server code is failing, where exactly would the errors be available?
Here is what I usually do to track server crashes down (I assume your server is written in JavaScript / TypeScript).
Use the following server options:
let serverModule = "path to your server"
let debugOptions = { execArgv: ["--nolazy", "--debug=6009"] };
let serverOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions}
};
Key here is to use the TransportKind.ipc. Errors that happen in the server and printed to stdio will then show in the output channel associated to your server (the name of the output channel is the name passed to the LanguageClient)
If you want to debug the server startup / initialize sequence you can change the debugOptions to:
let debugOptions = { execArgv: ["--nolazy", "--debug-brk=6009"] };
If the extension is started in debug mode (e.g. for example launched from VS Code using F5) then the LanguageClient automatically starts the server in debug mode. If the extension is started normally (for example as a real extension in VS Code) then the server is started normally as well.
To make this all work you need a latest version of the LSP node npm module both for server can client (e.g. 2.6.x)