Get parameter and attributes of a class in .cc file - networking

The problem is: Several mobile elements(ME) are employed to gather sensory data from the field. first the nodes should be clusterd and some energy-riched CHs should be selected as rendezvous nodes(RN).sensor nodes deliver their data to RNs and finally the mobile elements should visit these RNs to gather data.
The main part of this work is Estimation of routing paths toward RNs.
1) how can I do clustering and determining the RNs?
2)how can I force mobile elements to pass my defined movement paths?
I used INET wireless showcases to simulate this problem.
first part: I don't know. Plz help!
as the second part of my problem( movement of ME) I did:
module MEpath extends AdhocHost
{
parameters:
#display("i=device/cellphone");
#class(MEpath);
mobilityType = "MassMobility";
}
network MyNet
{
parameters:
int numHost;
int numME;
string mediumType = default("IdealRadioMedium");
submodules:
visualizer: IntegratedCanvasVisualizer {
parameters:
#display("p=47,16");
}
configurator: IPv4NetworkConfigurator {
parameters:
#display("p=47,97");
}
radioMedium: <mediumType> like IRadioMedium {
parameters:
#display("p=55,271");
}
lifecycleController: LifecycleController {
parameters:
#display("p=34,176");
}
host[numHost]: AdhocHost {
parameters:
#display("p=222,300");
}
mobileHost[numME]: MEpath {
#display("p=296,207;i=device/pocketpc");
}
}
Is defining MEpath module correct or not? which class or .cc file should I change? what should I write in MEpath.cc?
maybe it is unusual but at all I have problem in working with omnet++ and inet manual. I couldn't find out which attribute and parameter of a class should I change? !

Ad. 2. You can use BonnMotionMobility. It is explained in INET Framework 4.0 User's Guide as well as in INET API Reference. It required a file which contains several values: time, x, and y, separated by a space. An example of this file you can find in examples directory of INET for example: examples\mobility\bonnmotion_small.movements.
To use this type of mobility you should set in omnetpp.ini something like:
**.mobileHost*.mobility.typename = "BonnMotionMobility"
**.mobileHost*.mobility.traceFile = "your_trace_file"
Moreover, you should remove this line:
mobilityType = "MassMobility";
from your MEpath definition (because this way it is hardcoded, and it cannot be controlled via omnetpp.ini).
The definition of MEpath is correct. It requires a *.h and *.cc files that contain a declaration and definition of MEpath C++ class.

Related

Symfony 5 switch cache adapter on condition

