How to implement sending a control message once every 5 seconds for each node in the network and send the reply by the receiver - omnet++

I have made a type of control message called MyControlMessage. Now I want every node to broadcast this type of control message once every 5 seconds and every node that received this type of message should set the value of a field of that message and send it to the source specified in the control message. How is this possible in the Omnet++?
Thanks in advance
NED file is as :
network NetworkRM
{
parameters:
#display("bgb=900,400");
submodules:
visualizer: IntegratedMultiVisualizer {
parameters:
#display("p=64.256,62.247997");
}
configurator: Ipv4NetworkConfigurator {
parameters:
#display("p=64.256,180.72");
}
radioMedium: Ieee80211DimensionalRadioMedium {
parameters:
#display("p=62.247997,287.14398");
}
source: AdhocHost {
parameters:
#display("p=277,45");
}
destination: AdhocHost {
parameters:
#display("p=522,45");
}
source2: AdhocHost {
parameters:
#display("p=277,315");
}
destination2: AdhocHost {
parameters:
#display("p=522,315");
}
}

Related

Dynamic field or field of type (Struct, Map, Any) for custom options

Assuming I need to define a custom option for a method, for example:
message MessageBusOptions {
string namespace = 1;
optional string queue = 2;
}
extend google.protobuf.MethodOptions {
optional MessageBusOptions message_bus_options = 50000;
}
So far everything works as expected. I can define my service the following way:
services TestServices {
rpc SendMessage(MessageReq) returns(MessageRes) {
option (message_bus_options) = {
namespace: "abc",
queue: "default"
}
}
}
Now, how I can I add a dynamic field to the MessageBusOptions so that I can provide a dynamic value, for example:
services TestServices {
rpc SendMessage(MessageReq) returns(MessageRes) {
option (message_bus_options) = {
namespace: "abc",
queue: "default",
dynamic_field: {
a: "a",
b: "b"
}
}
}
}
I tried the following types (Map, Any, Struct) but all of them led to this error
Error while parsing option value for "xxx": Message type "xxx" has no field named "xxx".
How can I define such dynamic field in the custom option?

Simple Spring GraphQL Subscription returning error

I'm trying to create a simple Spring GraphQL subscription handler. Here's my controller:
#Controller
public class GreetingController {
#QueryMapping
String sayHello() {
return "Hello!";
}
#SubscriptionMapping
Flux<String> greeting(#Argument int count) {
return Flux.fromStream(Stream.generate(() -> "Hello # " + Instant.now()))
.delayElements(Duration.ofSeconds(1))
.take(count);
}
}
Here's the GraphQL schema:
type Query {
sayHello: String
}
type Subscription {
greeting(count: Int): String
}
Spring configuration:
spring:
graphql:
graphiql:
enabled: true
path: /graphiql
When I try to run above subscription using graphiql hosted by the spring I receive following error:
{
"errors": [
{
"isTrusted": true
}
]
}
When I run the same graphql request using Postman I receive following response:
{
"data": {
"upstreamPublisher": {
"scanAvailable": true,
"prefetch": -1
}
}
}
What is causing the subscription not to return data from my controller?
As explained in the linked GitHub issue, a subscription requires the ability to stream data within a persistent transport connection - this is not available other plain HTTP.
You'll need to enable WebSocket support in your application first. The GraphiQL UI should use the WebSocket transport transparently for this.

Publish events with MassTransit

I'm trying to publish message in one microservice and get it in another one, but cannot implement this using MassTransit 5.5.3 with RabbitMQ.
As far as I know we don't have to create a ReceiveEndpoint to be able to publish event so I'm just creating the same message interface in both services and publish a message, but as I can see in RabbitMQ it either goes to nowhere (if doesn't mapped to a queue) or goes to "_skipped" queue.
Publisher:
namespace Publisher
{
class Program
{
static async Task Main(string[] args)
{
var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
IRabbitMqHost host = cfg.Host("host", "vhost", h =>
{
h.Username("xxx");
h.Password("yyy");
});
});
bus.Start();
await bus.Publish<Message>(new { Text = "Hello World" });
Console.ReadKey();
bus.Stop();
}
}
public interface Message
{
string Text { get; set; }
}
}
Consumer:
namespace Consumer
{
class Program
{
static async Task Main(string[] args)
{
var bus = Bus.Factory.CreateUsingRabbitMq(cfg =>
{
IRabbitMqHost host = cfg.Host("host", "vhost", h =>
{
h.Username("xxx");
h.Password("yyy");
});
cfg.ReceiveEndpoint(host, e =>
{
e.Consumer<MbConsumer>();
});
});
bus.Start();
bool finish = false;
while(!finish)
{
await Task.Delay(1000);
}
bus.Stop();
}
}
public interface Message
{
string Text { get; set; }
}
public class MbConsumer : IConsumer<Message>
{
public async Task Consume(ConsumeContext<Message> context)
{
await Console.Out.WriteLineAsync(context.Message.Text);
}
}
}
I'm expeting the consumer to get the message once it's been published but it doesn't get it. I think this is because the full message types are different ("Publisher.Message" vs. "Consumer.Message") so message contract is different. How should I fix this code to get the event in the consumer? Looks like I'm missing some fundamental thing about RabbitMQ or MassTransit.
Your guess is correct. MassTransit uses the fully qualified class name as the message contract name. MassTransit also uses type-based routing, so FQCNs are used to create exchanges and bindings.
So, if you move your message class to a separate namespace like:
namespace Messages
{
public interface Message
{
string Text { get; set; }
}
}
You then can reference this type when you publish a message
await bus.Publish<Messages.Message>(new { Text = "Hello World" });
and define your consumer
public class MbConsumer : IConsumer<Messages.Message>
{
public async Task Consume(ConsumeContext<Message> context)
{
await Console.Out.WriteLineAsync(context.Message.Text);
}
}
it will work.
You might want also to look at RMQ management UI to find out about MassTransit topology. With your code, you will see two exchanges, one Publisher.Message and another one Consumer.Message where your consumer queue is bound to the Consumer.Message exchange, but you publish messages to the Publisher.Message exchange and they just vanish.
I would also suggest specifying a meaningful endpoint name for your receive endpoint:
cfg.ReceiveEndpoint(host, "MyConsumer", e =>
{
e.Consumer<MbConsumer>();
});

