matt.fellows
2022-08-02 23:22
has joined #avro

ali.ustek
2022-08-02 23:22
has joined #avro

uglyog
2022-08-02 23:22
has joined #avro

andrevdrodrigues
2022-08-02 23:22
has joined #avro

matt.fellows
2022-08-02 23:23
Creating this channel to discuss any proposed work to create a plugin for Avro

yousafn
2022-08-02 23:23
has joined #avro

matt.fellows
2022-08-02 23:24
Noting we haven?t yet road tested the https://github.com/pact-foundation/pact-plugins/blob/main/docs/writing-plugin-guide.md (Ron has created several plugins, but we?ll need more data points to flesh this out - I plan on writing one soon in order to do a talk on it), there are examples that can be followed to help

matt.fellows
2022-08-02 23:25
We have a feature request here: https://pact.canny.io/feature-requests/p/support-apache-avro (y?all might want to vote on it)

ali.ustek
2022-08-03 09:19
I've started conversation of creating a plugin where I work. However, I'll be on holiday for 3 weeks from friday, so can't push anything yet

ali.ustek
2022-08-03 09:31
How would you like to proceed with the repo? would you create a repo on `pact-foundation` and we contribute or we create and manage the plugin repo ourselves?


yousafn
2022-08-03 09:55
Hi Ali, it would be probably be best just to raise under your own account, we can get feedback from the team and other users, and once we are all happy and it's stable we can think about moving it into the pact-foundation. The reservation with doing it straight away under the pact-foundation is the pact maintainers will be under a level of expectation to maintain it, and we would only want to do that when the kinks and niggles are ironed out. We've used this pattern successfully in the past :sunglasses: Thanks for your efforts @ali.ustek much appreciated as I'm sure it will be for others


ali.ustek
2022-08-03 10:58
I'm trying to follow the protobuf plugin however, it seems out-of-date with the latest pact-core, any directions?

matt.fellows
2022-08-03 11:16
To be honest, you could probably remove all of the other stuff and just leave the avro bits behind. I think we?ll want to keep the avro plugin as it?s own entirely contained repo, and (if successful - which I think it will be!) eventually, we could just incorporate it into the pact-foundation account.

matt.fellows
2022-08-03 11:17
So that?s to say, I don?t think you need to fork any project, a blank slate repo based on that sub folder is a good start

matt.fellows
2022-08-03 11:17
What does `pact-core` have to do with this, sorry?

matt.fellows
2022-08-03 11:17
oh, sorry I read that as the Pact JS core

matt.fellows
2022-08-03 11:18
would you mind please elaborating?

ali.ustek
2022-08-03 11:25
OK, will change it

ali.ustek
2022-08-03 11:27
in protobuf `PactPluginservice` extends `PactPluginGrpcKt.PactPluginCoroutineImplBase` which doesn't exist anymore. Closes I could find is `PactPluginGrpc.PactPluginImplBase` , which has the same methods but returns types are void

ali.ustek
2022-08-03 11:28
on the Guide `You can find the proto file that defines the plugin interface in the proto directory. Your plugin will need to implement this interface.` I'm a novice when it comes to protobuf so don't even know where to start. that's why I thought copy/paste from protobuf plugin will be easier for me


matt.fellows
2022-08-03 11:33
In case it?s not clear, have you read https://github.com/pact-foundation/pact-plugins/blob/main/docs/writing-plugin-guide.md first (it explains how the plugins communicate over gRPC)? You?ll then be creating a *content type* plugin (https://github.com/pact-foundation/pact-plugins/blob/main/docs/content-matcher-design.md), where the content type will (presumably) be `avro/binary` Basically the plugin will start a gRPC server (via the pact plugin driver) and Pact will communicate to it using the https://github.com/pact-foundation/pact-plugins/blob/main/proto/plugin.proto you alluded to.

matt.fellows
2022-08-03 11:35
@uglyog should be able to give you some pointers with regards to the Java code, and re-using helpful bits, but hopefully that background might help a touch.

ali.ustek
2022-08-03 11:35
I'll read the docs again

ali.ustek
2022-08-03 11:42
@ming.meng @deb.kimnach @chaitanya.guttula ^FYI

ali.ustek
2022-08-03 11:52
@gunjan.titiya FYI^

gunjan.titiya
2022-08-03 11:52
has joined #avro

chaitanya.guttula
2022-08-03 12:43
has joined #avro

deb.kimnach
2022-08-03 12:48
has joined #avro

matt.fellows
2022-08-03 13:40
(just a note, we have a team outing tomorrow so it will be a quiet day from the PF team, i?ll aim to check in Friday out time - AEST)

mike.key
2022-08-03 21:34
has joined #avro

uglyog
2022-08-04 03:21
@ali.ustek the gRPC plugin was re-written in Rust https://github.com/pactflow/pact-protobuf-plugin and I haven't gone back and updated that example one

jaswanth.ooty
2022-08-12 12:47
has joined #avro

duynguyenptithcm
2022-08-20 07:24
has joined #avro

mahinsyeda99
2022-09-07 09:54
has joined #avro

mahinsyeda99
2022-09-09 07:49
Hello everyone. My organisation is developing microservice application. We use kafka as the message broker and avro schema. We are planning to have contract tests but looks like we only have json support now. From the previous discussion on this channel, I see that there are plans to provide a plugin to support avro. May I know the progress on this? We would like to have the contract tests for our services in place as early as possible. Can someone help me on this?

matt.fellows
2022-09-09 11:20
@ali.ustek (a community member) was looking into it, but I don?t believe work has started. We (Pact maintainers / Pactflow) don?t have it officially on a roadmap but we?d obviously be very supportive of any work in this space.

muirandy
2022-10-13 14:07
has joined #avro

stefan.tertan
2022-11-01 17:25
has joined #avro

momarquez
2022-11-10 17:50
has joined #avro

yousafn
2022-11-18 12:56
Hey team. How are you all getting on in the world of Avro, I built my first Avro app last week on my holidays, (only a basic hello world type app), so keen to see where you all up to, whether I can help out? If not, I'll happily share progress when I have something to report :slightly_smiling_face:

ali.ustek
2022-11-18 13:05
I've not made much progress, I had a chat with @matt.fellows, he mentioned that matchers work in Rust only and I've started to familiarise myself with Rust, as I am Java/Scala dev

yousafn
2022-11-18 13:14
I think this PR might be useful, it exposes matching rules via the FFI functions https://github.com/pact-foundation/pact-reference/pull/229 rather than needing to be re-written in the consuming language

yousafn
2022-11-18 13:15
Same here, I think we all are to some degree. Feel free to ask any other questions if you get stuck. I am enjoying the polyglot nature of being able to see the same thing in a few different languages, even if I don't fully understand it. Thanks for your efforts so far

ali.ustek
2022-11-18 13:17
have you got a sample rust project? I created one and trying to understand if this needs to be a `http://lib.rs` or a `http://main.rs` looking at the protobuff plugin both are in use

yousafn
2022-11-18 13:38
hmm A sample of a rust project consuming a plugin? or a sample of a rust plugin?

yousafn
2022-11-18 13:40
Here https://github.com/pactflow/pact-protobuf-plugin/tree/main/src http://lib.rs is referencing http://built.rs which is in the output directory, so must be from an out of the build, and is the main entry point. the http://main.rs contains all the mean (init plugin and posting its port etc)

yousafn
2022-11-18 13:41
there is also the CSV prototype to compare and contrast, also in rust https://github.com/pact-foundation/pact-plugins/tree/main/plugins/csv

ali.ustek
2022-11-18 16:50
yep, I've trying to compare those two. CSV one seems simpler than the protobuf, which seem to have more things, i.e mock server

