Kafka Create Topic API Options for Non-Java Languages - apache-kafka

While you can create a topic via Java or Java-based languages (see here), there does not seem to be a clean way to do this without using Java. As a result, pure-language client APIs (like kafka-node, a pure JavaScript client) can't directly create topics. Instead, we have two options:
1) Use a hack like sending a metadata request to a topic -- if auto.create.topics.enable is set to true, then you can create a topic -- but only with the default configuration, no control over partitions, etc.
2) Write a wrapper around a Java-based client just for topic creation. The easiest way to do this is to exec the script bin/kafka-topics.sh with command line arguments, which is ugly, to say the least.
Is there a better way to do this, though? There's a pure-JavaScript client for Zookeeper, node-zookeeper-client, what happens if I manipulate broker / partition info directly in Zookeeper?
Any other thoughts?

You can now use REST Proxy API v3 to create Kafka topics with http requests for non-Java languages.
According to the Confluent REST Proxy API Reference the creation of a topic is possible with the REST Proxy API v3 that is currently available as a preview feature.
"The API v3 can be used for evaluation and non-production testing purposes or to provide feedback to Confluent."
An example of a topic creation request is presented below and documented here:
POST /v3/clusters/cluster-1/topics HTTP/1.1
Host: kafkaproxy.example.com
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"attributes": {
"topic_name": "topic-1",
"partitions_count": 2,
"replication_factor": 3,
"configs": [
{
"name": "cleanup.policy",
"value": "compact"
}
]
}
}
}
Using curl:
curl -X POST -H "Content-Type: application/vnd.api+json" -H "Accept: application/vnd.api+json" \
--data '{"data":{"attributes": {"topic_name": "topic-1", "partitions_count": 2, "replication_factor": 1, "configs": [{"name": "cleanup.policy","value": "compact"}]}}}' \
"http://localhost:8082/v3/clusters/<cluster-id>/topics"
where the cluster-id can be identified using
curl -X GET -H "Accept: application/vnd.api+json" localhost:8082/v3/clusters

Related

How to set default namesevers for a Google Cloud DNS zone?

I'm using Google's CloudDNS API to batch upload a bunch of domains to Google Cloud. I want to be able to override the default nameservers that Google randomly assigns for example
ns-cloud-e1.google.com
ns-cloud-e2.google.com
ns-cloud-e3.google.com
ns-cloud-e4.google.com
to
n1.domain.com
n2.domain.com
n3.domain.com
I've noticed that Google's CloudDNS API's documentation references the following
nameServerSet (string) -
Optionally specifies the NameServerSet for this ManagedZone. A
NameServerSet is a set of DNS name servers that all host the same
ManagedZones. Most users will leave this field unset.
Though when trying to use this property via the CloudDNS, I receive a response from the API saying that the data provided through data is invalid. I passed through in the format of "n1.domain.com.,n2.domain.com.,n3.domain.com.". I've also tried passing through an array of nameservers and a RecordResourceSet class from the Google PHP package, with no avail.
Is this the correct format I should be following or is it not possible to pre-define the nameservers when the managed zone is created and instead have to do this after the zone is created?
Code example below, $cloud_dns->service is an instance of Google_Service_Dns
$cloud_dns->service->managedZones
->create(
'blah',
new Google_Service_Dns_ManagedZone([
'dnsName' => $dns_name_formatted,
'name' => 'app-' . $domain_name,
'description' => 'Batch Uploaded Domain',
'nameServerSet' => 'n1.domain.com.,n2.domain.com.,n3.domain.com.'
]),
);
You may wish to consider filing this issue with Google's public Issue Tracker.
You're not the first to encounter this and that question is 4 years old and remains unanswered :-(
Regardless of language SDK, the underlying call can be tested using Google's APIs Explorer and specifically ManagedZones:create which conveniently includes the relevant API method. You can plug in your values and try it out (securely) within the browser, or:
NAME="yourdomain-com"
DNS="yourdomain.com." # Must end with a period (.)
TOKEN=$(gcloud auth print-access-token)
curl \
--request POST \
--header "Authorization: Bearer ${TOKEN}" \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--data "{\"nameServerSet\":\"n1.domain.com.,n2.domain.com.\",\"name\":\"${NAME}\",\"dnsName\":\"${DNS}\",\"description\":\"\"}" \
"https://dns.googleapis.com/dns/v1/projects/${PROJECT}/managedZones"
I tried to craft a request using nameServerSet using the API directly and am unable. It's thus not a language SDK issue but a question of whether|how this property may be set.
It's somewhat interesting to note that you can't set name servers when creating zones through the console (link). But, you may subsequently change them. The console POSTs to ManagedZone:changes, e.g.:
POST https://www.googleapis.com/dns/v1beta2/projects/${PROJECT}/managedZones/${NAME}/changes
{
"additions": [
{
"name": "...",
"type": "NS",
"ttl": 21600,
"rrdatas": [
"ns-cloud-d1.googledomains.com.",
"ns-cloud-d3.googledomains.com.",
"ns-cloud-d4.googledomains.com."
]
}
],
"deletions": [
{
"name": "...",
"type": "NS",
"ttl": 21600,
"rrdatas": [
"n1.domain.com.",
"n2.domain.com.",
"n3.domain.com."
]
}
]
}

