How to connect to other databases (1 to 15) than default database (0) in stackexchange redis? - redis

I have 3 applications pointing to single redis endpoint. I want to use separate redis database per application. But when I am trying to set defaultDatabase to 1 or 2 in ConfigurationOption it is still using database 0. I am using stackexchange redis. Code is as given below :
var configurationOptions = new ConfigurationOptions
{
EndPoints = { "myredis.redis.cache.windows.net" },
Password = "xxxxxxxxxxxxxxxxxxx",
Ssl = true,
ConfigurationChannel = "MyRedis",
ChannelPrefix = "MR",
DefaultDatabase = 1,
};
var connectionMultiplexer = ConnectionMultiplexer.Connect(configurationOptions);
var cacheClient = new StackExchangeRedisCacheClient(connectionMultiplexer, new JilSerializer(), database: 1);
Now adding new key to cache using ICacheClient
var user = new User()
{
Id = 100,
Name = "John Doe"
};
var response = cacheClient.Add("mykey", user);
Then retrieving added key from cache
var addedUser= cacheClient.Get<string>("mykey");
Is there anything I am doing wrong? Ideally as per stated in configuration options it should store keys to db1 but it is storing to db0 instead.

When you retrieve the database object, you should specify the database number. https://stackexchange.github.io/StackExchange.Redis/Basics.html#using-a-redis-database

Related

Routing Query Not Working in Azure IoT Hub Event Grid

I created a device simulator with the following code:
private static async void SendDeviceToCloudMessagesAsync()
{
while (true)
{
var tdsLevel = Rand.Next(10, 1000);
var filterStatus = tdsLevel % 2 == 0 ? "Good" : "Bad";
var waterUsage = Rand.Next(0, 500);
var currentTemperature = Rand.Next(-30, 100);
var motorStatus = currentTemperature >= 50 ? "Good" : "Bad";
var telemetryDataPoint = new
{
deviceId = DeviceId,
temperature = currentTemperature,
filter = filterStatus,
motor = motorStatus,
usage = waterUsage,
tds = tdsLevel
};
var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
var message = new Message(Encoding.UTF8.GetBytes(messageString));
message.ContentType= "application/json";
message.Properties.Add("Topic", "WaterUsage");
await _deviceClient.SendEventAsync(message);
Console.WriteLine("{0} > Sending message: {1}", DateTime.Now, messageString);
await Task.Delay(5000);
}
}
The output in Azure IoT Explorer is the following:
"body": {
"deviceId": "MyFirstDevice",
"temperature": 60,
"filter": "Bad",
"motor": "Good",
"usage": 302,
"tds": 457
},
"enqueuedTime": "Sun Jan 29 2023 13:55:51 GMT+0800 (Philippine Standard Time)",
"properties": {
"Topic": "WaterUsage"
}
}
I know what to filter in the Azure IoT Hub Message Routing to only filter out temperatures >= 50. The routing query: $body.body.temperature >= 50 does not work as shown below. Any idea on what should be the query?
I have used the following code which worked for me. Instead of using Encoding.UTF8.GetBytes, I have used Encoding.ASCII.GetBytes and explicitly set the ContentEncoding to UTF8 using the below code.
var messageString = JsonConvert.SerializeObject(telemetryDataPoint);
var message = new Message(Encoding.ASCII.GetBytes(messageString));
message.ContentEncoding = "utf-8";
message.ContentType = "application/json";
message.Properties.Add("Topic", "WaterUsage");
Even though the messages you notice in the Azure IoT explorer has the properties information, using Visual Studio Code's Start Monitoring Built-in end point option, you will notice the messages routed to the built in end point have a different format. Please refer the below images for details.
I have used the routing query $body.temperature >= 50 to route the messages to an end point. I could validate from the blob storage container end point that the messages received have the temperature greater than or equal to 50. Please find the below image of routed messages for reference

How to add Authentiction to WebApp with Pulumi

