Make dynamic request using Gatling - scala

I want to make a dynamic request using Gatling.
using Gatling we are getting to rest-API to which we are posting an SMS request I want that each request should be done with a different sent of mob no.
exec(http("Sms Delivery")
.post(s"/deliveries")
.body(StringBody(
s"""{ "template":
|{ "type":"inline", "inline":
| { "channels":
| "sms":{ "body":{ "layout":"{greeting}", "fragments":{ "greeting":{"en-US":"ABC123 Interested to hear about some jobs?"}}}} }} },
| "recipients":[ { "contactDetails":{ "mobileNumber" : "+1${Random.nextInt(123123123)}" } }],
| "requester": "${UUID.random.toString}"}""".stripMargin)).asJson
.check(status.is(202))
.check(jsonPath("$.messageId").ofType[String])
)
}
setUp(
scenario("Create message-Cmd")
.exec(createMessageServiceSms()).inject(
rampConcurrentUsers(0) to (6) during(1),
constantConcurrentUsers(5) during (testTime seconds)
)
)
Let suppose Gatling sends 100 requests the for all those requests my mob no remains the same for each request is same let say +12011705515.
However, I want all no. should be different.

The string is created only once, then parsed as Expression Language, which allows you to substitute in session attributes.
If you want custom functions like creating a UUID and calling Random.nextInt, you need to pass in a function to StringBody.
StringBody(_ =>
s"""{ "template":
|{ "type":"inline", "inline":
| { "channels":
| "sms":{ "body":{ "layout":"{greeting}", "fragments":{ "greeting":{"en-US":"ABC123 Interested to hear about some jobs?"}}}} }} },
| "recipients":[ { "contactDetails":{ "mobileNumber" : "+1${Random.nextInt(123123123)}" } }],
| "requester": "${UUID.random.toString}"}""".stripMargin)
)
The parameter that we discarded is the virtual user's Session.
Worth noting that you may have too few digits for the mobileNumber, but that's another issue than creating a dynamic request.

Related

JupyterHub - log current user

