JDBC Kafka Connect using multiple tables with resulting nested JSON and arrays - jdbc

Kafka Connect and JDBC Source Connector.
I am trying to get a nested JSON with arrays from the tables:
/* Create tables, in this case DB2 */
CREATE TABLE contacts(
contact_id INT NOT NULL GENERATED ALWAYS AS IDENTITY,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(contact_id)
);
CREATE TABLE phones(
phone_id INT NOT NULL GENERATED ALWAYS AS IDENTITY,
phone_no VARCHAR(20) NOT NULL,
phone_type VARCHAR(10) NOT NULL,
contact_id INT NOT NULL,
modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY(phone_id),
FOREIGN KEY (contact_id)
REFERENCES contacts(contact_id)
ON UPDATE NO ACTION
ON DELETE CASCADE
);
/* Insert some data */
INSERT INTO contacts(first_name, last_name)
VALUES
('John','Doe');
INSERT INTO phones(phone_no, phone_type, contact_id)
VALUES
('Johns phone #1','HOME',1),
('Johns phone #2','MOBILE',1),
('Johns phone #3','WORK',1);
The JSON I would like get out on Kafka topic via Kafka Connect is something like this (minor adjustments are possible):
{
"contact_id": 1,
"first_name": "John",
"last_name": "Doe",
"modified_at": "2022-03-16T13:33:04.276",
"phones":
[
{
"phone_id": 1,
"phone_no": "Johns phone #1",
"phone_type": "HOME",
"contact_id": 1,
"modified_at": "2022-03-16T13:33:05.101"
},
{
"phone_id": 2,
"phone_no": "Johns phone #2",
"phone_type": "MOBILE",
"contact_id": 1,
"modified_at": "2022-03-16T13:33:05.210"
},
{
"phone_id": 3,
"phone_no": "Johns phone #3",
"phone_type": "WORK",
"contact_id": 1,
"modified_at": "2022-03-16T13:33:05.673"
}
]
}
How can I do that with Kafka Connect (i.e. Kafka Connect config)?

The JDBC connector does not support arrays types.
You could write a VIEW that defines a JOIN between your tables, then query that in the connector, and this would create unique events, e.g.
Record 1
{
"contact_id": 1,
"first_name": "John",
"last_name": "Doe",
"modified_at": "2022-03-16T13:33:04.276",
"phone_id": 1,
"phone_no": "Johns phone #1",
"phone_type": "HOME",
"contact_id": 1,
"modified_at": "2022-03-16T13:33:05.101"
}
Record 2
{
"contact_id": 1,
"first_name": "John",
"last_name": "Doe",
"modified_at": "2022-03-16T13:33:04.276",
"phone_id": 2,
"phone_no": "Johns phone #2",
"phone_type": "MOBILE",
"contact_id": 1,
"modified_at": "2022-03-16T13:33:05.210"
}
You then would need to use a Stream Processing library to group-by contact_id, for example. Or you can use Debezium / JDBC Source on the individual tables, and do the JOIN in Kafka Streams / KSQL and create the arrays in there.

Related

How to get data from ManyToOne Entity in Java Spring Boot with id decrease after update field

When I updated an entity in Spring with id, my entity always displayed at the last of list. How can I do format this to a list with id decrease. Below is my example after updating
"educations": [
{
"id": 17,
"name": "NEU",
"major": "QTKD",
"fromDate": "12/11/2019",
"toDate": "12/11/2023",
"description": "123456"
},
{
"id": 5,
"name": "PTIT",
"major": "IT",
"fromDate": "12/11/2019",
"toDate": "12/11/2023",
"description": "123456"
}
],

How do i test create lead user case in Jmeter for muliple users

When user there is a new user (Identified through new Mobile No) then system store details and create an Unique ID for Customer,
But how to do performance testing for this scenario for 1000 Virtual Users, Only getting 1 Successful and others unsuccessful due to It required different Mobile No for each user
Request
{
"firstName": "Ankit",
"lastName": "Singh",
"mobileNumber": "8169089997",
"vehicleData": [
{
"registrationNumber": "UP32MX0505",
"vehicleType": "CAR"
},
{
"registrationNumber": "KA01HP8748",
"vehicleType": "BIKE"
}
],
"otherVehicles": [
{
"vehicleRegistrationNumber": "UP43Z0064",
"make": "Volvo",
"model": "Xc90",
"fuelType": "Hybrid (Electric + Petrol)",
"vehicleType": "CAR"
}
]
}
Response
{
"id": 331,
"mobileNo": "8169089997",
"firstName": "Ankit",
"lastName": "Singh",
"emailAddress": null,
"avatarId": null,
"profileImageUrl": null,
"gender": null,
"city": null,
"failedToSaveVehicles": []
}
How about using different mobile numbers for different users? For example you can consider using __threadNum() and __longSum() functions combination like replacing your 8169089997 with ${__longSum(8169000000,${__threadNum},)}
More information on JMeter Functions concept: Apache JMeter Functions - An Introduction