I am trying to add an authentication provider to a Pulumi WebApp but is totaly unclear to me how to achieve that. The class WebApp from package #pulumi/azure-native/web only offers the property identity but no property tho assign e.g. a Microsoft AD. Can anybody provide a hint on how to set this up?
There are some of the Pulumi Azure pre-requisites and have the appropriate permissions in your tenant and Azure subscription.
Follow the below steps to add the authentication to app service webapp with pulumi and deploy:
Creating the project:
Start by creating the application, and adding the AzureAD package we’ll need to create the Azure AD application registration.
pulumi new azure-csharp `
--name easyauth-webapp `
--description "azure ad secured app" `
--stack dev `
--config azure-native:location=eastus
dotnet add package Pulumi.AzureAD
We next need to update the contents of the pulumi.dev.yaml file to contain a few additional config items. Paste the following into the file:
config:
azure-native:location: eastus
azure-native:subscriptionId: UPDATE_ME
azure-native:tenantId: UPDATE_ME
easyauth-webapp:tenantId: UPDATE_ME
easyauth-webapp:ownerId: UPDATE_ME
easyauth-webapp:siteName: UPDATE_ME
easyauth-webapp:appRegistrationName: UPDATE_ME
You can set siteName and appRegistrationName to whatever you want.
The subscriptionId and tenantId should be set to the appropriate target’s for your Azure app service and Azure AD application registration, respectively.
The following commands may be helpful in retrieving these values:
# Get your user's id
az ad signed-in-user show --query objectId
# List all subscriptions (and their tenant) that you have access to
az account list
Deploy the website (with no security):
We’ll next create the website we want to deploy. We’re going to use the run from ZIP package functionality to deploy the contents of the wwwroot folder.
Create that folder and add some content to the index.htm file:
Ex:
<!-- wwwroot/index.htm -->
<html>
<head>
<title>A very secure app</title>
</head>
<body>
Hello EasyAuth with Pulumi!
</body>
</html>
Now we can deploy this file to Azure with Pulumi.
Modify the MyStack.cs file to contain the below code, which has been adapted from the Pulumi Function Stack example:
// MyStack.cs
using System;
using Pulumi;
using Pulumi.AzureAD;
using Pulumi.AzureAD.Inputs;
using Pulumi.AzureNative.Resources;
using Pulumi.AzureNative.Storage;
using Pulumi.AzureNative.Storage.Inputs;
using Pulumi.AzureNative.Web;
using Pulumi.AzureNative.Web.Inputs;
class MyStack : Stack
{
public MyStack()
{
var config = new Pulumi.Config();
var tenantId = config.Require("tenantId");
var ownerId = config.Require("ownerId");
var siteName = config.Require("siteName");
var appRegistrationName = config.Require("appRegistrationName");
var rg = new ResourceGroup($"RG-{siteName}");
var storageAccount = new StorageAccount("storageaccount", new StorageAccountArgs
{
ResourceGroupName = rg.Name,
Kind = "StorageV2",
Sku = new SkuArgs
{
Name = SkuName.Standard_LRS,
},
});
var appServicePlan = new AppServicePlan("appserviceplan", new AppServicePlanArgs
{
ResourceGroupName = rg.Name,
Kind = "App",
Sku = new SkuDescriptionArgs
{
Tier = "Basic",
Name = "B1",
},
});
var container = new BlobContainer("zips", new BlobContainerArgs
{
AccountName = storageAccount.Name,
PublicAccess = PublicAccess.None,
ResourceGroupName = rg.Name,
});
var blob = new Blob("appservice-blob", new BlobArgs
{
ResourceGroupName = rg.Name,
AccountName = storageAccount.Name,
ContainerName = container.Name,
Type = BlobType.Block,
Source = new FileArchive("wwwroot"),
});
var codeBlobUrl = SignedBlobReadUrl(blob, container, storageAccount, rg);
var app = new WebApp("app", new WebAppArgs
{
Name = siteName,
ResourceGroupName = rg.Name,
ServerFarmId = appServicePlan.Id,
SiteConfig = new SiteConfigArgs
{
AppSettings = {
new NameValuePairArgs{
Name = "WEBSITE_RUN_FROM_PACKAGE",
Value = codeBlobUrl,
}
},
}
});
this.Endpoint = app.DefaultHostName;
}
// From https://github.com/pulumi/examples/blob/master/azure-cs-functions/FunctionsStack.cs
private static Output<string> SignedBlobReadUrl(Blob blob, BlobContainer container, StorageAccount account, ResourceGroup resourceGroup)
{
return Output.Tuple<string, string, string, string>(
blob.Name, container.Name, account.Name, resourceGroup.Name).Apply(t =>
{
(string blobName, string containerName, string accountName, string resourceGroupName) = t;
var blobSAS = ListStorageAccountServiceSAS.InvokeAsync(new ListStorageAccountServiceSASArgs
{
AccountName = accountName,
Protocols = HttpProtocol.Https,
SharedAccessStartTime = "2021-01-01",
SharedAccessExpiryTime = "2030-01-01",
Resource = SignedResource.C,
ResourceGroupName = resourceGroupName,
Permissions = Permissions.R,
CanonicalizedResource = "/blob/" + accountName + "/" + containerName,
ContentType = "application/json",
CacheControl = "max-age=5",
ContentDisposition = "inline",
ContentEncoding = "deflate",
});
return Output.Format($"https://{accountName}.blob.core.windows.net/{containerName}/{blobName}?{blobSAS.Result.ServiceSasToken}");
});
}
[Output] public Output<string> Endpoint { get; set; }
}
We can now deploy the site and verify it has worked as intended:
pulumi up --stack dev
curl (pulumi stack --stack dev output Endpoint)
[
Securing the site:
To configure Easy Auth we first create an Azure AD application registration.
In this example I’m specifying AzureADMyOrg which restricts access to the tenant the application registration is deployed in. I’m also adding a RedirectUri that points at the Easy Auth middleware of the deployed site. A password is needed to use as a client secret (the web application being the client in this case).
Once the application registration is created we can add WebAppAuthSettings to our site. The example specifies no anonymous access (using RedirectToLoginPage), and connects the site to the application registration using the ClientId and ClientSecret (password).
Paste the below code just after the this.Endpoint... code in the above MyStack.cs:
// MyStack.cs
// After this.Endpoint = app.DefaultHostName;
var adApp = new Application("ADAppRegistration", new ApplicationArgs
{
DisplayName = appRegistrationName,
SignInAudience = "AzureADMyOrg",
Owners = new[] { ownerId },
Web = new ApplicationWebArgs
{
ImplicitGrant = new ApplicationWebImplicitGrantArgs
{
IdTokenIssuanceEnabled = true
},
RedirectUris = new System.Collections.Generic.List<string> { $"https://{siteName}.azurewebsites.net/.auth/login/aad/callback" }
}
}
);
var applicationPassword = new ApplicationPassword("appPassword", new ApplicationPasswordArgs
{
ApplicationObjectId = adApp.Id,
DisplayName = "Client secret for web app"
});
var allowedAudience = adApp.ApplicationId.Apply(id => $"api://{id}");
var authSettings = new WebAppAuthSettings("authSettings", new WebAppAuthSettingsArgs
{
ResourceGroupName = rg.Name,
Name = app.Name,
Enabled = true,
UnauthenticatedClientAction = UnauthenticatedClientAction.RedirectToLoginPage,
DefaultProvider = BuiltInAuthenticationProvider.AzureActiveDirectory,
ClientId = adApp.ApplicationId,
ClientSecret = applicationPassword.Value,
Issuer = $"https://sts.windows.net/{tenantId}/v2.0",
AllowedAudiences = new[] { allowedAudience },
});
We can now update the site, From the command line we can’t get much further than this.
But in a browser we’ll get redirected to complete the login flow and access the site.
pulumi up --stack dev
# Redirect to HTTPS
curl (pulumi stack --stack dev output Endpoint)
# Access denied
curl "https://$(pulumi stack --stack dev output Endpoint)"
Refer this Github link for pulumi samples.

How to pull data from Jenkins API to Google Sheet

I want to retrieve data via Jenkins API using Google Sheet Script and store it in Google Sheet
1) Pull Jenkins Job Builds using Jenkins API to Google Sheet - DONE
2) Store data to Google Sheet ???
(need only "builds.subBuilds.buildNumber" and "builds.subBuilds.duration" values)
(need to correct mistake in the script)
function getJenkinsBuilds() {
// get the jenkins job
var response = UrlFetchApp.fetch('http://jenkins.[domain].co/job/Build+Deploy/api/json', {
'method': 'get',
'muteHttpExceptions' : true,
'headers' : {'Authorization' : 'Basic [tokan]'},
});
// parse the json reply and return builds
var data = JSON.parse(response);
var builds = data["builds"];
Logger.log(builds);
return builds;
};
// store predefined parameters from builds in the spreadsheet
function setDataToTable() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Jenkins');
var cell = sheet.getRange("A1");
var rows = [['buildNumber','duration'],['','']]; // I GUESS THE MISTAKE IS HERE?
sheet.getRange(cell.getRow(), cell.getColumn(), rows.length, rows[0].length).setValues(rows);
}
Actual result:
Log shows retrieved array with Builds objects, i.e.:
[19-10-10 16:18:16:937 AEDT] [{number=2081, subBuilds=[{jobName=...
'Jenkins' spreadsheet is empty.
Expected result:
Store "builds.subBuilds.buildNumber" and "builds.subBuilds.duration" values
in the Google Sheet ('Jenkins' spreadsheet), i.e.:
buildNumber duration
123 15sec
456 16sec
... ...
I was able to make it working in the next way:
function getJenkinsBuilds()
{
// get jenkins builds
var response = UrlFetchApp.fetch('http://jenkins.[domain].co/job/Build+Deploy/api/json', {
'method': 'get',
'muteHttpExceptions' : true,
'headers' : {'Authorization' : 'Basic [token]'}
});
// parse the json reply
var data = JSON.parse(response);
var builds = data["builds"];
var number = data['builds'][0]['number'];
var url = data['builds'][0]['url'];
Logger.log(number);
Logger.log(url);
// fill in the spreadsheet with data
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('Jenkins');
var cell = sheet.getRange('A1');
var rows = [['BUILD']];
for (var i = 0; i < builds.length; i++)
{
var number = data['builds'][i]['number'];
var url = data['builds'][i]['url'];
rows.push(['=HYPERLINK("'+url+'","'+number+'")']);
Logger.log(number);
Logger.log(url);
sheet.getRange(cell.getRow(), cell.getColumn(), rows.length, rows[0].length).setValues(rows);
}
};

Using express-socket.io-session, no session data is available in subsequent requests

Here's my setup:
I have the session stuff in a file called session-middleware.js
var ExpressSession = require('express-session');
var RedisStore = require('connect-redis')(ExpressSession);
expires_in_x_days = 5;
expiration_date = new Date();
expiration_date.setDate(expiration_date.getDate() + expires_in_x_days);
var session = ExpressSession({
resave: false,
saveUninitialized: false,
store: new RedisStore(),
secret: process.env.SESSION_SECRET_KEY,
cookie: {
expires: expiration_date,
secure: false
}
});
module.exports = session;
In my bin/www file I load it into my app object.
var shared_session_middleware = require('express-socket.io-session');
var session_middleware = require('../session-middleware');
app.use(session_middleware);
io.use(shared_session_middleware(session_middleware, {
autoSave: true
}));
from what I can tell the configuration looks fine... and oddly this seemed to be working before.
When I go into redis, I can see a new session ID is being created for every request, and every refresh... I can load the session data in redis and see that the data I saved to it was persisted, but whenever I make a subsequent request... that data is no longer there
127.0.0.1:6379> keys *
1) "sess:2OjdEYYfmUmeMkJhfLAQHSKP6PQFrSsx"
2) "sess:lqVnA4dBun5J3Bk17lTkuKJmWQ4oCRCB"
3) "sess:OJrI2MzfSEaKMtUkHvBEwWbDZeBHJ5Q9"
4) "sess:Qd0NKKrlX0o0yu-f905NiqisFvSo4vWn"
5) "sess:D4CLLgMb3Q_LRzPLq_BIyvYKfLq7217e"
6) "sess:ZQE77OiW-F7XUro_XtBqgyp0gwwvae7b"
127.0.0.1:6379> key "sess:ZQE77OiW-F7XUro_XtBqgyp0gwwvae7b"
(error) ERR unknown command 'key'
127.0.0.1:6379> get "sess:ZQE77OiW-F7XUro_XtBqgyp0gwwvae7b"
"{\"cookie\":{\"originalMaxAge\":431985563,\"expires\":\"2019-08-08T19:44:38.188Z\",\"httpOnly\":true,\"path\":\"/\"},\"client_token\":\"a66af8647f2d9998bbe7e3acf00ea2a21fc74596\"}"