I use a custom logger to log who is currently doing any kind of stuff in Jupyterhub.
logging_config: dict = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"company": {
"()": lambda: MyFormatter(user=os.environ.get("JUPYTERHUB_USER", "Unknown"))
},
},
....
c.Application.logging_config = logging_config
Output:
{"asctime": "2022-06-29 14:13:43,773", "level": "WARNING", "name": "JupyterHub", "message": "Updating Hub route http://127.0.0.1:8081 \u2192 http://jupyterhub:8081", "user": "Unknown"
The logger itself works fine, but I am not able to log who was performing the action. In the Image I start, there is a JUPYTERHUB_USER env variable available. This seems to get passed from JupyterHub ( I don´t know how this is done exactly). But in JupyterHub I don´t have this variable available.
Is there a way to use it in JupyterHub, not just in the jupyterLab container?
This doesn't get you all the way there but it's a start - we add extra pod annotations/labels through KubeSpawner's extra_annotations using the cluster_options hook (see our helm chart for our complete daskhub setup):
dask-gateway:
gateway:
extraConfig:
optionHandler: |
from dask_gateway_server.options import Options, String, Select, Mapping, Float, Bool
from math import ceil
def cluster_options(user):
def option_handler(options):
extra_annotations = {
"hub.jupyter.org/username": user.name
}
default_extra_labels = {
"hub.jupyter.org/username": user.name,
}
return Options(
Select(
...
),
...,
handler=option_handler,
)
c.Backend.cluster_options = cluster_options
You can then poll pods with these labels to get real time usage. There may be a more direct way to do this though - not sure.

Azure Function App Push-OutputBinding Adding Subscription Information to JSON Output using Powershell

I have written several Azure Functions over the past year in both powershell and C#. I am currently writing an API that extracts rows from a Storage Account Table and returns that data in a JSON format.
The data pulls fine.
The data converts to JSON just fine.
A JSON formatted response is displayed - which is fine - but the Push-OutputBinding shoves in additional data to my original JSON data - account information, environment information, subscription information, and tenant information.
I've tried a number of different strategies for getting past this. I gave up on using C# to interact with the Tables because the whole Azure.Data.Tables and Cosmos tables packages are a hot mess with breaking changes and package conflicts and .Net 6 requirements for new functions apps. So please don't offer up a C# solution unless you have a working example with specific versions for packages, etc.
Here is the code:
Note that I have verified that $certData and $certJson properly formatted JSON that contain only the data I want to return.
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with query parameters or the body of the request.
$filter = $Request.Query.Filter
if (-not $filter) {
$filter = "ALL"
}
$certData = GetCerts $filter | ConvertTo-Json
#$certJson = $('{ "CertData":"' + $certData + '" }')
$body = "${CertData}"
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = [HttpStatusCode]::OK
ContentType = "application/json"
Body = $body
})
When I call the httpTrigger function, the response looks like this:
{ "CertData":"[
{
"Name": "MySubscriptionName blah blah",
"Account": {
"Id": "my user id",
"Type": "User",
....
},
"Environment": {
"Name": "AzureCloud",
"Type": "Built-in",
...
},
"Subscription": {
"Id": "SubscriptionID",
"Name": "SubscriptionName",
....
},
"Tenant": {
"Id": "TenandID",
"TenantId": "TenantId",
"ExtendedProperties": "System.Collections.Generic.Dictionary`2[System.String,System.String]",
...
},
"TokenCache": null,
"VersionProfile": null,
"ExtendedProperties": {}
},
{
"AlertFlag": 1,
"CertID": "abc123",
"CertName": "A cert Name",
"CertType": "an assigned cert type",
"DaysToExpire": 666,
"Domain": "WWW.MYDOMAIN.COM",
"Expiration": "2033-10-04T21:31:03Z",
"PrimaryDomain": "WWW.MYDOMAIN.COM",
"ResourceGroup": "RANDOM-RESOURCES",
"ResourceName": "SOMERESOURCE",
"Status": "OK",
"Subscription": "MYSUBSCRIPTIONNAME",
"Thumbprint": "ABC123ABC123ABC123ABC123ABC123",
"PartitionKey": "PARKEY1",
"RowKey": "ID666",
"TableTimestamp": "2022-02-03T09:00:28.7516797-05:00",
"Etag": "W/\"datetime'2022-02-03T14%3A00%3A28.7516797Z'\""
},
...
Not only does the returned values add data I don't want exposed, it makes parsing the return data that I do want to get when I make API calls problematic.
How do I get rid of the data added by the Push-OutputBinding?
Was able to resolve issue by modifying run.ps1 as follows:
using namespace System.Net
# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)
# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."
# Interact with query parameters or the body of the request.
$filter = $Request.Query.Filter
if (-not $filter) {
$filter = "ALL"
}
$certData = ( GetCerts $filter | Select-Object -Skip 1 )
#write-information $certData | Format-List
# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]#{
StatusCode = [HttpStatusCode]::OK
Body = $certData
})

How to create a schedule in pagerduty using restApi and python