Is it possible to use cockroach gen_random_uuid() function inside JSON data while inserting into JSON datatype in cockroachDB

I am new to cockroach DB and was wondering if the below ask is possible
One of the columns in my table is of JSON type and the sample data in it is as follows
{
"first_name": "Lola",
"friends": 547,
"last_name": "Dog",
"location": "NYC",
"online": true,
"Education": [
{
"id": "4ebb11a5-8e9a-49dc-905d-fade67027990",
"UG": "UT Austin",
"Major": "Electrical",
"Minor": "Electronics"
},
{
"id": "6724adfa-610a-4efe-b53d-fd67bd3bd9ba",
"PG": "North Eastern",
"Major": "Computers",
"Minor": "Electrical"
}
]
}
Is there a way to replace the "id" field in JSON as below to get the id generated dynamically?
"id": gen_random_uuid(),
Yes, this should be possible. To generate JSON data that includes a randomly-generated UUID, you can use a query like:
root#:26257/defaultdb> select jsonb_build_object('id', gen_random_uuid());
jsonb_build_object
--------------------------------------------------
{"id": "d50ad318-62ba-45c0-99a4-cb7aa32ad1c3"}
If you want to update in place JSON data that already exists, you can use the jsonb_set function (see JSONB Functions).

Accomplish the select box Vuetify behavior into a text field

I want to accomplish the following, but using a textfield (v-text-field) input instead:
<v-select
:items="addresses"
label="Address Field"
item-value="id"
item-text="address_line1"
v-model="address_id"
>
</v-select>
The select box returns all the "address_line1" (item-text) values from the addresses array (:items) and the default selected value is the one that matches with address_id (v-model) in the zones array. The data comes from two arrays of objects, that are related and comes from two external API. I want a textfield with the related value, and because I want the user to be able to update the field freely.
zones: [
{
"id": 1,
"name": "Museum",
"description": "description",
"address_id": 1,
"branch_id": 1,
"parent_zone_id": 2,
"provider_id": 10
},
{
"id": 2,
"name": "Restaurant",
"description": "description",
"address_id": 2,
"branch_id": 1,
"parent_zone_id": 2,
"provider_id": 10
},
]
addresses: [
{
"id": 1,
"name": "Address Name",
"address_line1": "7210 Euismod Rd.",
"address_line2": null,
"address_line3": null,
"zip_code": "6301",
"city": "Some City",
"state_id": 3296,
"country_id": 238,
"latitude": "10.99710000",
"longitude": "63.91130000",
"user_id": 11
},
{
"id": 2,
"name": "Address Name 2",
"address_line1": "2110 Elmond St.",
"address_line2": null,
"address_line3": null,
"zip_code": "6301",
"city": "Some Other City",
"state_id": 3296,
"country_id": 238,
"latitude": "10.99710000",
"longitude": "63.91130000",
"user_id": 11
}
]
The only way I can think of, is by hidding the select box, which picks the value selected. And then ref the value to the input text field somehow.
In this use case, v-autocomplete might be useful for you. It allows you to type on the field freely and will actively search for the addresses as you type.
<v-autocomplete
:items="addresses"
label="Address Field"
item-value="id"
item-text="address_line1"
v-model="address_id"
></v-autocomplete>
Here's a sample demo.
Also, you might want to update your vuetify to the latest version (vuetify 2.3.10 as of now) because I have encountered problems in lower versions, specifically vuetify 2.0.1. The problem is that v-autocomplete's displayed text is not updating properly when you try to select an option that is equal to its v-model value. Fortunately, this is fixed in later versions.

zoho books custom function with deluge