Round Robin Group over two different hosts is not working

I am trying to split load over more than one akka actor system.
Unfortunately the round robin group in not forwarding messages to remote workers. I can see that actor is activated, but there is no work done.
the full code is on github
Is there any other setting that I could miss in my configuration?
private void CreateRemoteCrawlerGroup()
{
var hostname = "374110044f24";
var hostname2 = "25b360699a27";
var remoteAddress2 = Address.Parse($"akka.tcp://DeployTarget#{hostname2}:8090");
var remoteScope2 = new RemoteScope(remoteAddress2);
var remoteCrawler1 =
Context.ActorOf(
Props.Create(() => new WebCrawlerActor(new AppSettingsConfiguration(), Self))
.WithRouter(new RoundRobinPool(2)) // new DefaultResizer(1, 2, messagesPerResize: 500)
.WithDispatcher("my-dispatcher")
.WithDeploy(Deploy.None.WithScope(remoteScope2)), "a");
var remoteAddress = Address.Parse($"akka.tcp://DeployTarget#{hostname}:8090");
var remoteScope = new RemoteScope(remoteAddress);
var remoteCrawler2 =
Context.ActorOf(
Props.Create(() => new WebCrawlerActor(new AppSettingsConfiguration(), Self))
.WithRouter(new RoundRobinPool(2)) // new DefaultResizer(1, 2, messagesPerResize: 500)
.WithDispatcher("my-dispatcher")
.WithDeploy(Deploy.None.WithScope(remoteScope)), "remoteCrawler01");
var workers = new List<string> { remoteCrawler1.Path.ToString(), remoteCrawler2.Path.ToString() };
var router = Context.ActorOf(Props.Empty.WithRouter(new RoundRobinGroup(workers)), "some-group");
_actorDictionary.Add("WebCrawlerActor", router);
}
the solution was switch to akka cluster and use clustr pool instead
var remoteEcho2 =
Context.ActorOf(
Props.Create(() => new WebCrawlerActor(new AppSettingsConfiguration(), Self))
.WithRouter(new ClusterRouterPool(new RoundRobinPool(5), new ClusterRouterPoolSettings(5, 1, true, "crawler"))), "WebCrawlerActor2a");
_actorDictionary.Add("WebCrawlerActor", remoteEcho2);