When through the documentation of pagerduty was but still not able to understand what parameters to send in the request body and also facing trouble in understanding how to make the api request.If any one can share the sample code on making a pagerduty schedule that would help me alot.
Below is the sample code to create schedules in PagerDuty.
Each list can have multiple items (to add more users / layers)
import requests
url = "https://api.pagerduty.com/schedules?overflow=false"
payload={
"schedule": {
"schedule_layers": [
{
"start": "<dateTime>", # Start Time of layer | "start": "2021-01-01T00:00:00+05:30",
"users": [
{
"user": {
"id": "<string>", # ID of user to add in layer
"summary": "<string>",
"type": "<string>", # "type": "user"
"self": "<url>",
"html_url": "<url>"
}
}
],
"rotation_virtual_start": "<dateTime>", # Start of layer | "rotation_virtual_start": "2021-01-01T00:00:00+05:30",
"rotation_turn_length_seconds": "<integer>", # Layer rotation, for multiple user switching | "rotation_turn_length_seconds": <seconds>,
"id": "<string>", # Auto-generated. Only needed if you want update and existing Schedule Layer
"end": "<dateTime>", # End Time of layer | "end": "2021-01-01T00:00:00+05:30",
"restrictions": [
{
"type": "<string>", # To restrict shift to certain timings Weekly daily etc | "type": "daily_restriction",
"duration_seconds": "<integer>", # Duration of layer | "duration_seconds": "300"
"start_time_of_day": "<partial-time>", #Start time of layer | "start_time_of_day": "00:00:00",
"start_day_of_week": "<integer>"
}
],
"name": "<string>", # Name to give Layer
}
]
"time_zone": "<activesupport-time-zone>", # Timezone to set for layer and its timings | "time_zone": "Asia/Kolkata",
"type": "schedule",
"name": "<string>", # Name to give Schedule
"description": "<string>",# Description to give Schedule
"id": "<string>", # Auto-generated. Only needed if you want update and existing Schedule Layer
}
}
headers = {
'Authorization': 'Token token=<Your token here>',
'Accept': 'application/vnd.pagerduty+json;version=2',
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, json=payload)
print(response.text)
Best way to do this is to get the postman collection for PagerDuty and edit the request as per your liking. Once you get a successful response, convert that into code using the inbuilt feature of postman.
Using PagerDuty API for scheduling is not easy. Creating new schedule is okaish, but if you decide to update schedule - it is definitely not trivial. You'll probably occur bunch of limitation: number of restriction per layer, must reuse current layers, etc.
As option you can use a python library pdscheduling https://github.com/skrypka/pdscheduling

Get the groups of a customeruser in otrs

