Hi all! I wanted to know if PactFlow supports Data...
# pactflow
p
Hi all! I wanted to know if PactFlow supports Database as well. Like if our PROVIDER is Java Based Kafka Service and it is calling SP on database CONSUMER SIDE for certain tasks. Can we have contract testing implemented between the two?
m
As in, can you contract test between an application and a database? Probably technically yes, but it's not common
I'll see if I can dig up any resources
p
@Matt (pactflow.io / pact-js / pact-go) Were you able to find anything on this?
m
sorry, it’s in a private chat I think. @Yousaf Nabi (pactflow.io) did you have anything public on this one?
y
hmmm, if you are just testing the message, then fact its a database shouldn’t matter. I made some noddy example of using postgres and logical replication, to ensure that the correct json message is being emitted from the database (which would be consumed into a kinesis stream, transformed and sent to s3 - as the full flow) https://github.com/YOU54F/pact-logical-replication/tree/main • consumer https://github.com/YOU54F/pact-logical-replication/blob/main/message_pact_js/message.consumer.test.ts • provider https://github.com/YOU54F/pact-logical-replication/blob/main/message_pact_js/message.provider.test.ts
I don’t think we get asked about it very often, especially as changes to our stored procs in databases, were covered with a large suite of unit tests for psql which covered migration paths, but it would still be possibly to say remove a field from a SP that a consumer relied on
🙌 1
m
ah yes, the logical replication - that’s what I couldn’t remember. thanks
p
Apologies for the late reply on this. @Yousaf Nabi (pactflow.io) In my scenario, we have a java based kafka messaging system which calls an SP from the database team and the SP helps store the message into DB. I wanted to know HOW the database would act as a Consumer/Provider in this scenario? How would be publish/verify results from Database side to the pact broker?
m
See the examples above for Kafka. Same principle. I don't think it's a good use case tho tbh
p
Can you elaborate on why its not a good use case? I am trying to understand that myself so that I can make my leads understand it as well.
m
There are a few reasons, but the main one is that, usually, a database only has a relationship to one system. It’s an anti-pattern to have multiple systems talk to the same database (because that’s what leads to breaking changes - a schema change). So usually, only one system “manages” the database. It’s an implementation detail abstracted by an API (one over a network boundary or otherwise) In that case, you can test using other means (unit tests and integration tests of the system) Maybe you could describe the scenario in a bit more detail.
we have a java based kafka messaging system which calls an SP from the database team and the SP helps store the message into DB.
Is the database is implementation detail in this scenario? The contract sounds like it’s between the SP and kafka producer(s). Who’s reading from the db, if any? Are they reading via a public API or reaching into the database? What kind of database is it? a better question - what problems are you facing or what problems are you looking to prevent?
p
Well, the Java Kafka project sends minimal information in the payload... and this SP in the database project creates new payload using the minimal information from the Kafka Project and puts in to a AQ. There is a job which is scheduled BU wise. Whenever there is READY message in the AQ it consumes the data and stores the data in DB tables.
m
Perhaps a diagram would help, I think a few concepts are unclear here. What is SP and BU? These aren't familiar to me
y
Kafka Service (Publisher) publishes events to a (AQ) active queue, in this case a READY message DB Service has a SP (stored procedure) which is • triggered by the READY message on the AQ • takes the payload and performs a database action You want to assert that Kafka -> Ready Message -> AQ AQ -> SP -> DB You would want to replay the message to the AQ (probably being agnostic of the queuing mechanism, so having something that can construct the message for the DB, without knowing about kafka, Pact can then provide this the event to pass to your SP handler) Your DB does it’s thing and successfully returns, so Pact is happy You can assert on your DB state after executing the verification. Having a setup and teardown based on the state would be valuable. It’s a bit messy though - one there is alot of moving parts and this would probably be better tested closer to the DB. I feel its actually more complicated because the consumer of these messages (the SP would be the one generating the Pact files) - and the producer - the kafka service would verify it would send them. That’s the inverse of consumer/provider paradigm for HTTP. The SP as a consumer would need to generate pacts for all its possibly many producers.
🙌 1
It’s an anti-pattern to have multiple systems talk to the same database (because that’s what leads to breaking changes - a schema change). So usually, only one system “manages” the database. It’s an implementation detail abstracted by an API (one over a network boundary or otherwise) In that case, you can test using other means (unit tests and integration tests of the system)
I’ve seen this a few times, where business logic is applications is directly tied to database schemas, and it gets painful, quickly
✅ 1
So in a previous org, we have stored procs in a postgres database, we used PGTap to test all of our migrations would apply, and that our stored procs would work as expected. These were tested in isolation. We would use logical replication, which would cause json messages to be spat out, whenever the DB was touched (app updates, inserts etc) These messages would be picked up by Kinesis -> Lamda (Transforms) -> S3 (Store) They were later ingested by other systems. For the PG -> Kinesis, we would use a test database, with the logical replication setup, and trigger inserts/updates into the db, and check the kinesis handler could process them, in component integration tests. We then separately tested our transform layer, that it could handle the expected kinesis payloads, and convert to the expected format consumers required, who would pick up the transformed data. That is why I wrote the logical replication stuff with Pact, as I could see an opportunity to capture those contracts between each hop, just to help increase the confidence, which retaining the speed of testing these in insolation. We still had integration tests that tested both subcutaneously (tested via API calls) and via the UI, that exercised all the systems moving parts. (We had some external deps, both in the org and third party to deal with as well)
Some of the effort we went through to test locally, didn’t pay off, as some of the for example serverless-offline and localstack, were close but not quite compared to the real infra, so there were some compromises in the confidence, which increased as the project grew in scale. We then switched to considering more ephemeral environments on PR’s so that we could test our changed bit of an application, with all the real infra (things like aurora, serverless and configurable/modular apps meant we could point them to different apps/services ) Separately there was a-lot of work done to consider atomic transactions, and journals of system activities, especially with EDA, as there was alot of failure points and we didn’t want our system transactions in a half enacted state
👍 1