WSO2 stream processor, json error "contains missing attributes" with kafka - apache-kafka

I am using kafka to get data to WSO2 stream processor in Json format, but I am getting the error "contains missing attributes.Hence dropping the message" error on every json file I send to wso2 kafka topic.
I have downloaded latest JSON siddhi connector "https://store.wso2.com/store/assets/analyticsextension/details/0e6a6b38-f1d1-49f5-a685-e8c16741494d" and replaced in my wso2/lib directory.
I don't get any error if I run this on simulator but only when events are published to kafka topic manually.
Below is my WSO2 Stream processor code:
#App:name('Transaction json')
/*
TransactionStream definition. It receives events from "kafka_topic" in json format.
*/
#source(type = 'kafka', topic.list = 'kafka_topic', partition.no.list = '0', threading.option = 'single.thread', group.id = 'group', bootstrap.servers = 'localhost:9092',
#map(type = 'json',enclosing.element='$',
#attributes(code = "code", name = "name",desc = "desc",transRefId ="transRefId",origAmount ="origAmount",amount = "amount",currency = "currency",requestId = "requestId",redeemedCashcode = "redeemedCashcode", sender_id ="sender.id",sender_name = "sender.name", sender_phone = "sender.phone",sender_pocket = "sender_pocket",sender_client = "sender.client",receiver_id = "receiver.id",receiver_name = "receiver.name",receiver_phone = "receiver.phone",receiver_pocket = "receiver.pocket",receiver_client = "receiver.client",beneficiary_phone = "beneficiary.phone",receiver_client = "receiver.client",beneficiary_phone = "beneficiary.phone",beneficiary_name = "beneficiary.name",beneficiary_nric = "beneficiary.nric",depositor_phone = "depositor.phone",depositor_name = "depositor.name",depositor_nric = "depositor.nric",offer = "offer",service = "service" , message = "message",status = "status",processedBy_id = "processedBy.id",processedBy_name = "processedBy.name",processedBy_phone = "processedBy.phone",processedBy_client = "processedBy.client",processedBy_owner = "processedBy.owner",processedAt = "processedAt",fees_debitFee = "fees.debitFee",fees_creditFee = "fees.creditFee",deviceId = "deviceId",isRefund ="isRefund",oldTransRefId = "oldTransRefId",linkBankTrans_err = "linkBankTrans.err",linkBankTrans_message = "linkBankTrans.message",linkBankTrans_data = "linkBankTrans.data",linkBankTrans_status = "linkBankTrans.status",linkBankTrans_request_url = "linkBankTrans.request.url",linkBankTrans_request_requestParams = "linkBankTrans.request.requestParams",linkBankTrans_action = "linkBankTrans.action",bankAccountNo = "bankAccountNo",transType = "transType",devGrp = "devGrp",createdAt = "createdAt",updatedAt = "updatedAt")))
define stream TransactioninputStream (code string, name string, desc string, transRefId string, origAmount float, amount float, currency string, requestId string, redeemedCashcode string, sender_id string, sender_name string, sender_phone string, sender_pocket string, sender_client string, receiver_id string, receiver_name string, receiver_phone string, receiver_client string, beneficiary_phone string, beneficiary_name string, beneficiary_nric string, depositor_phone string, depositor_name string,depositor_nric string, offer string, service string, message string, status string, processedBy_id string, processedBy_name string, processedBy_phone string, processedBy_client string, processedBy_owner string,processedAt string, fees_debitFee float, fees_creditFee float, deviceId string, isRefund string, oldTransRefId string, linkBankTrans_err string, linkBankTrans_message string, linkBankTrans_data string, linkBankTrans_status string, linkBankTrans_request_url string, linkBankTrans_request_requestParams string, linkBankTrans_action string, bankAccountNo string, transType string, devGrp string, createdAt string);
Reference Json:
{
"cd": "acb235dd",
"name": "Newtest",
"desc": "testing env",
"ref": "3232d3dew3",
"ora": 500000,
"amount": 500000,
"curr": "INR",
"sen": {
"id": "fdgdfgv",
"name": "dao",
"phone": "8268826483",
"pocket": "bde4gvfdgd3fd",
"cl": "try"
},
"rec": {
"id": "fsfsgfs3322",
"name": "mmv",
"phone": "76288373",
"pocket": "null",
"cl": "test"
},
"bef": {
"phone": "null",
"name": "null",
"ic": "null"
},
"dep": {
"phone": "null",
"name": "null",
"ic": "null"
},
"offer": "htgdte44",
"service": "gdrgdrgdv34",
"status": "done",
"prb": {
"id": "fdgdgd",
"name": "test",
"phone": "frgvrd",
"cl": "test",
"owner": "null"
},
"processedAt": {
"$date": "2019-09-19T10:17:05.377+0000"
},
"fees": {
"debitFee": 0,
"creditFee": 0,
},
"dId": "vdsvdd433",
"anumb": "xxxx6452",
"ttype": "normal",
"devGrp": 0,
"createdAt": {
"$date": "2019-09-19T10:17:05.381+0000"
},
"updatedAt": {
"$date": "2019-09-19T10:17:05.381+0000"
},
"_id": {
"$oid": "5d8355a1a3b8053cb768eea8"
},
"bankTrans": {
"err": "0",
"message": "successfully!",
"data": "fbsvbsgfiyshiu39",
"status": 0,
"request": {
"url": "http://localhost/testing",
"requestParams": "89743874023804832084093278327082384-329-4932-r-98-384-83-24"
},
"action": "testing"
}
}