I am extending OTRS with an app and need to get the groups a customeruser is in. I want to do this by communicating with the SessionGet-Endpoint (https://doc.otrs.com/doc/api/otrs/6.0/Perl/Kernel/GenericInterface/Operation/Session/SessionGet.pm.html)
The Endpoint for SessionGet returns a lot of information about the user but not the groups he is in. I am not talking about agents who can login to the backend of otrs but customerusers.
I am using OTRS 6 because it was the only one available in docker. I created the REST-endpoints in the backend and everything works well. There is a new functionality why I need to get the information about the groups.
Had a look at the otrs system-config but could not figure out if it is possible to include this information in the response.
Although I am a programmer, I did not want to write perl because of ... reasons.
I had a look at the file which handles the incoming request at /opt/otrs/Kernel/GenericInterface/Operation/Session/SessionGet.pm and traced the calls to the actual file where the information is collected from the database in /opt/otrs/Kernel/System/AuthSession/DB.pm. In line 169 the SQL-statement is written so it came to my mind that I just can extend this to also get the information of the groups, because, as I said, I did not want to write perl...
A typical response from this endpoint looks like this:
{
"SessionData": [
{
"Value": "2",
"Key": "ChangeBy"
},
{
"Value": "2019-06-26 13:43:18",
"Key": "ChangeTime"
},
{
"Value": "2",
"Key": "CreateBy"
},
{
"Value": "2019-06-26 13:43:18",
"Key": "CreateTime"
},
{
"Value": "XXX",
"Key": "CustomerCompanyCity"
},
{
"Value": "",
"Key": "CustomerCompanyComment"
}
...
}
A good thing would be to just insert another Value-Key-pair with the IDs of the groups. The SQL-statement queries only one table $Self->{SessionTable} mostly called otrs.sessions.
I used the following resources to create a SQL-statement which extends the existing SQL-statement with the needed information. You can find it here:
$DBObject->Prepare(
SQL => "
(
SELECT id, data_key, data_value, serialized FROM $Self->{SessionTable} WHERE session_id = ? ORDER BY id ASC
)
UNION ALL
(
SELECT
(
SELECT MAX(id) FROM $Self->{SessionTable} WHERE session_id = ?
) +1
AS id,
'UserGroupsID' AS data_key,
(
SELECT GROUP_CONCAT(DISTINCT group_id SEPARATOR ', ')
FROM otrs.group_customer_user
WHERE user_id =
(
SELECT data_value
FROM $Self->{SessionTable}
WHERE session_id = ?
AND data_key = 'UserID'
ORDER BY id ASC
)
)
AS data_value,
0 AS serialized
)",
Bind => [ \$Param{SessionID}, \$Param{SessionID}, \$Param{SessionID} ],
);
Whoever needs to get the groups of a customeruser can replace the existing code with the one provided. At least in my case it works very well. Now, I get the expected key-value-pair:
{
"Value": "10, 11, 6, 7, 8, 9",
"Key": "UserGroupsID"
},
I used the following resources:
Adding the results of multiple SQL selects?
Can I concatenate multiple MySQL rows into one field?
Add row to query result using select
Happy coding,
Nico

Requesting help to parse a string

I am using Invoke-WebRequest to get back an HtmlWebResponseObject object. I want to get the value of the ID field, when the description field matches a particular string (in this case, "server1"). There are hundreds of results returned by Invoke-WebRequest (so the string is super long) Given the sample below, how would I extract the ID?
{
"status": 200,
"data": [
{
"nextRecipient": 0,
"clearSent": true,
"lastSentNotificationOn": 0,
"netscanVersion": "0",
"suppressAlertClear": "false",
"build": "19000",
"lastSentNotificationOnLocal": "",
"id": 6,
"resendIval": 15,
"watchdogUpdatedOn": "2016-04-11 10:28:02 MDT",
"escalatingChainId": 6,
"description": "domain\server1",
"ackComment": "",
"credential2": "",
"updatedOn": 1460392096,
"updatedOnLocal": "2016-04-11 10:28:16 MDT",
"agentConf": "product.code={guid}\r\n# Installer version, Shall not be modified\r\ninstaller.version=0001\r\n\r\n# Generated by Agent Configuration Wizard\r\nserver=url\r\ncompany=company\r\nid=6\r\ncredential==cred\r\n\r\n# logger settings. Set logger.size to 0 to no limitation on logger size, otherwise, size limited to Mbytes specified by that\r\nlogger.output=console\r\nlogger.logfile=\r\nlogger.size=64\r\nlogger.level=info\r\n\r\n#watchdog log level\r\nlogger.watchdog=info\r\n# for each component, add more detailed control here\r\n# e.g. \r\n# logger.level.controller=debug\r\n#\r\n# if not set, it will use default log level, i.e. value of logger.level\r\n#\r\n\r\n#if agent shall watch watchdog, default to false\r\nagentmonitorwatchdog=true\r\n\r\n#whether watchdog upgrades agent, default to true\r\nagent.autoupgrade=true\r\n\r\n#service connection timeouts. Default to 5 seconds for connecting and 30 seconds for sending / reading feeds from server\r\nservice.connect_timeout=5\r\nservice.read_timeout=30\r\n\r\n#SSL & Proxy settings\r\nssl.enable=true\r\nproxy.enable=false\r\nproxy.host= \r\nproxy.port=\r\nproxy.user=\r\nproxy.pass=\r\nproxy.exclude=\r\n\r\n#sbproxy settings\r\nsbproxy.address=127.0.0.1\r\nsbproxy.port=72\r\nsbproxy.logsize=64\r\nsbproxy.restartOn102=false\r\nsbproxy.pdhNoAuthentication=false\r\n\r\n#sbproxy connection pool settings\r\nsbproxy.pool.connections=50\r
Thanks.
Convert the response from a JSON string to an object and expand the relevant properties:
$response | ConvertFrom-Json |
Select-Object -Expand data |
Where-Object { $_.description -match 'server1' } |
Select-Object -Expand id