can't open a receiver bound to application header x-match expression - amqp

I'm using rhea (https://github.com/amqp/rhea), a node.js library to develop AMQP 1.0 clients.
I'm trying to adapt https://github.com/amqp/rhea/tree/master/examples/selector example using an x-match expression instead of a JMS expression.
The purpose is to implement an header routing mechanism based on a AMQP 1.0 compliant broker (ActiveMQ, Qpid, ...).
I tried this code in the appropriate section in recv.js:
connection.open_receiver({
source: {
address: 'amq.match',
filter: {
'x-match': 'all',
value: {
'nat': 'it',
'prod': 'a22'
}
}
}
})
Received a connection error "Expected value type is 'Filter' but got 'String' amqp:decode-error" from Qpid Java broker (rel. 7.1.0).

According to this answer received on rhea github repo:
https://github.com/amqp/rhea/issues/200#issuecomment-469220880
The filter needs to be a described value. Try something like this:
connection.open_receiver({
source: {
address: 'amq.match',
filter: {
'foo': amqp_types.wrap_described({
'nat': 'it',
'prod': 'a22',
'x-match': 'all'
}, 0x468C00000002)
}
}
});
where:
var amqp_types = require('rhea').types;
That works only with Qpid cpp, it's not working with ActiveMQ and Qpid java.

Related

PyObjc: implement NSXPCInterface

I am writing an Extension and main app is in PyObjc. I want to setup communication between main app and Extension.
With ref to link I tried writing a Protocol.
SampleExtensionProtocol = objc.formal_protocol('SampleExtensionProtocol', (), [
objc.selector(None, b"upperCaseString:withReply:", signature=b"v#:##",isRequired=0),
objc.selector(None, b"setEnableTemperProof:withReply:", signature=b"v#:##",isRequired=0),
])
Connection object is created.
connection = NSXPCConnection.alloc().initWithMachServiceName_options_("com.team.extension",NSXPCConnectionPrivileged)
Registered Metadata as well.
objc.registerMetaDataForSelector(b'NSObject', b'upperCaseString:withReply:', {
'arguments': {
3: {
'callable': {
'retval': {'type': b'#'},
'arguments': {
0: {'type': b'^v'},
1: {'type': b'i'},
},
},
}
}
})
objc.registerMetaDataForSelector(b'NSObject', b'setEnableTemperProof:withReply:', {
'arguments': {
3: {
'callable': {
'retval': {'type': b'#'},
'arguments': {
0: {'type': b'^v'},
1: {'type': b'i'},
},
},
}
}
})
But while creating an Interface getting error.
mySvcIF = Foundation.NSXPCInterface.interfaceWithProtocol_(SampleExtensionProtocol)
ValueError: NSInvalidArgumentException - NSXPCInterface: Unable to get extended method signature from Protocol data (SampleExtensionProtocol / upperCaseString:withReply:). Use of clang is required for NSXPCInterface.
It is not possible to define a protocol in Python that can be used with NSXPCInterface because that class needs "extended method signatures" which cannot be registered using the public API for programmatically creating protocols in the Objective-C runtime.
As a workaround you have to define the protocol in a small C extension that defines to protocol. The PyObjC documentation describes a small gotcha for that at https://pyobjc.readthedocs.io/en/latest/notes/using-nsxpcinterface.html, including how to avoid that problem.

Nestjs kafka implementation