I'm creating a custom function in zoho books that will create a record in zoho creator using payment record information from zoho books. I've been able to successfully create a record in zoho creator but I'm unable to get the invoice_id from the customer_payment map.
Unfortunately, there's no error being thrown.
Below is the code:
paymentMap = Map();
//set order to payment invoice id - this is not working
paymentMap.put("Order",customer_payment.get("invoices[0].invoice_id"));
paymentMap.put("Description",customer_payment.get("card_type"));
paymentMap.put("Payment_ZB_ID",customer_payment.get("payment_id"));
response = zoho.creator.createRecord("XXXXX","XX","Payment",paymentMap);
info response;
Below is the map that is available:
customer_payment
{
"payment_id": "11111111111111111",
"payment_number": "1",
"payment_number_prefix": "",
"payment_number_suffix": "1",
"documents": [],
"customer_id": "11111111111111111",
"customer_name": "John Doe",
"payment_mode": "Stripe",
"card_type": "visa",
"card_type_formatted": "Visa",
"date": "2019-03-04",
"date_formatted": "03/04/2019",
"account_id": "11111111111111111",
"account_name": "Stripe Clearing",
"account_type": "payment_clearing",
"account_type_formatted": "Payment Clearing Account",
"currency_id": "11111111111111111",
"currency_code": "USD",
"exchange_rate": 1,
"exchange_rate_formatted": "$1.00",
"amount": 1,
"amount_formatted": "$1.00",
"unused_amount": 0,
"unused_amount_formatted": "$0.00",
"bank_charges": 0.33,
"bank_charges_formatted": "$0.33",
"tax_account_id": "",
"is_client_review_settings_enabled": false,
"tax_account_name": "",
"tax_amount_withheld": 0,
"tax_amount_withheld_formatted": "$0.00",
"discount_amount": 0,
"discount_amount_formatted": "$0.00",
"description": "Stripe processing fees : $0.33 ",
"reference_number": "12345",
"online_transaction_id": "12345",
"settlement_status": "",
"settlement_status_formatted": "",
"invoices": [
{
"invoice_number": "11111111111111111",
"invoice_payment_id": "11111111111111111",
"invoice_id": "11111111111111111",
"amount_applied": 1,
"amount_applied_formatted": "$1.00",
"tax_amount_withheld": 0,
"tax_amount_withheld_formatted": "$0.00",
"discount_amount": 0,
"discount_amount_formatted": "$0.00",
"total": 1,
"total_formatted": "$1.00",
"balance": 0,
"balance_formatted": "$0.00",
"date": "2019-03-04",
"date_formatted": "03/04/2019",
"due_date": "2019-03-04",
"due_date_formatted": "03/04/2019",
"price_precision": 2,
"apply_date": "",
"apply_date_formatted": ""
}
],
"payment_refunds": [],
"last_four_digits": "1234",
"template_id": "11111111111111111",
"template_name": "Elite Template",
"page_width": "8.27in",
"page_height": "11.69in",
"orientation": "portrait",
"template_type": "elite",
"template_type_formatted": "Elite",
"attachment_name": "",
"can_send_in_mail": true,
"can_send_payment_sms": false,
"is_payment_details_required": true,
"custom_fields": [],
"custom_field_hash": {},
"imported_transactions": []
}
paymentMap.put("Order",customer_payment.get("invoices[0].invoice_id"));
Deluge does not throw an error here. Instead, when an element whose key is not available is being fetched, it throws a null.
The key used in ur code snippet invoices[0].invoice_id is not a valid key in the customer_payment map. So, this has been throwing a null value which would have populated as an empty (or no) value in Zoho Creator.
If you notice the customer_payment clearly, all invoices are available under the key "invoices".
invoices = customer_payment.get("invoices");// now invoices will have the list of invoices in customer_payment map
Assuming that the payment has only one invoice, the invoice ID can be extracted as below:
invoiceId = invoices.getJson("invoice_id");
It is also possible to extract the invoice ID as you have tried, like the below:
info customer_payment.get("invoices").get(0).get("invoice_id");
You can fetch invoice_id like this :
customer_payment = {"payment_id":"11111111111111111","payment_number":"1","payment_number_prefix":"","payment_number_suffix":"1","documents":{},"customer_id":"11111111111111111","customer_name":"John Doe","payment_mode":"Stripe","card_type":"visa","card_type_formatted":"Visa","date":"2019-03-04","date_formatted":"03/04/2019","account_id":"11111111111111111","account_name":"Stripe Clearing","account_type":"payment_clearing","account_type_formatted":"Payment Clearing Account","currency_id":"11111111111111111","currency_code":"USD","exchange_rate":1,"exchange_rate_formatted":"$1.00","amount":1,"amount_formatted":"$1.00","unused_amount":0,"unused_amount_formatted":"$0.00","bank_charges":0.33,"bank_charges_formatted":"$0.33","tax_account_id":"","is_client_review_settings_enabled":false,"tax_account_name":"","tax_amount_withheld":0,"tax_amount_withheld_formatted":"$0.00","discount_amount":0,"discount_amount_formatted":"$0.00","description":"Stripe processing fees : $0.33 ","reference_number":"12345","online_transaction_id":"12345","settlement_status":"","settlement_status_formatted":"","invoices":{{"invoice_number":"11111111111111111","invoice_payment_id":"11111111111111111","invoice_id":"11111111111111111","amount_applied":1,"amount_applied_formatted":"$1.00","tax_amount_withheld":0,"tax_amount_withheld_formatted":"$0.00","discount_amount":0,"discount_amount_formatted":"$0.00","total":1,"total_formatted":"$1.00","balance":0,"balance_formatted":"$0.00","date":"2019-03-04","date_formatted":"03/04/2019","due_date":"2019-03-04","due_date_formatted":"03/04/2019","price_precision":2,"apply_date":"","apply_date_formatted":""}},"payment_refunds":{},"last_four_digits":"1234","template_id":"11111111111111111","template_name":"Elite Template","page_width":"8.27in","page_height":"11.69in","orientation":"portrait","template_type":"elite","template_type_formatted":"Elite","attachment_name":"","can_send_in_mail":true,"can_send_payment_sms":false,"is_payment_details_required":true,"custom_fields":{},"custom_field_hash":{},"imported_transactions":{}};
invoices = customer_payment.getJson("invoices");
//info invoices;
invoiceId = invoices.getJSON("invoice_id");
info invoiceId;

Resources