When Iot Agent sends data within milliseconds, the values are not notified to Draco subscription

Our device sends millisecond level telemetry data to Fiware. The payload contains DeviceId, DeviceDateTime and Attribute values as follows:
{"humidity":50.5,"device_id":"WS-100","devicetime":"2020-06-08T17:38:35.629+5:30"}
But we have observed that millisecond level tracking is not available in MongoDB and also Fiware does not notify the Draco subscription when data received at millisecond level. It only sends one payload per second. This is our Draco subscription:
curl -iX POST \
'http://52.172.34.29:1026/v2/subscriptions?options=skipInitialNotification' \
-H 'Content-Type: application/json' \
-H 'fiware-service: openiot' \
-H 'fiware-servicepath: /' \
-d '{
"description": "Subscription",
"subject": {
"entities": [
{
"idPattern": ".*"
}
],
"condition": {
"attrs": []
}
},
"notification": {
"http": {
"url": "http://52.172.34.29:3003/v2/notify"
},
"attrs": [],
"onlyChangedAttrs":true,
"throttling": 5
}
}'
Can you please let us know how to handle this millisecond changes in Orion subscription.
Thanks!
Milliseconds support is part of Orion backlog (see issues #3412, #2670 and #432) but it has not been implemented yet. I know there are people in the FIWARE community working on this feature, but I don't know when it will be available.
However, even if Orion doesn't support milliseconds natively, the application always has the option to manage it itself. For instance, using a devicetimeMs which value is an integer with time in milliseconds, included along with the other data when you send a telemetry measure. This is the typical workaround.
UPDATE: milliseconds support for DateTime attributes and metadata has been implemented. The feature will be avaiable in next Orion version (2.5.0) but it can be used right now if you get :latest container from dockerhub.

How to create topics from command line in Kafka REST proxy

I am using Kafka rest proxy, but not whole Confluent Platform just Kafka rest with my Kafka brokers. But I am not able to create topics from command line by the following command.
bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test.
I want to know is there any other way out.
The command you have tried out is not meant to interact with the REST Proxy Server of Kafka, but rather interacting with the Kafka cluster directly.
According to the Confluent REST Proxy API Reference the creation of a topic is only possible with the REST Proxy API v3 that is currently available as a preview feature.
"The API v3 can be used for evaluation and non-production testing purposes or to provide feedback to Confluent."
An example of a topic creation request is presented below and documented here:
POST /v3/clusters/cluster-1/topics HTTP/1.1
Host: kafkaproxy.example.com
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json
{
"data": {
"attributes": {
"topic_name": "topic-1",
"partitions_count": 2,
"replication_factor": 3,
"configs": [
{
"name": "cleanup.policy",
"value": "compact"
}
]
}
}
}
Using curl:
curl -X POST -H "Content-Type: application/vnd.api+json" -H "Accept: application/vnd.api+json" \
--data '{"data":{"attributes": {"topic_name": "topic-1", "partitions_count": 2, "replication_factor": 1, "configs": [{"name": "cleanup.policy","value": "compact"}]}}}' \
"http://localhost:8082/v3/clusters/<cluster-id>/topics"
where the cluster-id can be identified using
curl -X GET -H "Accept: application/vnd.api+json" localhost:8082/v3/clusters

Sonos Cloud API HTTP POST always returns 500

I'm trying to control my Sonos One (Gen 1) speaker through cloud APIs but all the POST request return 500 Internal Server Error without error message.
I generated an access_token as described in the documentation and was able to obtain information about the 'households' inside my network, finally both the group id and the player id.
I tried to obtain information about the status of the group by performing a GET on the following endpoint and it worked:
https://api.ws.sonos.com/control/api/v1/groups/{{group_id}}/playback
Same with other GET requestes (e.g. groupVolume).
The problem arise when I try to make a POST (e.g. changing the volume or playing an audioClip), it returns 500 Internal Server Error without any body.
For all the requests I am using Postman including as Headers:
Content-Type: application/json
Authorization: Bearer [token]
Content-Length: ??? (automatically inserted by postman)
while for the body of the change volume request I select the raw option and then select JSON(application/json) option.
The body is:
{
"volume": 80
}
The endpoint is the following: https://api.ws.sonos.com/control/api/v1/groups/{{group_id}}/groupVolume
I also tried controlling the player with node (Package) and it works.
Also tried to use Wireshark to see what requests the node-sonos package is performing but it seems it's not using the Cloud APIs.
I expect the player to change volume, but the API doesn't do anything and doesn't return any error message.
EDIT:
The cURL request from POSTMAN is the following:
curl -X POST \
https://api.ws.sonos.com/control/api/v1/players/<playerID>/audioClip \
-H 'authorization: Bearer XXX' \
-H 'cache-control: no-cache' \
-H 'content-type: application/json' \
-H 'postman-token: XXX' \
-d '{
"appId": "edu.myInstitute.myName",
"clipType": "CUSTOM",
"name": "Test",
"streamUrl": "http://...mp3_file_url"
}'