This happens when some of the attributes are missing in the message. Here in the sample message, there is no code attribute. That's why the messages are dropped. However, you can ask siddhi JSON mapper to process messages even if attributes are missing using, fail.on.missing.attributes=false. Please see API docs of JSON mapper https://siddhi-io.github.io/siddhi-map-json/api/5.0.5/

Related

How to reference two different collections of same db based on object_id in mongo and fastapi

my schema for two collections.
class SectionModel(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
name: str = Field(max_length=50)
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
json_encoders = {ObjectId: str}
schema_extra = {
"example": {
"name": "",
}
}
class FaqModel(BaseModel):
id: PyObjectId = Field(default_factory=PyObjectId, alias="_id")
section_id:str
question:str = Field(max_length=50)
answer:str = Field(max_length=100)
class Config:
allow_population_by_field_name = True
arbitrary_types_allowed = True
json_encoders = {ObjectId: str}
schema_extra = {
"example": {
"section_id": "",
"question": "",
"answer": "",
}
}
my endpoint to create/add data
#router.post("/section",tags=["FAQ"])
def create_section(data: SectionModel = Body(...)):
try:
data = jsonable_encoder(data)
new_section = crud.create_section(data=data)
return {"success":True}
my crud method
def create_section(data):
data = db["sections"].insert_one(data)
return data
my db looks like this after adding data
db.sections.find().pretty();
[
{
_id: '63e4a4d9304637ec1b578136',
name: 'karnataka'
},
{
_id: '63e4c2056f1845a3fc2180c5',
name: 'Cricket'
}
]
db.faqs.find().pretty();
[
{
_id: '63e4cd7a1fdf5ee828bb33b9',
section_id: '63e4a4d9304637ec1b578136',
question: 'how many districts are in karnataka',
answer: '31'
},
{
_id: '63e4cd7a1fef5ee828c2b83b7',
section_id: '63e4c2056f1845a3fc2180c5',
question: 'who is called as hitman',
answer: 'Rohit sharma'
}
]
in faqs collection i am storing section_id as string and not referenced anywhere. if it is correct way then how to fetch response like,
{
"section": ["karnataka", "Cricket"],
"faq": {
"karnataka": [{
"question": "how many districts are in karnataka",
"answer": "31"
}, {
"question": "q2",
"answer": "ans2"
}],
"Cricket": [{
"question": "who is called as hitman",
"answer": "rohit sharma"
}, {
"question": "q4",
"answer": "ans4"
}]
}
}
if not this way means how to reference from the model and achieve this.
Thanks for input.

Duplicate error even though collection is empty

I try to insert multiple documents into my MongoDB collection, but whatever I do, I get a duplicate error. I made sure that there should be no duplicates possible by dropping the whole collection.
I tried it with .insertMany(), .save(), .create() - none of them do work. Though the docs get inserted, I still get the duplicate error 11000.
My function to insert the docs:
Words.prototype.addManyGeneralWordsEN = async function(words) {
await generalWordEN.create(words).then((res) => {
console.log(res)
})
.catch((err) => {
console.log(err.code)
})
}
// add words to database
await this.addManyGeneralWordsEN(wordsToAdd)
My schema:
const generalWordENSchema = new mongoose.Schema(
{
german: {
type: String,
required: true
},
english: {
type: String,
required: true
},
partOfSpeech: {
required: true,
type: String
},
example: {
default: null,
type: String,
},
defintion: {
default: null,
type: String,
},
image: {
default: null,
type: String,
},
audio: {
default: null,
type: String,
},
level: {
default: null,
type: Number,
},
}
)
generalWordENSchema.index({ german: 1, english: 1, partOfSpeech: 1}, { unique: true })
module.exports = generalWordENSchema
My sample data:
[
{
"english": "clothes",
"german": "Kleidung",
"partOfSpeech": "noun",
"example": "My wife's wardrobe is filled with beautiful clothes.",
"definition": "",
"image": "",
"audio": "",
"level": ""
},
{
"english": "men's clothing",
"german": "Herrenbekleidung",
"partOfSpeech": "noun",
"example": "Men's clothing is on the second floor.",
"definition": "",
"image": "",
"audio": "",
"level": ""
}
]
The problem is probably on this line
generalWordENSchema.index({ german: 1, english: 1, partOfSpeech: 1}, { unique: true })
You created an index for the collection and used partOfSpeech as unique, but you have two documents with the same value noun.
It should work if you change it to:
generalWordENSchema.index({ german: 1, english: 1 }, { unique: true });
You also have a typo on the Schema declaration that might cause you different issues. You typed defintion instead of definition.

Converting list of map to a list of objects in dart

I am making a request to an API which returns me a response.
final response = await http.get(Uri.parse(requestUrl), headers: headers);
It returns the following response.
{
"meta": {
"upcomingMatchCount": 5,
"inProgressMatchCount": 10,
"completedMatchCount": 5
},
"matchList": {
"matches": [
{
"id": 49944,
"matchTypeId": 15,
"series": {
"id": 2739,
"name": "LV= Insurance County Championship 2021",
"shortName": "LV= Insurance County Championship 2021"
},
"name": "",
"status": "LIVE",
"venue": {
"name": "The Cooper Associates County Ground",
"shortName": "The Cooper Associates County Ground"
},
"homeTeam": {
"isBatting": true,
"id": 55,
"name": "Somerset",
"shortName": "SOM"
},
"awayTeam": {
"isBatting": false,
"id": 46,
"name": "Gloucestershire",
"shortName": "GLO"
},
"currentMatchState": "Live",
"isMultiDay": true,
"matchSummaryText": "Live: Gloucestershire won the toss and elected to bowl.",
"scores": {
"homeScore": "8-293",
"homeOvers": "88.0",
"awayScore": "0-0",
"awayOvers": "0"
},
"liveStreams": [],
"isLive": false,
"currentInningId": 1,
"isMatchDrawn": false,
"isMatchAbandoned": false,
"startDateTime": "2021-04-15T10:00:00Z",
"endDateTime": "2021-04-18T17:00:00Z",
"isWomensMatch": false,
"isGamedayEnabled": false,
"removeMatch": false
},
{
"id": 49942,
"matchTypeId": 15,
"series": {
"id": 2739,
"name": "LV= Insurance County Championship 2021",
"shortName": "LV= Insurance County Championship 2021"
},
"name": "",
"status": "LIVE",
"venue": {
"name": "The Spitfire Ground, St Lawrence",
"shortName": "The Spitfire Ground, St Lawrence"
},
"homeTeam": {
"isBatting": false,
"id": 45,
"name": "Kent",
"shortName": "KEN"
},
"awayTeam": {
"isBatting": true,
"id": 40,
"name": "Yorkshire",
"shortName": "YRK"
},
"currentMatchState": "Live",
"isMultiDay": true,
"matchSummaryText": "Live: Yorkshire won the toss and elected to bat.",
"scores": {
"homeScore": "0-0",
"homeOvers": "0",
"awayScore": "8-358",
"awayOvers": "100.0"
},
"liveStreams": [],
"isLive": false,
"currentInningId": 1,
"isMatchDrawn": false,
"isMatchAbandoned": false,
"startDateTime": "2021-04-15T10:00:00Z",
"endDateTime": "2021-04-18T17:00:00Z",
"isWomensMatch": false,
"isGamedayEnabled": false,
"removeMatch": false
},
]
I am retrieving the match list from this response as follows:
final list = map['matchList']['matches'] as List;
I have a Model class which represents each match from the matches key:
class MatchModel {
int id;
int matchTypeId;
Series series;
String name;
String status;
Venue venue;
HomeTeam homeTeam;
HomeTeam awayTeam;
String currentMatchState;
bool isMultiDay;
String matchSummaryText;
Scores scores;
List<Null> liveStreams;
bool isLive;
int currentInningId;
bool isMatchDrawn;
bool isMatchAbandoned;
String startDateTime;
String endDateTime;
bool isWomensMatch;
bool isGamedayEnabled;
bool removeMatch;
MatchModel(
{this.id,
this.matchTypeId,
this.series,
this.name,
this.status,
this.venue,
this.homeTeam,
this.awayTeam,
this.currentMatchState,
this.isMultiDay,
this.matchSummaryText,
this.scores,
this.liveStreams,
this.isLive,
this.currentInningId,
this.isMatchDrawn,
this.isMatchAbandoned,
this.startDateTime,
this.endDateTime,
this.isWomensMatch,
this.isGamedayEnabled,
this.removeMatch});
MatchModel.fromJson(Map<String, dynamic> json) {
id = json['id'];
matchTypeId = json['matchTypeId'];
series =
json['series'] != null ? new Series.fromJson(json['series']) : null;
name = json['name'];
status = json['status'];
venue = json['venue'] != null ? new Venue.fromJson(json['venue']) : null;
homeTeam = json['homeTeam'] != null
? new HomeTeam.fromJson(json['homeTeam'])
: null;
awayTeam = json['awayTeam'] != null
? new HomeTeam.fromJson(json['awayTeam'])
: null;
currentMatchState = json['currentMatchState'];
isMultiDay = json['isMultiDay'];
matchSummaryText = json['matchSummaryText'];
scores =
json['scores'] != null ? new Scores.fromJson(json['scores']) : null;
if (json['liveStreams'] != null) {
liveStreams = new List<Null>();
json['liveStreams'].forEach((v) {
});
}
isLive = json['isLive'];
currentInningId = json['currentInningId'];
isMatchDrawn = json['isMatchDrawn'];
isMatchAbandoned = json['isMatchAbandoned'];
startDateTime = json['startDateTime'];
endDateTime = json['endDateTime'];
isWomensMatch = json['isWomensMatch'];
isGamedayEnabled = json['isGamedayEnabled'];
removeMatch = json['removeMatch'];
}
How do i map data from the list of matches to the list of my MatchModel? Do let me know if you need anything else, any help will be appreciated.
the thing is the response object which is returned is actually a string, so you need to first convert that to json using like
var json = jsonDecode(response).
Once you have it in json format what you can do is access the list as json['matchList']['matches']. So now you can iterater over it like
List<MatchModel> matches = []
for(var match in json['matchList']['matches']){
matches.add(MatchModel.fromJson(match));
}
Hope it's useful.
I would recommend JSON serialization with code generation. In that way you just need a annotation #JsonSerializable for the class, a constructor and part 'match.g.dart'; at the begin of your file. After this, the json_serializable package will generate the Json-converter-methods/factories for you.
For more information you can use this article: https://flutter.dev/docs/development/data-and-backend/json.
Try this.
var json = jsonDecode(response.body)['matchList']['matches'];
List<MatchModel> matches = List.from(json).map((e) => MatchModel.fromJson(Map.from(e))).toList();

How to push in Mongoose sub sub document array?

Following is my schema:
new Schema({
user: [{
email: { type: String },
contactList: [{
frndemail: { type: String },
msgList: [{
from : String,
to : String,
content : String,
time : String,
type: String,
subtype : String,
state: String
}],
unreadmsgList:[{
from : String,
to : String,
content : String,
time : String,
type: String,
subtype : String,
state: String
}]
}]
}]
});
In the above schema i am trying to push new messages in the msgList, but my query is not working i am trying something like this:
MyModel.update({"user.email":"myemail#gmail.com","user.contactList.frndemail":"frndemail#gmail.com"}, {
$push:{"user.$.contactList.$.msgList":{
"from": "myemail#gmail.com",
"to": "frndemail#gmail.com",
"content": "abc",
"time": "1:00 PM",
"type": "",
"subtype": "",
"state": ""
}}
},
function(err,doc){
if (err) {
console.log("msg creation failed " +err);
} else {
console.log("msg created successfully "+doc);
}
});
Please if anyone correct this query for me thanks...

Swagger-spray adds extraneous parameters

I'm Switching from spray-swagger to swagger-spray in order to get swagger2.0 generated, and I'm encountering the following problem: swagger-spray automatically adds parameters of type 'body', in addition to the manually specified #ApiImplicitParams, for all actual function params.
Annotated code:
#Path("areas/{areaId}/items/{itemId}")
#ApiOperation("Retrieves an item from an area by id", httpMethod = "GET", produces = "application/json", consumes = "application/json")
#ApiImplicitParams(Array(
new ApiImplicitParam(name = "areaId", paramType = "path", required = true, dataType = "integer", value = "Items area")
new ApiImplicitParam(name = "itemId", paramType = "path", required = true, dataType = "integer", value = "Item id")
))
def getItem(areaId: Int, itemId: Int) = { ... }
The generated swagger contains the following:
...
parameters: [
{
in: "body",
name: "body",
required: false,
schema: {
type: "integer",
format: "int64"
}
},
{
in: "body",
name: "body",
required: false,
schema: {
type: "integer",
format: "int64"
}
},
{
name: "areaId",
in: "path",
description: "Items area",
required: true,
type: "integer"
},
{
name: "itemId",
in: "path",
description: "Item id",
required: true,
type: "integer"
} ]
Instead of only the last 2. Any idea where these extra params come from / how can I suppress them / what am I doing wrong?
Thanks