I've read nestjs microservice and kafka documentation but I couldn't figure out some of it. I'll be so thankful if you can help me out.
So as the docs says I have to create a microService in main.ts file as follows:
const app = await NestFactory.createMicroservice<MicroserviceOptions>(AppModule, {
transport: Transport.KAFKA,
options: {
client: {
brokers: ['localhost:9092'],
}
}
});
await app.listen(() => console.log('app started'));
Then there is a kafkaModule file like this:
#Module({
imports: [
ClientsModule.register([
{
name: 'HERO_SERVICE',
transport: Transport.KAFKA,
options: {
client: {
clientId: 'hero',
brokers: ['localhost:9092'],
},
consumer: {
groupId: 'hero-consumer'
}
}
},
]),
]
})
export class KafkaModule implements OnModuleInit {
constructor(#Inject('HERO_SERVICE') private readonly clientService: KafkaClient)
async onModuleInit() {
await this.clientService.connect();
}
}
The first thing I can't figure is what is the use of the first parameter of createMicroservice ? (I passed AppModule and KafkaModule and both worked correctly. knowing that kafkaModule is imported at appModule)
The other thing is that from what I understood, the microservice part and the configuration in the main.ts file is used to subscribe on the topics that is used in MessagePattern or EventPattern decorators, and the kafkaClient described in the kafkaModule is used to send messages to different topics.
the problem here is if what I said earlier is true, then why clientModule uses a default groupId if not specified to work as consumer. strange thing is I couldn't find a solution to get any message from any topic using clientModule.
what I'm doing right now is to use different group ids in each file so they wont have any conflicts.
The first parameter of createMicroservice, it will help to guide how the consumer will connect to Kafka when you want to consume a message from a specific topic.
Example: we want to get message from topic: test01
How we declare?
import {Controller} from '#nestjs/common'
import {MessagePattern, Payload} from '#nestjs/microservices'
#Controller('sync')
export class SyncController {
#MessagePattern('test01')
handleTopicTest01(#Payload() message: Sync): any {
// Handle your message here
}
}
The second block is used as producer that is not consumer. When application want to send message to a specific topic, the clientModel will support this.
#Get()
sayHello() {
return this.clientModule.send('say.hello', 'hello world')
}

Unable to create straight connectors in jsplumb

I'm using version 2.15 of jsplumb in an Angular project and am trying to create straight connections between the elements. The code below initiates the instance
ngAfterViewInit() {
this.jsPlumbInstance = jsPlumb.getInstance({
Container: '.diagram'
});
// can I add other defaults here?
}
I create the connection like this
this.jsPlumbInstance.connect({
source,
target,
anchors: ['Bottom', 'Top'],
detachable: false,
endpoint: 'Dot'
});
which results in curvy lines between anchors. I tried to add a 'connector' property above setting it to 'straight' or ['straight'], but that leads to the 'unknown connector type 'straight' error. The docs here do not specify the syntax and the link to it is broken.
i had to set the connector on the instance
this.jsPlumbInstance = jsPlumb.getInstance({
Container: '.diagram',
Connector: 'Straight',
Endpoints: [
['Dot', { radius: 3 }],
['Dot', { radius: 3 }]
],
ConnectionsDetachable: true,
Anchors: ['Bottom', 'Top']
});
anyone knows how to make all elements draggable in the community edition?

How to configure rest client in quarkus microprofile case

When using Quarkus microprofile as a rest client, how can I configure underlying HttpClient?
Like number of retries, connection pool size per host and so on?
Also is it possible to force client restart somehow (so connections pool will be restarted)?
https://download.eclipse.org/microprofile/microprofile-rest-client-2.0-RC2/microprofile-rest-client-2.0-RC2.html#_configuration_keys outlines the full set of configuration keys that can be used.
The ones you're looking for are:
{packageName}.{interfaceName}/mp-rest/connectTimeout
{packageName}.{interfaceName}/mp-rest/readTimeout
The RestClientBuilder also has methods for setting those properties if you're using the programmatic API instead of the CDI approach.
I'm not aware of any means of restarting the underlying HTTP client connection pool. What would be the use case for such a situation that doesn't require the whole application to be restarted?
So... After a lot of digging, here is a solution I've found so far. It is not obvious apparently:
To make it work in pure Java (no native)
Under resources/META-INF/services directory add file named org.eclipse.microprofile.rest.client.spi.RestClientBuilderListener containing class name of your implementation of RestClientBuilderListener interface. For example my.test.MyBuilderListener. This will allow ServiceLocator to execute your listener
Refer a property you want to modify from ResteasyClientBuilder, for example to set your custom value to connectionTTL code will looks like this:
public void onNewBuilder(RestClientBuilder builder) {
log.info("Changing TTL for connections");
builder.property("resteasy.connectionTTL", List.of(2L, TimeUnit.SECONDS));
}
Ie. add a resteasy. prefix to a property name
Profit
Now native support:
After steps above:
Set both MyBuildListener and ResteasyClientBuilder available for reflection by creating a file reflection-config.json:
[
{
"name": "org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true
}, {
"name": "my.test.MyBuilderListener",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredFields": true,
"allPublicFields": true
}
]
Add service registration file to resources. Create a file named resources-config.json with content
{
"resources": [
{
"pattern": "META-INF/services/org\\.eclipse\\.microprofile\\.rest\\.client\\.spi\\.RestClientBuilderListener$"
}
]
}
register both files in application.yaml:
quarkus:
native:
additional-build-args: -H:ResourceConfigurationFiles=resources-config.json, -H:ReflectionConfigurationFiles=reflection-config.json
Native profit
Have fun

gRPC connectivity problem: How to figure out if it is the server or the client?

I am reading a Golang book named "Go Blueprints". So one of the chapters is about implementing a micro-service. And the communication with that service could be http or gRPC. I think I did everything right, however I can't get gRPC communication work. When I try to ask the server from the client, I get this error:
rpc error: code = Unimplemented desc = unknown service Vault
My question is how to start debugging this? How can I check if the problem is in the server or in the client?
In your implementation, the service name was wrong when you initialised endpoints for Hash and Validate. It should be pb.Vault instead of Vault. So the New method should look like this:
func New(conn *grpc.ClientConn) vault.Service {
var hashEndpoint = grpctransport.NewClient(
conn, "pb.Vault", "Hash",
vault.EncodeGRPCHashRequest,
vault.DecodeGRPCHashResponse,
pb.HashResponse{},
).Endpoint()
var validateEndpoint = grpctransport.NewClient(
conn, "pb.Vault", "Validate",
vault.EncodeGRPCValidateRequest,
vault.DecodeGRPCValidateResponse,
pb.ValidateResponse{},
).Endpoint()
return vault.Endpoints{
HashEndpoint: hashEndpoint,
ValidateEndpoint: validateEndpoint,
}
}
In general, you should consult the generated .pb.go file of the matching proto on how things are named. As you can see, it is not straightforward and it probably depends on the implementation of the proto generators.
In your case, here is what it looks like:
grpc.ServiceDesc{
ServiceName: "pb.Vault",
HandlerType: (*VaultServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "Hash",
Handler: _Vault_Hash_Handler,
},
{
MethodName: "Validate",
Handler: _Vault_Validate_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "vault.proto",
}

Resources