Как мне отправить данные JSON на kafka, используя REST-прокси в Confluent?
Для моей диссертации бакалавра я пытаюсь отправить машинные данные (в данном случае исторические данные, отправленные с помощью сценария Python), используя http-соединение с kafka. Я использую платформу Confluent, работающую в Docker в системе Windows.
Используя скрипт python, я пытаюсь отправить данные в REST-прокси. Сначала я получил сообщения об ошибках относительно типа данных, которые мне удалось разрешить.
import pandas as pd
import csv, os, json, requests, time, datetime, copy, sys
if len(sys.argv) > 1:
bgrfc_value = str(sys.argv[1])
else:
print("No arguments for bgrfc given, defaulting to 'false'")
bgrfc_value = 'false'
if len(sys.argv) > 2:
filePath = str(sys.argv[2])
else:
filePath = "path"
if len(sys.argv) > 3:
batchSize = int(float(str(sys.argv[3])))
else:
batchSize = 10
# Build skeleton JSON
basejson = {"message": {"meta" : "", "data": ""}}
#metajson = [{'meta_key' : 'sender', 'meta_value': 'OPCR'},
# {'meta_key' : 'receiver', 'meta_value': 'CAT'},
# {'meta_key' : 'message_type', 'meta_value': 'MA1SEK'},
# {'meta_key' : 'bgrfc', 'meta_value': bgrfc_value}]
#basejson['message']['meta'] = metajson
url = "http://127.0.0.1:8082/"
headers = {'Content-Type':'application/json','Accept':'application/json'}
def assign_timestamps(batch):
newtimestamps = []
oldtimestamps = []
# Batch timestamps to list, add 10 newly generated timestamps to a list
for item in batch['tag_tsp'].values.tolist():
newtimestamps.append(datetime.datetime.now())
oldtimestamps.append(datetime.datetime.strptime(str(item), "%Y%m%d%H%M%S.%f"))
# Sort old timestamps without sorting the original array to preserve variance
temp = copy.deepcopy(oldtimestamps)
temp.sort()
mrtimestamp = temp[0]
# Replicate variance of old timestamps into the new timestamps
for x in range(batchSize):
diff = mrtimestamp - oldtimestamps[x]
newtimestamps[x] = newtimestamps[x] - diff
newtimestamps[x] = newtimestamps[x].strftime("%Y%m%d%H%M%S.%f")[:-3]
# Switch old timestamps with new timestamps
batch['tag_tsp'] = newtimestamps
return batch
# Build and send JSON, wait for a sec
def build_json(batch):
assign_timestamps(batch)
batchlist = []
for index, row in batch.iterrows():
batchlist.append(row.to_dict())
basejson['message']['data'] = batchlist
print(basejson)
req = requests.post(url, json = json.loads(json.dumps(basejson)), headers = headers)
print(req.status_code)
time.sleep(1)
while(True):
df = pd.read_csv(filePath, sep=";", parse_dates=[2], decimal=",", usecols = ['SENSOR_ID', 'KEP_UTC_TIME', 'VALUE'], dtype={'SENSOR_ID': object})
df = df[::-1]
df.rename(columns={'SENSOR_ID' : 'ext_id', 'KEP_UTC_TIME' : 'tag_tsp', 'VALUE' : 'tag_value_int'}, inplace=True)
# Fill list with batches of 10 rows from the df
list_df = [df[ i:i + batchSize] for i in range(0, df.shape[0], batchSize)]
for batch in list_df:
build_json(batch)
Скрипт отправляет данные, но в ответ я получаю код состояния 500.
1 ответ
Ваши значения заголовков не верны. Вам нужно установить Accept
а также Content-type
два заголовка, как указано ниже:
Accept: application/vnd.kafka.v2+json
Content-Type : application/vnd.kafka.json.v2+json
Также данные должны быть структурированы следующим образом:
{"records":[{"value":{<Put your json record here>}}]}
Например:
{"records":[{"value":{"foo":"bar"}}]}
Я считаю, что данные, которые вы помещаете в "значение", должны быть строкой. Примерно так будет работать:
{"records":[{"value":"{'foo':'bar'}"}]}
Если при чтении из своей темы вы получаете забавное сообщение, попробуйте закодировать свое сообщение с помощью кодировки base64. Исходная строка json после кодирования должна быть такой:
{"records":[{"value":"eyJmb28iOiJiYXIifQ=="}]}