Couchbase create document fails through sync-gateway public rest API

As per Couchbase Sync-Gateway REST API documentation here below mentioned cURL should create a document in the specified database.
Below is the generated cURL from Postman.
curl -X PUT -H "Cache-Control: no-cache" -H "Postman-Token: 498d0fb6-77ac-9335-2379-14258c6731c7" -d '' "http://192.168.244.174:4984/db/"
I also tried adding JSON to the body of the request.
But when I send the put request through Postman, instead of creating a new document, it tries to create a new database and the JSON response is
{
"error": "Precondition Failed",
"reason": "Database already exists"
}
Am I missing something or it was a bug? Is there any other way to create a document to sync gateway?
There is a mistake in the documentation.
As per documentation,
You can either specify the document ID by including the _id object in the request message body, or let the software generate an ID.
But Couchbase REST API does not seem to work like that (may be they are not updating their documentation regularly). You need to provide the id in the URL like /{db}/{id}.
The below cURL worked for me.
curl -X PUT -H "Content-Type: application/json" -H "Cache-Control: no-cache" -H "Postman-Token: 75ab844e-5130-708e-69e9-e87f878108b4" -d '{"name": "xxx",
"full_name": "xxx yyy"}' "http://192.168.244.174:4984/db/123"
JSON response is
{
"id": "123",
"ok": true,
"rev": "1-9324dabc947fc963a754b113d1215ac3"
}