matt.fellows
2022-11-30 23:29
FYI I thought a feature request existed but it did not: https://pact.canny.io/admin/board/feature-requests/p/plugin-avro

orbit
2022-12-01 15:44
has joined #avro

yousafn
2022-12-14 10:38
This was the avro file I was using for my little hello world app, just so we can have a look at the structure ```{ "type" : "record", "name" : "Item", "namespace" : "example.avro", "fields" : [ {"name": "name", "type": "string"}, {"name": "description", "type":["string", "null"]}, {"name": "price", "type":["double", "null"]} ] }```

yousafn
2022-12-14 10:41
Was using this example http://hadooptutorial.info/avro-serialization-ruby-example/ Any resources to learning about avro would be really useful!

ali.ustek
2022-12-14 11:13
@yousafn here is my cannibalised protobuf to avro plugin skeleton https://github.com/austek/pact-avro-plugin/tree/rust_main

yousafn
2022-12-14 11:13
Awesome thanks for sharing my friend! Will pull it down and have a look through today

yousafn
2022-12-16 15:45
Hey Ali, got some time today. The following is all from `rust_main` Weirdly I can't send a request from the CLI, I get an error logged in the plugin ```evans cli call io.pact.plugin.PactPlugin.InitPlugin --proto plugin.proto --host localhost --file samplePayloads/InitPluginRequest.json --port 51356``` `InitPluginRequest.json` :point_down: ```{ "implementation": "plugin-driver-rust", "version": "0.1.16" }``` `2022-12-16T15:36:58.218418Z ERROR tokio-runtime-worker tower_http::trace::on_failure: response failed classification=Code: 16 latency=1 ms` However running it from a pact-test, https://github.com/pact-foundation/example-project-js-foobar-plugin/blob/694455935899fa16a71aaadc9bb08ec56130d1bb/test/plugin.consumer.spec.ts#L27 by updating the refs here from `foo` to `avro` - and running the test, I can see the plugin being started and trying to process the content-types, here it fails as it's not expecting this type of request. this would be more in line, taken from the readme, ``````java builder // Tell the Pact framework to load the protobuf plugin .usingPlugin("protobuf") // Define the expected message (description) and the type of interaction. Here is is an asynchronous message. .expectsToReceive("Person Message", "core/interaction/message") // Provide the data for the test .with(Map.of( // For a single asynchronous message, we just provide the contents for the message. For RPC service calls, there // will be a request and response message "message.contents", Map.of( // set the content type, so the Pact framework will know to send it to the Protobuf plugin "pact:content-type", "application/protobuf", // pact:proto contains the source proto file, which is required to be able to test the interaction "pact:proto", filePath("addressbook.proto"), // provide the name of the message type we are going to test (defined in the proto file) "pact:message-type", "Person", // We can then setup the expected fields of the message "name", "notEmpty('Fred')", // The name field must not be empty, and we use Fred in our tests "id", "matching(regex, '100\\d+', '1000001')", // The id field must match the regular expression, and we use 1000001 in the tests "email", "matching(regex, '\\w+@[a-z0-9\\.]+', '')" // Emails must match a regular expression // phones is a repeated field, so we define an example that all values must match against "phones", Map.of( "number", "matching(regex, '(\\+\\d+)?(\\d+\\-)?\\d+\\-\\d+', '+61-03-1234-5678')" // Phone numbers must match a regular expression // We don't include type, as it is an emum and has a default value, so it is optional // but we could have done something like matching(equalTo, 'WORK') ) ) )) `````` have you got a sample test at all that you are trying to run? I can see the error in my pact test, that is will call configure_avro service.


yousafn
2022-12-16 16:05
Sound, got a JS test that will call the plugin, and can see the plugin configuring the contents, and issuing a response that it got no requests :+1: Off to pick the wife up from work but then will issue a grpc client req so I can get this test to pass. ```/* tslint:disable:no-unused-expression no-empty */ import chai from 'chai'; import chaiAsPromised from 'chai-as-promised'; import { SpecificationVersion, PactV4, LogLevel } from '@pact-foundation/pact'; import net = require('net'); import { generateAvroMessage, parseAvroMessage } from '../protocol'; import axios from 'axios'; chai.use(chaiAsPromised); const { expect } = chai; describe('Plugins - Avro Protocol', () => { const HOST = '127.0.0.1'; describe('TCP interface', () => { const pact = new PactV4({ consumer: 'myconsumer', provider: 'myprovider', spec: SpecificationVersion.SPECIFICATION_VERSION_V4, logLevel: (process.env.LOG_LEVEL as LogLevel) || 'error', }); describe('with AVRO protocol', async () => { it('generates a pact with success', () => { const avroMessage = `{ "pact:proto": "/Users/saf/dev/pluginopedia/proto/simple.proto", "pact:content-type": "application/avro", "pact:proto-service": "Test/GetTest", "request": { "in": "matching(boolean, true)" }, "response": { "out": "matching(boolean, true)" } }`; return pact .addSynchronousInteraction('a AVRO message') .usingPlugin({ plugin: 'avro', version: '0.0.5', }) .withPluginContents(avroMessage, 'application/avro') .startTransport('grpc', HOST) .executeTest(async (tc) => { const message = await sendAvroMessageTCP('hellotcp', HOST, tc.port); expect(message).to.eq('tcpworld'); }); }); }); }); }); const sendAvroMessageTCP = ( message: string, host: string, port: number ): Promise<string> => { const socket = net.connect({ port: port, host: host, }); const res = socket.write(generateAvroMessage(message) + '\n'); if (!res) { throw Error('unable to connect to host'); } return new Promise((resolve) => { socket.on('data', (data) => { resolve(parseAvroMessage(data.toString())); }); }); };``` ```export const parseAvroMessage = (raw: string): string => { return raw }; export const generateAvroMessage = (raw: string): string => { return raw };```

ali.ustek
2022-12-18 01:33
Sorry, this is still very early stages, stripped down version of the protobuff plugin

yousafn
2022-12-19 11:09
No need to apologise! It gets us on the same page :raised_hands:

simon.petty
2023-01-10 08:28
has joined #avro

tonis.ojandu
2023-02-09 09:48
has joined #avro

ali.ustek
2023-02-12 20:20
I've put a skeleton of the avro plugin together, https://github.com/austek/pact-avro-plugin `PactAvroPluginService` is the Plugin implementation. I've lots of questions but here is a small list before I can continue 1- what is supposed to be in the ConfigureInteractionResponse, what is the content of the each Interaction? is it what ever the user put into the test for the consumer? 2- I've tried a dummy Interaction but getting `While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length.`, so far I don't know why 3- What is plugin supposed to do? get a request, get a response and make the mock server respond with that response given the request? 4- where do content matchers/generators get into picture?

uglyog
2023-02-12 22:28
I'll have a review today and see if I can answer your questions

uglyog
2023-02-13 00:32
1 - ConfigureInteractionResponse contains the data to create the Pact interaction with. It kind of depends on your protocol whether is one or more interactions. I assume with Avro, there would be one (gRPC can support steaming, where there may be multiple). So, using the gRPC example, this does the following: ? parsers the incoming config data into gRPC specific elements (Protobuf message, gRPC metadata) ? Works out the matching rules and generators that must be applied to those elements. ? Create the actual Protobuf message to be used in the test ? Record any gRPC data needed for that interaction (this is the plugin config). This can be either stored against the interaction or in the global metadata section for the plugin in the Pact file.

uglyog
2023-02-13 00:36
So, ConfigureInteractionResponse encapsulates all that data. On the other side, the Pact framework will take that and create the interaction from it and add it to the Pact file it is setting up.