I need to switch the Symfony cache adapter depending on ENV conditions. Like if some variable is set, use "cache.adapter.apcu" or use "cache.adapter.filesystem" otherwise.
Is it possible somehow? The documentation is not really helpful with it.
P.S.: It is not possible for us to do this via the creation of a whole new environment
Here is a basic example for a CacheAdapter which has adapters fed into it and then picking one based on a parameter (or alternatively envvar):
<?php
namespace App\Cache;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\InvalidArgumentException;
use Psr\Container\ContainerInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Symfony\Contracts\Service\ServiceSubscriberTrait;
class EnvironmentAwareCacheAdapter implements AdapterInterface, ServiceSubscriberInterface
{
use ServiceSubscriberTrait;
private string $environment;
public function __construct(string $environment)
{
$this->environment = $environment;
}
public function getItem($key)
{
return $this->container->get($this->environment)->getItem($key);
}
public function getItems(array $keys = [])
{
return $this->container->get($this->environment)->getItems($key);
}
// ...
}
This is how you would configure it:
services:
App\Cache\EnvironmentAwareCacheAdapter:
arguments:
$environment: '%kernel.environment%'
tags:
- { name: 'container.service_subscriber', key: 'dev', id: 'cache.app' }
- { name: 'container.service_subscriber', key: 'prod', id: 'cache.system' }
It's not the most elegant solution and is missing error handling and possibly a fallback. Basically, by adding tags with an appropriately named key and the alias to an existing cache as id, you can then refer to that cache with the key in your own adapter. So, depending on your environment you will pick either one. You can replace the key and the constructor argument with anything else you like. I hope that helps.
It seems like you can not set up your cache configuration to use a environment variable like so:
framework:
cache:
app: %env(resolve:CACHE_ADAPTER)%
It is the constraint of FrameworkBundle that provides the cache service. And this constraint will not be "fixed" (Using environment variables at compile time #25173).
To make it possible you need to make your own cache provider that can just pass all arguments to the needed cache provider. You will have access to environment variables at runtime and so you can use it as a proxy that knows what provider to use.

How to pass a parameter from the Jupyter backend to a frontend extension

I currently have a value that is stored as an environment variable the environment where a jupyter server is running. I would like to somehow pass that value to a frontend extension. It does not have to read the environment variable in real time, I am fine with just using the value of the variable at startup. Is there a canonical way to pass parameters a frontend extension on startup? Would appreciate an examples of both setting the parameter from the backend and accessing it from the frontend.
[update]
I have posted a solution that works for nbextentions, but I can't seem to find the equivalent pattern for labextensions (typescript), any help there would be much appreciated.
I was able to do this by adding the following code to my jupter_notebook_config.py
from notebook.services.config import ConfigManager
cm = ConfigManager()
cm.update('notebook', {'variable_being_set': value})
Then I had the parameters defined in my extension in my main.js
// define default values for config parameters
var params = {
variable_being_set : 'default'
};
// to be called once config is loaded, this updates default config vals
// with the ones specified by the server's config file
var update_params = function() {
var config = Jupyter.notebook.config;
for (var key in params) {
if (config.data.hasOwnProperty(key) ){
params[key] = config.data[key];
}
}
};
I also have the parameters declared in my main.yaml
Parameters:
- name: variable_being_set
description: ...
input_type: text
default: `default_value`
This took some trial and error to find out because there is very little documentation on the ConfigManager class and none of it has an end-to-end example.

Scaldi: couldn't find bindings defined in typesafe config

Here is the issue. Let assume I have two mutable modules:
class DbModule extends Module { bind[JdbcBackend#Database] toProvider
inject[JdbcDriver].backend.Database.forURL(
inject[String]("db.url"),
inject[String]("db.username"),
inject[String]("db.password"), null,
inject[String]("db.driver")
) }
and here is the corresponding config:
resources/application.conf:
db { url="postgres url" username="db_user" password="db_password" driver="cc" }
Somewhere in the code I do:
implicit val inj = TypesafeConfigInjector() :: new AppModule
However this injector gives the following exception:
caldi.InjectException: No binding found with following identifiers:
* TypeTagIdentifier(String) * StringIdentifier(db.url)
The order in Scaldi is important: the binding is resolved from left to right.
The :: operator, as stated in the docs, composes two injectors by inverting the operands. Thus, in your case, AppModule is resolved first, hence it cannot find the config params injected.
To solve your problem, use the ++ operator to keep your injectors in order.
I hope this is helpful.

How to dynamically change autoscaling instance names

I have created a heat stack which autoscales depending on CPU use. Each time a new instance is created, it is given a random name.
Is there a way to set a specific name with a counter added to the end of it so that each time a new instance is created it increases by 1?
E.g. Myinstance1, Myinstance2, Myinstance3 ... MyinstanceX
Thanks in advance!
In Openstack HEAT, stack resource names are manipulated with stack_name and suffixed with a short_id. That's why on every autoscaled up instance you could see the instance name as such. This is how the implementation done in overall HEAT project and it is not possible to define instance name suffixed with incremental number.
if i understood you correctly, and if you are Object Oriented Programing:
you are looking for a design pattern called Factory, or more simply, create a static member that will increase in the constructor, and will be added to the name member of the instance created.
You can set the custom names by going to your Auto Scaling Groups and Tags tab, and then adding a tag with the key of "Name" and the value of "MyInstance". Numbering does not make that much sense since your instances are going to be launched and terminated constantly.
Update at 21/09/2020 :
Seems that creating an incremental number is impossible so far, but I found a workaround to achieve my goal, so post here hoping that could give you some ideas.
Mindset:
I tried to find something (which is number) that is created dynamically with the instance for scaling up, to me that is OS::Neutron::Port, so I append one part of IP address after a string to get a distinctive name for each instance.
Solution:
1.Create a port OS::Neutron::Port.
2.Get IP address using get_attr.
3.Split it with dot as delimiter using str_split.
4.Append one part of the address to the string using str_replace.
Sample Code:
lb_server.yaml
resources:
corey_port:
type: OS::Neutron::Port
properties:
network: { get_param: network }
fixed_ips:
- subnet: { get_param: subnet }
number:
type: OS::Heat::Value
properties:
value:
# 192.168.xxx.yyy => [192,168,xxx,yyy]
str_split: ['.', { get_attr: [corey_port, fixed_ips, 0, ip_address] }]
server:
type: OS::Nova::Server
properties:
name:
str_replace:
template: Corey-%last%
params:
# 0 1 2 3
#[192,168,xxx,yyy]
"last%": { get_attr: [number, value, 3] }
flavor: { get_param: flavor }
......
The outcome shoud be Corey-168, Corey-50, Corey-254, etc.

Non-scalar ENVs for use as Symfony Parameter

I'm trying to use ENVs to set my parameters in Symfony2. The scalar values are easy enough, but I have parameters that are arrays that I need to set somehow with ENVs.
The parameter in question:
parameters:
redis.servers:
- { host: 127.0.0.1, port: 6379 }
- { host: other, port: 6379 }
# and so on
The kicker here is that the array of servers can change dynamically, so I can't just assume there's 2.
What I hoped to do (but this just gives me a string of json):
SYMFONY__REDIS__SERVERS=[{"host":"127.0.0.1","port":"6379"}]
Is this possible? Any work-arounds that are feasible? There are multiple bundles we're using that accept array/object parameters, so I can't do an update there to process the param. It would have to be app level, if anything.
Thanks.
I was able to solve this by updating the AppKernel to override the getEnvParameters() method of the parent Kernel. This method only runs on parameters that the Kernel already found in the ENV (technically from $_SERVER). I like it because it won't run on the entire parameter stack, nor the entire $_SERVER array.
protected function getEnvParameters()
{
$parameters = parent::getEnvParameters();
foreach ($parameters as &$parameter) {
if (is_string($parameter)) {
$decoded = json_decode($parameter, true);
// we only care about arrays (or objects that get turned into arrays)
if (!json_last_error() && is_array($decoded)) {
$parameter = $decoded;
}
}
}
return $parameters;
}

Resources