Add or delete from connection depending on response

Essentially, I have users who can have payments, and theses payments can be filtered with an arg.
Here is my schema, simplified :
type User {
payments($filter: PaymentsFilter): PaymentsConnection,
}
enum PaymentsFilter {
MissingDetails,
}
type PaymentsConnection {
edges { ... }
pageInfo { ... }
}
type Payment {
id
description
}
The MissingDetails filter returns only the Payment who are missing a description.
For example, if I have 2 Payment :
[
{ id: 1, description: null },
{ id: 2, description: 'A great payment' },
]
A query as such :
query {
loggedUser {
payments(filter: MissingDetails) {
...
}
}
}
Would return only the first Payment, with id: 1.
I want to achieve an UpdatePaymentMutation, that would update the payment and depending on if the description is set or not in the response, I would RANGE_ADD it to the connection with the filter MissingDetails, or RANGE_DELETE it.
How can I achieve that ?

GraphQL Relay Mutation Config RANGE_ADD's parentName for connections

I have a page that uses GraphQL Relay connection which fetches drafts.
query {
connections {
drafts(first: 10) {
edges {
node {
... on Draft {
id
}
}
}
}
}
}
In this page, I also create draft through CreateDraftMutation.
mutation {
createDraft(input: {
clientMutationId: "1"
content: "content"
}) {
draft {
id
content
}
}
}
After this mutation, I want Relay to add the created draft into its store. The best candidate for mutation config is RANGE_ADD, which is documented as following:
https://facebook.github.io/relay/docs/guides-mutations.html
RANGE_ADD
Given a parent, a connection, and the name of the newly created edge in the response payload Relay will add the node to the store and attach it to the connection according to the range behavior specified.
Arguments
parentName: string
The field name in the response that represents the parent of the connection
parentID: string
The DataID of the parent node that contains the connection
connectionName: string
The field name in the response that represents the connection
edgeName: string
The field name in the response that represents the newly created edge
rangeBehaviors: {[call: string]: GraphQLMutatorConstants.RANGE_OPERATIONS}
A map between printed, dot-separated GraphQL calls in alphabetical order, and the behavior we want Relay to exhibit when adding the new edge to connections under the influence of those calls. Behaviors can be one of 'append', 'ignore', 'prepend', 'refetch', or 'remove'.
The example from the documentation goes as the following:
class IntroduceShipMutation extends Relay.Mutation {
// This mutation declares a dependency on the faction
// into which this ship is to be introduced.
static fragments = {
faction: () => Relay.QL`fragment on Faction { id }`,
};
// Introducing a ship will add it to a faction's fleet, so we
// specify the faction's ships connection as part of the fat query.
getFatQuery() {
return Relay.QL`
fragment on IntroduceShipPayload {
faction { ships },
newShipEdge,
}
`;
}
getConfigs() {
return [{
type: 'RANGE_ADD',
parentName: 'faction',
parentID: this.props.faction.id,
connectionName: 'ships',
edgeName: 'newShipEdge',
rangeBehaviors: {
// When the ships connection is not under the influence
// of any call, append the ship to the end of the connection
'': 'append',
// Prepend the ship, wherever the connection is sorted by age
'orderby(newest)': 'prepend',
},
}];
}
/* ... */
}
If the parent is as obvious as faction, this is a piece of cake, but I've been having hard time identifying parentName and parentID if it came directly from query connections.
How do I do this?
Edit:
This is how query was exported.
export default new GraphQLObjectType({
name: 'Query',
fields: () => ({
node: nodeField,
viewer: {
type: viewerType,
resolve: () => ({}),
},
connections: {
type: new GraphQLObjectType({
name: 'Connections',
which in return is used in the relay container
export default Relay.createContainer(MakeRequestPage, {
fragments: {
connections: () => Relay.QL`
fragment on Connections {
I've been having hard time identifying parentName and parentID if it
came directly from query connections.
faction and ships in the example from Relay documentation are exactly the same as connections and drafts in your case. Each GraphQLObject has an ID,so does your connections object. Therefore, for your mutation, parentName is connctions and parentID is the ID of connections.
query {
connections {
id
drafts(first: 10) {
edges {
node {
... on Draft {
id
}
}
}
}
}
}
By the way, I guessconnections and drafts are terms from your application domain. Otherwise, connections confuses with GraphQL connection type.

Resources