uglyog
2023-02-13 00:45
2- I have never seen that error before. Looks like the response going back to the Pact framework is being truncated in the middle of the message. Could be because of the async nature of Scala and a buffer is not being flushed, or maybe an exception is be raised somewhere that is causing the generation of the response to be truncated at that point. But, basically, the gRPC server the plugin has started is not sending a valid Protobuf message back. Or is this the incoming message that is not being read correctly?

uglyog
2023-02-13 00:47
3- and 4- are related, by answering 3- will require answering 4-

uglyog
2023-02-13 03:38
A plugin has a few things it is required to do. At the basic level, it needs to be able to verify that a payload is correct based on the test data received (be a content matcher) and be able to generate valid payloads (be a content generator). I.e, you plugin needs to be able to match an AVRO message and determine if it is correct (based on what the user has specified in their test), and also be able to generate an AVRO message for use in the test.

uglyog
2023-02-13 03:41
The next level up, it should (doesn't have to) be able to create a mock server for use in tests. This is only for protocols where this makes sense (the CSV plugin does not do this). Ideally, the mock server will re-use the content matcher and content generator behaviour to receive a request, verify that it is correct based on the config it has been given, and if correct, generate a valid response.

uglyog
2023-02-13 03:42
And then it needs to be able to verify a running server. This is the reverse of what the mock server does. It needs to be able to generate a valid request (using the content generator implementation), send that to a running provider, and then use it's content matcher implementation to verify the response is correct.

uglyog
2023-02-13 03:47
In essance, your AVRO plugin needs to be able to do: ? validate that an AVRO message is correct based on test configuration (AVRO content matcher) ? generate a valid AVRO message based on test configuration (AVRO content generator) ? act as an AVRO server, by being a mock server that can receive an AVRO request, validate it, and render an AVRO response back ? validate a running AVRO server, by generating an AVRO message, sending it to the server, and then validating the response from it.

dariusz.duleba
2023-02-13 08:37
has joined #avro

sugi
2023-02-13 10:05
has joined #avro

ali.ustek
2023-02-13 10:49
Hi Ron, could we setup a call?

ali.ustek
2023-02-13 20:49
Does interaction response body content has to be Protobuf DynamicMessage?

uglyog
2023-02-13 23:00
Protobuf DynamicMessage is specific to gRPC/Protobuf message generation. You need something similar for AVRO.

uglyog
2023-02-13 23:02
We can definitely setup a call, just need to take timezones into account (I'm in Melbourne/Australia), and @matt.fellows and @yousafn might want the option join as well

ali.ustek
2023-02-14 02:10
can you do in 8 hours, I'm in London

uglyog
2023-02-14 02:58
Yeah, ok, that's 9PM Melbourne time 10am London? @matt.fellows?

matt.fellows
2023-02-14 05:57
I think I can join, but will need to ask the wife when she gets home :laughing:

matt.fellows
2023-02-14 05:59
I?ll send an invite now so you all have it, and make Ron a co-presenter in case I can?t make it

yousafn
2023-02-14 11:30
sorry i missed you guys, was on holiday. did you get to catch up?

matt.fellows
2023-02-14 11:30
Yep - just caught up tonight!

ali.ustek
2023-02-15 19:05
Is `interactionMarkup` required? if so, what is it supposed to be set to?

yousafn
2023-02-15 19:06
no not required. allows the plug-in author to allow to markup formatted rendering of the pacts contents within the pact broker

ali.ustek
2023-02-15 19:12
@yousafn does below patct file look OK

ali.ustek
2023-02-15 19:12
```V4Pact configureInteractionResponseMessage(PactBuilder builder) { return builder .usingPlugin("avro") .expectsToReceive("Configure Interaction Response", "core/interaction/message") .with(Map.of( "message.contents", Map.of( "pact:avro", schemasPath, "pact:record-name", "Item", "pact:content-type", "avro/binary", "name", "notEmpty('Item-41')", "id", "matching(contentType, '22', '100')" ) )) .toPact(); }```

yousafn
2023-02-15 20:37
Hey buddy, Just had a quick look now, I've got an example for `asynchronous/messages` that I pulled out from Slack, diff against your pact doesn't look too dis-similar. nice work! need to spin it up on my machine locally ```{ "consumer": { "name": "Greeter Service" }, "interactions": [ { "_id": "f2a0ad127283680720dba3410ed3c8cc97d0c36b", "contents": { "content": { "callCount": "10", "distribution": [ { "callCount": "10", "id": "1" } ] }, "contentType": "application/json", "encoded": false }, "description": "private.metrics.greeting.usage", "key": "", "matchingRules": { "body": { "$.callCount": { "combine": "AND", "matchers": [ { "match": "regex", "regex": "\\d+" } ] }, "$.distribution": { "combine": "AND", "matchers": [ { "match": "ignore-order", "min": 0 } ] }, "$.distribution[0].callCount": { "combine": "AND", "matchers": [ { "match": "regex", "regex": "\\d+" } ] }, "$.distribution[0].id": { "combine": "AND", "matchers": [ { "match": "regex", "regex": "\\d+" } ] } } }, "metadata": { "contentType": "application/json" }, "pending": false, "providerStates": [ { "name": "non-empty-greeting-usage-statistics" } ], "type": "Asynchronous/Messages" } ], "metadata": { "pact-jvm": { "version": "4.3.5" }, "pactSpecification": { "version": "4.0" } }, "provider": { "name": "Greeting Usage Api" } }``` Here is an example for the gRPC plugin `synchronous/messages` ```{ "consumer": { "name": "grpc-consumer-go" }, "interactions": [ { "description": "calculate rectangle area request", "interactionMarkup": { "markup": "```protobuf\nmessage AreaResponse {\n repeated float value = 1;\n}\n```\n", "markupType": "COMMON_MARK" }, "key": "9ff637ebd9f6fcd2", "pending": false, "pluginConfiguration": { "protobuf": { "descriptorKey": "a85dff8f82655a9681aad113575dcfbb", "service": "Calculator/calculateMulti" } }, "request": { "contents": { "content": "CgwSCg0AAEBAFQAAgEAKBwoFDQAAQEA=", "contentType": "application/protobuf;message=AreaRequest", "contentTypeHint": "BINARY", "encoded": "base64" }, "matchingRules": { "body": { "$.shapes[0].rectangle.length": { "combine": "AND", "matchers": [ { "match": "number" } ] }, "$.shapes[0].rectangle.width": { "combine": "AND", "matchers": [ { "match": "number" } ] }, "$.shapes[1].square.edge_length": { "combine": "AND", "matchers": [ { "match": "number" } ] } } } }, "response": [ { "contents": { "content": "CggAAEBBAAAQQQ==", "contentType": "application/protobuf;message=AreaResponse", "contentTypeHint": "BINARY", "encoded": "base64" }, "matchingRules": { "body": { "$.value[0].*": { "combine": "AND", "matchers": [ { "match": "number" } ] }, "$.value[1].*": { "combine": "AND", "matchers": [ { "match": "number" } ] } } } } ], "transport": "grpc", "type": "Synchronous/Messages" } ], "metadata": { "pactRust": { "ffi": "0.3.15", "mockserver": "0.9.6", "models": "1.0.1" }, "pactSpecification": { "version": "4.0" }, "plugins": [ { "configuration": { "a85dff8f82655a9681aad113575dcfbb": { "protoDescriptors": "CsoHChVhcmVhX2NhbGN1bGF0b3IucHJvdG8SD2FyZWFfY2FsY3VsYXRvciK6AgoMU2hhcGVNZXNzYWdlEjEKBnNxdWFyZRgBIAEoCzIXLmFyZWFfY2FsY3VsYXRvci5TcXVhcmVIAFIGc3F1YXJlEjoKCXJlY3RhbmdsZRgCIAEoCzIaLmFyZWFfY2FsY3VsYXRvci5SZWN0YW5nbGVIAFIJcmVjdGFuZ2xlEjEKBmNpcmNsZRgDIAEoCzIXLmFyZWFfY2FsY3VsYXRvci5DaXJjbGVIAFIGY2lyY2xlEjcKCHRyaWFuZ2xlGAQgASgLMhkuYXJlYV9jYWxjdWxhdG9yLlRyaWFuZ2xlSABSCHRyaWFuZ2xlEkYKDXBhcmFsbGVsb2dyYW0YBSABKAsyHi5hcmVhX2NhbGN1bGF0b3IuUGFyYWxsZWxvZ3JhbUgAUg1wYXJhbGxlbG9ncmFtQgcKBXNoYXBlIikKBlNxdWFyZRIfCgtlZGdlX2xlbmd0aBgBIAEoAlIKZWRnZUxlbmd0aCI5CglSZWN0YW5nbGUSFgoGbGVuZ3RoGAEgASgCUgZsZW5ndGgSFAoFd2lkdGgYAiABKAJSBXdpZHRoIiAKBkNpcmNsZRIWCgZyYWRpdXMYASABKAJSBnJhZGl1cyJPCghUcmlhbmdsZRIVCgZlZGdlX2EYASABKAJSBWVkZ2VBEhUKBmVkZ2VfYhgCIAEoAlIFZWRnZUISFQoGZWRnZV9jGAMgASgCUgVlZGdlQyJICg1QYXJhbGxlbG9ncmFtEh8KC2Jhc2VfbGVuZ3RoGAEgASgCUgpiYXNlTGVuZ3RoEhYKBmhlaWdodBgCIAEoAlIGaGVpZ2h0IkQKC0FyZWFSZXF1ZXN0EjUKBnNoYXBlcxgBIAMoCzIdLmFyZWFfY2FsY3VsYXRvci5TaGFwZU1lc3NhZ2VSBnNoYXBlcyIkCgxBcmVhUmVzcG9uc2USFAoFdmFsdWUYASADKAJSBXZhbHVlMq0BCgpDYWxjdWxhdG9yEk4KDGNhbGN1bGF0ZU9uZRIdLmFyZWFfY2FsY3VsYXRvci5TaGFwZU1lc3NhZ2UaHS5hcmVhX2NhbGN1bGF0b3IuQXJlYVJlc3BvbnNlIgASTwoOY2FsY3VsYXRlTXVsdGkSHC5hcmVhX2NhbGN1bGF0b3IuQXJlYVJlcXVlc3QaHS5hcmVhX2NhbGN1bGF0b3IuQXJlYVJlc3BvbnNlIgBCHFoXaW8ucGFjdC9hcmVhX2NhbGN1bGF0b3LQAgFiBnByb3RvMw==", "protoFile": "syntax = \"proto3\";\n\npackage area_calculator;\n\noption php_generic_services = true;\noption go_package = \"io.pact/area_calculator\";\n\nservice Calculator {\n rpc calculateOne (ShapeMessage) returns (AreaResponse) {}\n rpc calculateMulti (AreaRequest) returns (AreaResponse) {}\n}\n\nmessage ShapeMessage {\n oneof shape {\n Square square = 1;\n Rectangle rectangle = 2;\n Circle circle = 3;\n Triangle triangle = 4;\n Parallelogram parallelogram = 5;\n }\n}\n\nmessage Square {\n float edge_length = 1;\n}\n\nmessage Rectangle {\n float length = 1;\n float width = 2;\n}\n\nmessage Circle {\n float radius = 1;\n}\n\nmessage Triangle {\n float edge_a = 1;\n float edge_b = 2;\n float edge_c = 3;\n}\n\nmessage Parallelogram {\n float base_length = 1;\n float height = 2;\n}\n\nmessage AreaRequest {\n repeated ShapeMessage shapes = 1;\n}\n\nmessage AreaResponse {\n repeated float value = 1;\n}\n" } }, "name": "protobuf", "version": "0.2.0" }, { "configuration": { "a85dff8f82655a9681aad113575dcfbb": { "protoDescriptors": "CsoHChVhcmVhX2NhbGN1bGF0b3IucHJvdG8SD2FyZWFfY2FsY3VsYXRvciK6AgoMU2hhcGVNZXNzYWdlEjEKBnNxdWFyZRgBIAEoCzIXLmFyZWFfY2FsY3VsYXRvci5TcXVhcmVIAFIGc3F1YXJlEjoKCXJlY3RhbmdsZRgCIAEoCzIaLmFyZWFfY2FsY3VsYXRvci5SZWN0YW5nbGVIAFIJcmVjdGFuZ2xlEjEKBmNpcmNsZRgDIAEoCzIXLmFyZWFfY2FsY3VsYXRvci5DaXJjbGVIAFIGY2lyY2xlEjcKCHRyaWFuZ2xlGAQgASgLMhkuYXJlYV9jYWxjdWxhdG9yLlRyaWFuZ2xlSABSCHRyaWFuZ2xlEkYKDXBhcmFsbGVsb2dyYW0YBSABKAsyHi5hcmVhX2NhbGN1bGF0b3IuUGFyYWxsZWxvZ3JhbUgAUg1wYXJhbGxlbG9ncmFtQgcKBXNoYXBlIikKBlNxdWFyZRIfCgtlZGdlX2xlbmd0aBgBIAEoAlIKZWRnZUxlbmd0aCI5CglSZWN0YW5nbGUSFgoGbGVuZ3RoGAEgASgCUgZsZW5ndGgSFAoFd2lkdGgYAiABKAJSBXdpZHRoIiAKBkNpcmNsZRIWCgZyYWRpdXMYASABKAJSBnJhZGl1cyJPCghUcmlhbmdsZRIVCgZlZGdlX2EYASABKAJSBWVkZ2VBEhUKBmVkZ2VfYhgCIAEoAlIFZWRnZUISFQoGZWRnZV9jGAMgASgCUgVlZGdlQyJICg1QYXJhbGxlbG9ncmFtEh8KC2Jhc2VfbGVuZ3RoGAEgASgCUgpiYXNlTGVuZ3RoEhYKBmhlaWdodBgCIAEoAlIGaGVpZ2h0IkQKC0FyZWFSZXF1ZXN0EjUKBnNoYXBlcxgBIAMoCzIdLmFyZWFfY2FsY3VsYXRvci5TaGFwZU1lc3NhZ2VSBnNoYXBlcyIkCgxBcmVhUmVzcG9uc2USFAoFdmFsdWUYASADKAJSBXZhbHVlMq0BCgpDYWxjdWxhdG9yEk4KDGNhbGN1bGF0ZU9uZRIdLmFyZWFfY2FsY3VsYXRvci5TaGFwZU1lc3NhZ2UaHS5hcmVhX2NhbGN1bGF0b3IuQXJlYVJlc3BvbnNlIgASTwoOY2FsY3VsYXRlTXVsdGkSHC5hcmVhX2NhbGN1bGF0b3IuQXJlYVJlcXVlc3QaHS5hcmVhX2NhbGN1bGF0b3IuQXJlYVJlc3BvbnNlIgBCHFoXaW8ucGFjdC9hcmVhX2NhbGN1bGF0b3LQAgFiBnByb3RvMw==", "protoFile": "syntax = \"proto3\";\n\npackage area_calculator;\n\noption php_generic_services = true;\noption go_package = \"io.pact/area_calculator\";\n\nservice Calculator {\n rpc calculateOne (ShapeMessage) returns (AreaResponse) {}\n rpc calculateMulti (AreaRequest) returns (AreaResponse) {}\n}\n\nmessage ShapeMessage {\n oneof shape {\n Square square = 1;\n Rectangle rectangle = 2;\n Circle circle = 3;\n Triangle triangle = 4;\n Parallelogram parallelogram = 5;\n }\n}\n\nmessage Square {\n float edge_length = 1;\n}\n\nmessage Rectangle {\n float length = 1;\n float width = 2;\n}\n\nmessage Circle {\n float radius = 1;\n}\n\nmessage Triangle {\n float edge_a = 1;\n float edge_b = 2;\n float edge_c = 3;\n}\n\nmessage Parallelogram {\n float base_length = 1;\n float height = 2;\n}\n\nmessage AreaRequest {\n repeated ShapeMessage shapes = 1;\n}\n\nmessage AreaResponse {\n repeated float value = 1;\n}\n" } }, "name": "protobuf", "version": "0.1.15" } ] }, "provider": { "name": "area-calculator-provider" } }```

matt.fellows
2023-02-15 23:29
Looks pretty good to my eye Ali!

matt.fellows
2023-02-15 23:31
> Is `interactionMarkup` required? if so, what is it supposed to be set to? I don?t think so, but when you have a fully functioning plugin I?d recommend populating it so tools can display the data in a user friendly way. e.g. in this quarter (or early next), we are planning to release plugin support in the PactFlow UI. It will be able to read the markdown contents and display it in our UI. You can choose to display the contract however makes sense, so long as it?s in markdown form (I think that?s all we currently support)

uglyog
2023-02-15 23:40
It supports Markdown or HTML, but I would recommend using Markdown.

ali.ustek
2023-02-16 14:03
OK, for now I'm going to ignore `interactionMarkup`

ali.ustek
2023-02-16 16:48
I'm trying to add the avro schema to PluginConfiguration, test log shows it on the payload but final pact file doesn't have it

ali.ustek
2023-02-16 16:48
what am I missing?

yousafn
2023-02-16 17:11
can see it in the logs, how are you adding it to the interaction in the configure interaction method?

ali.ustek
2023-02-17 00:23
Added it to the plugin pact configuration

ali.ustek
2023-02-17 07:39
Must have been some sort of caching issue within the IDE, clean build worked

ali.ustek
2023-02-28 23:36
@uglyog Hi, in `CompareContentsRequest.actual` and `CompareContentsRequest.expected` are of type `ByteString` . how are the values of those fields calculated. Can I just use `actualBody.getContent.toStringUtf8` to and use it to build the Avro message?

ali.ustek
2023-02-28 23:36
Or is it the plugin populating them somewhere else that I have to do?

matt.fellows
2023-02-28 23:45
Just FYI he?s off sick today.

matt.fellows
2023-02-28 23:45
My understanding is that `actual` is the actual bytes that were sent to the mock server from the test (i.e. what was actually sent from the users API client in the unit test) and that `expected` is what you configured in the `ConfigureInteraction` lifecycle method (i.e. what was configured in the test setup that you expected your code to send)

ali.ustek
2023-02-28 23:52
thx, Matt that helps

ali.ustek
2023-03-07 11:00
In Match Context, is the path for arrays supposed to contain the index?

ali.ustek
2023-03-07 11:03
In Content Matching response, what is supposed to be in the `ContentMismatch.actual` and `ContentMismatch.expected` ?

yousafn
2023-03-07 12:15
`ContentMismatch.actual` is the value the SUT sent, either captured by Pact (if its a supported transport) or the plugins mock server if its a new transport. `ContentMismatch.expected` is the value setup in the test interaction. so if you expected a body of `hello` , but the SUT sent `world` you would have something like. `{ContentMismatch : {expected: "hello", actual:"world"}}` rough example https://github.com/YOU54F/pluginopedia/blob/ca961ed3219671257328dfd8adaec51cdaab5c41/pact-plugin-template-swift/Sources/PactPlugin/PactPluginProvider.swift#L53-L79

yousafn
2023-03-07 12:18
`contentMismatch.path` ? I think so, as it will provide detail for the failure as to exactly where it occurs in the array

ali.ustek
2023-03-07 12:22
this path was the one in ContentMatchRequest, I think it's the one set in the configure init stage. so the question is really, should I set the path with index in configure init stage?

ali.ustek
2023-03-07 12:25
let me clarify, (I should really ask better questions), for the Avro plugin, each mismatch will be a field, do I put String representations of the Avro fields or Avro field itself

yousafn
2023-03-07 12:34
I would assume the former, a string representation so its human readable in the users console. if the actual message I got was base64 encoded, I would want to decode it before presenting it to the user (I think) so I saw `hello` not `aGVsbG8=`

yousafn
2023-03-07 12:34
I've got some time this week if you want to get some time together

ali.ustek
2023-03-07 12:35
both fields are ByteString, I assume it will be converted by the driver on the other side

ali.ustek
2023-03-07 12:35
having a session would be nice

yousafn
2023-03-07 12:42
Got a 9pm with Matt tonight if you wanted to gatecrash, he can take any q's offline for Ron ( I can invite Ron but he may be doing his morning run) otherwise we can get 30 mins in earlier. would be good to get it running on my machine so I can at least help alongside, if you could fire down the commands I'd need to run the tests from CLI that would be ace! I did have it but context switching like :sonic: atm

ali.ustek
2023-03-07 16:30
Let me see if I can make the 9PM today, I'll try

ali.ustek
2023-03-07 16:31
for now, I have the test automated `sbt test` will run all of them

uglyog
2023-03-07 22:30
Yes, because people could set matching rules against items in the array (I've never seen any, but who knows)

uglyog
2023-03-08 02:53
@ali.ustek just watched the recording of the catchup :-) ? For arrays, if the matching rules are to be applied to all items in the array, don't add the index (or add a `*`) ? If the matching rule is specific to one item in the array (i.e. it must only apply to the second item), use the index. But this is a very rare thing to do.


uglyog
2023-03-08 03:09
As to why it had this expression:

uglyog
2023-03-08 03:09
This is because your code was at the point where it was comparing the first address in the address list.

uglyog
2023-03-08 03:25
About the diff in `ContentMismatches`, it is optional, and if supplied will be displayed to the user. It is helpful in some contexts, but some times it just gets confusing. I have left it out of the protobuf plugin, because I'm lazy.

uglyog
2023-03-08 03:29
For the actual and expected values, these are meant to be the values that are being compared at that point. The idea was to display the error message, and then provide the expected and actual values. But it turned out most of the time, the message contained the values anyway, so they are a bit redundant.

uglyog
2023-03-08 03:31
I would add them (you can use the string version of the values) for simple fields, but leave them out of complex types.

ali.ustek
2023-03-08 10:26
thx a lot for the explanation

ali.ustek
2023-03-14 09:49
@yousafn my understanding is that the plugin only needs to be available locally. meaning it doesn't need to be uploaded to the pact broker, am I right?

ali.ustek
2023-03-14 09:51
Also, Do I need to enable V4 driver on the provider test? if so, how?

matt.fellows
2023-03-14 09:53
What do you mean by this? Any language that supports V4 should know how to run the verification z with the caveat they'll need the plugin installed in advance. Ron is currently improving this situation to autoinstall deps

ali.ustek
2023-03-14 09:54
on consumer side ` ```@PactTestFor(providerName = "order-provider", providerType = ProviderType.ASYNCH, pactVersion = PactSpecVersion.V4)``` `

ali.ustek
2023-03-14 09:54
```pactVersion = PactSpecVersion.V4``` is used to signify to use V4 pact

ali.ustek
2023-03-14 09:55
do I need to the same on procuer pact test

matt.fellows
2023-03-14 10:01
oh right, no shouldn?t be needed. A provider can support multiple consumers on different versions at the same time

ali.ustek
2023-03-14 10:01
thx

ali.ustek
2023-03-14 10:02
My provider test is failing but I don't see logs from the plugin

ali.ustek
2023-03-14 10:02
```09:42:14.391 [main] DEBUG a.c.d.pact.provider.ProviderVerifier - found class @au.com.dius.pact.provider.junitsupport.Provider("order-provider") @au.com.dius.pact.provider.junitsupport.loader.PactBroker(url="http://localhost:9292", host="${pactbroker.host:}", port="${pactbroker.port:}", scheme="${pactbroker.scheme:http}", tags={${pactbroker.tags:}}, consumerVersionSelectors={@au.com.dius.pact.provider.junitsupport.loader.VersionSelector(tag="${pactbroker.consumerversionselectors.tags:}", latest="${pactbroker.consumerversionselectors.latest:}", consumer="${pactbroker.consumers:}", fallbackTag="")}, consumers={${pactbroker.consumers:}}, authentication=@au.com.dius.pact.provider.junitsupport.loader.PactBrokerAuth(username="${pactbroker.auth.username:}", password="${pactbroker.auth.password:}", token="${pactbroker.auth.token:}", headerName="Authorization"), valueResolver=au.com.dius.pact.core.support.expressions.SystemPropertyResolver.class, enablePendingPacts="${pactbroker.enablePending:false}", providerTags={${pactbroker.providerTags:}}, providerBranch="${pactbroker.providerBranch:}", includeWipPactsSince="${pactbroker.includeWipPactsSince:}", enableInsecureTls="${pactbroker.enableInsecureTls:false}") class com.collibra.example.pulsar.avro.PactPulsarProducerTest 09:42:14.393 [main] DEBUG a.c.d.pact.provider.ProviderVerifier - found method [@au.com.dius.pact.provider.PactVerifyProvider("Order Created") public au.com.dius.pact.provider.MessageAndMetadata orderCreatedEvent()] 09:42:14.399 [main] DEBUG a.c.d.pact.provider.ProviderVerifier - Found methods = [public au.com.dius.pact.provider.MessageAndMetadata com.collibra.example.pulsar.avro.PactPulsarProducerTest.orderCreatedEvent() throws java.io.IOException] generates a message which has a matching body (FAILED) has matching metadata (OK) Failures: 1) Order Created: generates a message which has a matching body 1.1) body: / Actual body '? name-1??|A?????????street name Item-1 Item21' is not equal to the expected body '? name-1??|A?????????street name Item-1 Item-2' 09:42:14.720 [main] DEBUG a.c.d.p.p.DefaultTestResultAccumulator - Received test result 'Failed(results=[{attribute=body, description=Actual body '? name-1??|A?????????street name Item-1 Item21' is not equal to the expected body '? name-1??|A?????????street name Item-1 Item-2', identifier=/, diff=null, interactionId=857a381662884d96adb1cb05bc50788bf9d1ed65}], description=Body had differences)' for Pact order-provider-avro-consumer and Order Created (Pact Broker http://localhost:9292/pacts/provider/order-provider/consumer/avro-consumer/pact-version/d5c261bfc261542df7e0d1f0ba81810ef94bb192/metadata/c1tdW2N2XT05) 09:42:14.723 [main] DEBUG a.c.d.p.p.DefaultTestResultAccumulator - Number of interactions #1 and results: [Failed(results=[{attribute=body, description=Actual body '? name-1??|A?????????street name Item-1 Item21' is not equal to the expected body '? name-1??|A?????????street name Item-1 Item-2', identifier=/, diff=null, interactionId=857a381662884d96adb1cb05bc50788bf9d1ed65}], description=Body had differences)] 09:42:14.724 [main] DEBUG a.c.d.p.p.DefaultTestResultAccumulator - All interactions for Pact order-provider-avro-consumer have a verification result 09:42:14.724 [main] WARN a.c.d.p.p.DefaultTestResultAccumulator - Skipping publishing of verification results as it has been disabled (pact.verifier.publishResults is not 'true') 09:42:14.725 [main] DEBUG a.c.d.p.p.j.PactVerificationStateChangeExtension - afterEach for interaction 'Order Created'```

ali.ustek
2023-03-14 11:20
I've found the problem with my actual body and fixed it using trial and error. However, I don't see logs from the Avro plugin, currently it's using the `MessageAndMetadata` target and using matcher `http://au.com.dius.pact.core.matchers.Matching#matchBodyContents` not the matcher from the plugin what am I missing?


yousafn
2023-03-14 12:05
can you try with trace logs? if it doesn?t find the plug-in or there is an issue it falls back to the pact framework for matching

ali.ustek
2023-03-14 16:23
I don't see test trying to load the plugin at all

ali.ustek
2023-03-14 16:25
on consumer side following are needed,

ali.ustek
2023-03-14 16:25
```Map.entry("pact:avro", schemasPath), Map.entry("pact:record-name", "Order"), Map.entry("pact:content-type", "avro/binary"),```

ali.ustek
2023-03-14 16:25
do I need to populate them on provider side too>

yousafn
2023-03-14 17:31
I would expect it to pick it up from the data in your pact file, in the plugin configuration, and then call out to find the relevant plugin I'm not overly familiar with the jvm implementation https://github.com/pact-foundation/pact-jvm/blob/f858a1728ff54b8db13bd748c8846f49ddb66fa4/provider/lein/README.md?plain=1#L279 was that running with trace logs? Will ask Ron to take a look over our night (he is our JVM master)

ali.ustek
2023-03-14 20:59
the log I uploaded is with trace

yousafn
2023-03-14 22:08
Oh yes it is, apologies, could you share with us the pact file? I am wondering if it something with the linking of the interaction to the plugin configuration in `interactions.pluginConfiguration` and `metadata.plugins.configuration`

matt.fellows
2023-03-14 22:13
hmm strange

matt.fellows
2023-03-14 22:13
It should write the plugin configuration to the pact file, and then the provider will read the pact file and load in any plugins on verification

matt.fellows
2023-03-14 22:13
if the plugins don?t exist, it should error out complaining of the missing plugins

ali.ustek
2023-03-14 22:24
here is the pact file

uglyog
2023-03-14 22:25
Hmm, the plugin data is in the Pact file. Looks ok.

uglyog
2023-03-14 22:25
What version of Pact-JVM are you using?

yousafn
2023-03-14 22:33
I couldn't parse that file with jq until removing line 39

yousafn
2023-03-14 22:37
Using your pact's contents against pact-js plugin example https://github.com/pact-foundation/pact-js/blob/master/examples/v4/plugins/test/matt.provider.spec.ts It reads the pact file and starts looking for plugins (but can't find them - and pact-js core crashes but that is another issue) so it can read the pact file and recognise that it requires plugins (using the rust core) ```2023-03-14T22:33:48.076454Z INFO ThreadId(02) verify_provider_async: pact_verifier: Pact file requires plugins, will load those now 2023-03-14T22:33:48.078936Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Loading plugin PluginDependency { name: "avro", version: Some("0.0"), dependency_type: Plugin } 2023-03-14T22:33:48.081399Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Rust plugin driver version 0.2.2 2023-03-14T22:33:48.081427Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: load_plugin ThreadId(2): Waiting on PLUGIN_REGISTER lock 2023-03-14T22:33:48.085892Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: load_plugin ThreadId(2): Got PLUGIN_REGISTER lock 2023-03-14T22:33:48.087153Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Did not find plugin, will start it 2023-03-14T22:33:48.087179Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Loading plugin manifest for plugin PluginDependency { name: "avro", version: Some("0.0"), dependency_type: Plugin } 2023-03-14T22:33:48.092171Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Looking for plugin in "/Users/saf/.pact/plugins" 2023-03-14T22:33:48.093362Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found: "/Users/saf/.pact/plugins/.DS_Store" 2023-03-14T22:33:48.093717Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found: "/Users/saf/.pact/plugins/matt-0.0.7" 2023-03-14T22:33:48.093772Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found plugin manifest: "/Users/saf/.pact/plugins/matt-0.0.7/pact-plugin.json" 2023-03-14T22:33:48.096272Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Parsed plugin manifest: PactPluginManifest { plugin_dir: "", plugin_interface_version: 1, name: "matt", version: "0.0.7", executable_type: "exec", minimum_required_version: None, entry_point: "matt", entry_points: {}, args: None, dependencies: None, plugin_config: {} } 2023-03-14T22:33:48.096448Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found: "/Users/saf/.pact/plugins/protobuf-0.2.6" 2023-03-14T22:33:48.096933Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found plugin manifest: "/Users/saf/.pact/plugins/protobuf-0.2.6/pact-plugin.json" 2023-03-14T22:33:48.097300Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Parsed plugin manifest: PactPluginManifest { plugin_dir: "", plugin_interface_version: 1, name: "protobuf", version: "0.2.6", executable_type: "exec", minimum_required_version: None, entry_point: "pact-protobuf-plugin", entry_points: {}, args: None, dependencies: None, plugin_config: {"hostToBindTo": String("127.0.0.1"), "downloadUrl": String("https://github.com/protocolbuffers/protobuf/releases/download"), "protocVersion": String("3.19.1")} } 2023-03-14T22:33:48.097518Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found: "/Users/saf/.pact/plugins/protobuf-0.2.0" 2023-03-14T22:33:48.098275Z DEBUG ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Found plugin manifest: "/Users/saf/.pact/plugins/protobuf-0.2.0/pact-plugin.json" 2023-03-14T22:33:48.098430Z TRACE ThreadId(02) verify_provider_async: pact_plugin_driver::plugin_manager: Parsed plugin manifest: PactPluginManifest { plugin_dir: "", plugin_interface_version: 1, name: "protobuf", version: "0.2.0", executable_type: "exec", minimum_required_version: None, entry_point: "pact-protobuf-plugin", entry_points: {}, args: None, dependencies: None, plugin_config: {"hostToBindTo": String("127.0.0.1"), "protocVersion": String("3.19.1"), "downloadUrl": String("https://github.com/protocolbuffers/protobuf/releases/download")} } 2023-03-14T22:33:48.101216Z TRACE ThreadId(02) pact_ffi::verifier: pactffi_verifier_execute FFI function completed output=2```

ali.ustek
2023-03-14 22:43
I'm using ` ```"io.pact.plugin.driver" % "core" % "0.3.1"```

uglyog
2023-03-14 22:53
Ok, you are using the plugin driver directly? What are you using the run the verification tests?

ali.ustek
2023-03-14 23:10
I'm using ```"au.com.dius.pact.provider" % "junit5" % "4.5.2"```

uglyog
2023-03-14 23:39
Hmm, that is the correct version for using plugins

uglyog
2023-03-14 23:40
Let me investigate and see if it is a Pact-JVM issue


uglyog
2023-03-14 23:54
This needs to use `PluginTestTarget`

uglyog
2023-03-14 23:54
That knows how to start the plugins

uglyog
2023-03-14 23:55
This is a gRPC example: ```@BeforeEach void setupTest(PactVerificationContext context) { context.setTarget(new PluginTestTarget( Map.of( "host", "localhost", "port", server.serverPort(), "transport", "grpc" ) )); }```

uglyog
2023-03-15 00:02
But this is also a bug in Pact-JVM, it should always load any required plugins


yousafn
2023-03-15 00:10
teamwork makes the dreamwork, thanks Ron!

ali.ustek
2023-03-15 00:44
I'll add the workaround, thx Ron

ali.ustek
2023-03-15 00:48
by the way that information is not in the documentation site https://docs.pact.io/implementation_guides/jvm/provider/junit5


ali.ustek
2023-03-15 01:03
I've tried `http`, `https` and `grpc` but get failed: `java.lang.RuntimeException: Did not find a registered transport 'https', took 2.741s`

ali.ustek
2023-03-15 01:04
My plugin is not registering any transport by the way

uglyog
2023-03-15 01:07
Then it should just use `http`

uglyog
2023-03-15 01:08
Ok, let me fix the bug with the HTTP target, so you can use that one

uglyog
2023-03-16 06:05
@ali.ustek I have released Pact-JVM 4.5.3 will a fix for your issue

ali.ustek
2023-03-16 23:19
Hi @uglyog when running the provider test in Plugins `compareContents` method `request.getPluginConfiguration.interactionConfiguration` has no configuration, did I miss something?

matt.fellows
2023-03-17 02:47
Just FYI Ron is off today

ali.ustek
2023-03-17 03:25
NP, thx for letting me know

uglyog
2023-03-20 00:50
Hmm, it should have the interaction configuration that was added during the `configureInteraction` call

ali.ustek
2023-03-20 10:44
I'm not getting that, how do I debug, what class is responsible for it in the driver?


uglyog
2023-03-20 23:59
It logs out all the values, so you should see what it received back in your logs

ali.ustek
2023-03-21 03:07
In the logs I'm not getting logs on Line 479 and 481

ali.ustek
2023-03-21 03:14
put a break point on all `DefaultPluginManager` methods `invokeContentMatcher` got executed but not `configureContentMatcherInteraction`

uglyog
2023-03-21 03:20
Ok, let me just trace through Pact-JVM code just to make sure my understanding is correct, because I'm sure `configureContentMatcherInteraction` is called first

uglyog
2023-03-21 03:24
Oh, I'm digging around in the consumer code, but your dealing with the provider tests

uglyog
2023-03-21 03:30
`configureContentMatcherInteraction` is used on the consumer side to setup the interaction to be added to the Pact file, before the test is run. It won't be called when verifying the provider, because the interactions are loaded from the Pact file.

uglyog
2023-03-21 03:31
I think I need to write up a doco an these method calls to explain how they map to the Pact lifecycle.


ali.ustek
2023-03-21 03:33
OK, that make sense

uglyog
2023-03-21 03:33
Check the sequence diagram

ali.ustek
2023-03-21 03:34
I've already done the configure interaction, pact file has it

uglyog
2023-03-21 03:34
The second diagram in that doc shows the sequence of calls for provider verification

uglyog
2023-03-21 03:37
So coming back to your original question (sorry about all the confusion), the `interactionConfiguration` should be loaded from the interaction in the Pact file

ali.ustek
2023-03-21 03:38
let me re-generate the pact and try again

ali.ustek
2023-03-21 03:40
here is the pact file

ali.ustek
2023-03-21 03:40
does it look OK?

uglyog
2023-03-21 03:41
Yes, I would expect that `interactionConfiguration` gets populated with ```{ "record": "Order", "schemaKey": "885fa4ef2b2d4acfda5c6cbccb497be3" }```

uglyog
2023-03-21 03:43
If it is not, then there is another bug somewhere

ali.ustek
2023-03-21 03:44
nope, it's empty

ali.ustek
2023-03-21 03:44
if you want to connect, I can

uglyog
2023-03-21 03:45
BTW, would the `$.items.0.id` paths not be better as `$.items[*].id`? (i.e. apply to each item in the list)

ali.ustek
2023-03-21 03:45
for now, I've chosen the most easy way to populate

ali.ustek
2023-03-21 03:45
I'll optimise later

uglyog
2023-03-21 03:45
Yeah, that's a good strategy

uglyog
2023-03-21 03:45
connect?

ali.ustek
2023-03-21 03:46
zoom call

uglyog
2023-03-21 03:46
Oh, yeah, sure

uglyog
2023-03-21 03:46
Do you have time now?

ali.ustek
2023-03-21 03:46
if you want to see, that is

ali.ustek
2023-03-21 03:46
I'll have to be quiet as other are sleeping

uglyog
2023-03-21 03:47
We can do it at a better hour for you, it will give me some time to dig around and see if I can find something

ali.ustek
2023-03-21 03:48
sure we can do tomorrow

ali.ustek
2023-03-21 03:48
I can do your morning

uglyog
2023-03-21 03:50
8am my time would be 9pm your time, would that work for you?

uglyog
2023-03-21 03:57
I think I have found the problem. When verifying via the provider method call, it is not passing in the plugin config.

uglyog
2023-03-21 03:59
Sorry, I haven't tested this combination.


ali.ustek
2023-03-21 04:07
your 8am works for me, thx

ali.ustek
2023-03-21 04:08
oh, you've found the problem

ali.ustek
2023-03-21 04:09
I was going to say, pluginconfig is empty at `http://au.com.dius.pact.provider.ResponseComparison.kt:177`

uglyog
2023-03-21 07:41
4.5.4 is released, hopefully that fixes your issue


praveen.em
2023-03-24 08:15
has joined #avro

tonis.ojandu
2023-03-24 17:32
Hi all, Looking to contribute possibly. We here at Sympower are currently doing our Pulsar Avro async interaction contract testing with a temporary in-house band-aid tooling where we employ Avro Java POJO generators and Jackson JSON serialization. However, ideally we would prefer to move to pure Avro at some point. Especially, since we plan include python solutions to the mix. What is the state of Avro plugin development currently? I see there is some initial activity, but we are not sure how far things are along behind the scenes. We are hesitant at blindly starting any development from scratch, because there can already be something far along. However, if there is something ongoing, then we are open to supporting this effort.

ali.ustek
2023-03-25 06:33
Hi I've released an initial version of the plugin for testing purposes https://github.com/austek/pact-avro-plugin/releases/tag/v0.0.1

ali.ustek
2023-03-25 06:34
contributions are welcome

matt.fellows
2023-03-27 02:22
I will just make the point that Python does not yet support Plugins (requires it to be upgraded to use our shared core first before it can). You could do provider side verification using the CLI though.

tonis.ojandu
2023-03-27 15:05
Really nice work! I played around with the plugin today. Got it mostly working with our setup. Our consumers are able to produce contracts, our pact broker accepts them, our producer is able to download and execute against it, but it failed to fully match regex. I am sure we can get it working. There are few improvements in mind from initial testing: ? there is a small typo in the install shell. The `tgz` URL has an excess dash between letter `v` and version. ? it would be nice if there was an option to inject the relevant Avro schema from String. In our setup we sometimes don't have the schema available in the repo. We use generated POJO-s from dependency JAR-s that have schema as a static String field embedded in them. ? https://avro.apache.org/docs/1.11.1/idl-language/ support would also be nice. However, for us a solution for the previous would negate a need for this, since the code POJO generator converts it into the classical `.avsc` JSON format. ? It seems that my provider was doing the exact body matching, rather than regex matching. It is possible that this is just a missing feature currently or I am misusing it in some ways. Will dig deeper tomorrow. We are happy contribute to these and other changes. If we were to offer pull request would it be reasonable for you at this stage?

yousafn
2023-03-27 15:17
Awesome, thanks for taking a look at the plugin, I am sure Ali will appreciate the extra eyes and review. I am also sure he would appreciate pull requests, awesome to see people willing to contribute so soon :raised_hands:

ali.ustek
2023-03-27 15:18
@tonis.ojandu Contributions are wellcome

helenarodcal
2023-04-18 09:07
has joined #avro

joshua.ellis
2023-09-20 06:40
has joined #avro

ali.ustek
2023-11-29 06:55
@uglyog @matt.fellows Do I need to keep the version of the plugin up-to-date at https://github.com/pact-foundation/pact-plugins/blob/main/repository/repository.index#L752

ali.ustek
2023-11-29 06:56
is it possible to install latest or choose a version with `pact-plugin-cli` ?

ali.ustek
2023-11-29 06:56
Also, what is the recommended compression? zip/tgz ?

matt.fellows
2023-11-29 22:49
Hello! I think it does need a PR to update it if you want it in the index. Probably that could be automated?

matt.fellows
2023-11-29 22:49
> is it possible to install latest or choose a version with `pact-plugin-cli` ? (edited) Yes, I believe so. By default it installs the latest unless you specify the version


yousafn
2023-11-30 10:46
> Yes, I believe so. By default it installs the latest unless you specify the version Correct you need to specify the full url to an earlier release otherwise you will get the latest A version option could be nice as an argument to the CLI

yousafn
2023-11-30 10:53
approved but added a comment about jdk runtime version in the index :+1:

ali.ustek
2023-11-30 11:05
Hi Yousaf, as the new version is jus bug fixes and it's binary compatible, I didn't want to disturb the already published version

ali.ustek
2023-12-04 12:34
Hi, could this PR be merged?

yousafn
2023-12-04 13:05
Merged now @ali.ustek :+1: I?m not sure if we need a new version of the pact-plugin-cli publishing, if it contains the index directly, or if it just calls out to the gh repo for the file

yousafn
2023-12-04 13:06
actually don?t think so, looking at the last few releases of index updates, they didn?t coincide with a plugin cli publish

ali.ustek
2023-12-04 13:14
Hi, Yousaf,

ali.ustek
2023-12-04 13:14
thx for merging

ali.ustek
2023-12-04 13:14
no need to release the cli again

ali.ustek
2023-12-04 13:19
I'm getting ```Installing plugin avro version 0.0.4 2023-12-04T13:17:31.759814Z ERROR pact_plugin_cli: error - Did not find a matching file pattern on GitHub to install Error: ExitCode(unix_exit_status(1))```

yousafn
2023-12-04 13:24
same this works though and can?t see much diff between the releases and the entries in the index. ```pact-plugin-cli install avro -v 0.0.3``` checking again

yousafn
2023-12-04 13:52
This works `pact-plugin-cli install https://github.com/austek/pact-avro-plugin/releases/tag/v0.0.3` this does?t `pact-plugin-cli install https://github.com/austek/pact-avro-plugin/releases/tag/v0.0.4` Difference looks to be the archive format. `tar.gz` in 0.0.4 versus `zip` in 0.0.3

yousafn
2023-12-04 13:53
I can see that you changed it to zip in 0.0.3, but I would have imagined tar.gz/gz was supported as well


ali.ustek
2023-12-04 13:54
I thought it was supported

yousafn
2023-12-04 13:54
bundles must be zip

yousafn
2023-12-04 13:54
> ? For bundled plugins (like with Node.js or Java), you can use a Zip file. The file must be named `pact-${name}-plugin.zip` or `pact-${name}-plugin-${os}-${arch}.zip` if you have OS/arch specific bundles.

yousafn
2023-12-04 13:54
> For single executable plugins, the executable attached to the release must be gzipped and named in the form `pact-${name}-plugin-${os}-${arch}(.exe?).gz`


ali.ustek
2023-12-04 13:56
OK

ali.ustek
2023-12-04 13:56
I wanted to use tgz, so users don't have to make things executable, as it preserves the file mod

ali.ustek
2023-12-04 13:57
can we make feature request?

yousafn
2023-12-04 14:01
yeah, code is here where you can see the file look ups https://github.com/pact-foundation/pact-plugins/blob/f57ddf3e2f21afde0b50d4d1021ca009b001ab40/drivers/rust/driver/src/download.rs#L53 should be relatively trivial to update to look for tar.gz or zip


yousafn
2023-12-04 14:02
> I wanted to use tgz, so users don?t have to make things executable, as it preserves the file mod That makes total sense :+1:


yousafn
2023-12-07 16:16
Popped a PR in now

maciej.harapinski
2024-02-19 09:47
has joined #avro