camaraproject / Commonalities

Repository to describe, develop, document and test the common guidelines and assets for CAMARA APIs
Apache License 2.0
9 stars 24 forks source link

Subscription-Issue3: Support filter option for subscriptions #155

Closed shilpa-padgaonkar closed 2 months ago

shilpa-padgaonkar commented 4 months ago

Problem description We currently do not have a way to allow event consumers to subscribe to very "specific" events unless we create (very specific) distinct event types. Filters (as defined in CloudEvents subscription spec allow for subscriptions to specify that only a subset of events are to be delivered to the sink based on a set of criteria. The filter property in a subscription is a set of filter expressions, where each expression evaluates to either true or false for each event generated. The filter-dialects indicate which filter expression language is supported by event producers.

Possible evolution Camara subscriptions could agree to support filters for subscriptions. I have shown 2 (abstract) examples below which make use of extension-context-attributes (for eg. status_types) and then use it in filter expressions:

{ 
 "id": "123654", 
 "source": "https://notificationsendserver12.supertelco.com/", 
 "type": "org.camaraproject.device.v0.roaming-status", 
 "specversion": "1.0",
 "status_types": ["ROAMING_ON", "ROAMING_OFF", "COUNTRY_CHANGE"]
 "datacontenttype": "application/json", 
 "data": { 
    "statusType: ROAMING_ON,
    "device": { "phoneNumber": 123456789 },
    "countryCode": 208, 
    "countryName": "FR"
    "subscriptionId": "qs15-h556-rt89-1298"
  },
  "time": "2023-01-17T13:18:23.682Z" 
}
{ 
"id": "83a0d986-0866-4f38-b8c0-fc65bfcda452", 
"source": "https://notificationsendserver12.supertelco.com/", 
"type": "org.camaraproject.device.v0.connectivity-status", 
"specversion": "1.0",
"status_types: ["CONNECTIVITY_DISCONNECTED", "CONNECTIVITY_DATA", "CONNECTIVITY_SMS"],
"datacontenttype": "application/json", 
"data": { 
   "statusType": "CONNECTIVITY_DATA",
   "device": { "phoneNumber": 123456789 },
   "subscriptionId": "qs15-h556-rt89-1298"
 } 
 "time": "2023-01-19T13:18:23.682Z"
}
{
  "id": "56473905-b8c0-fc65bfcda452", 
  "protocol": "HTTP",
  "protocolSettings": {},
  "sink": "https://endpoint.example.com/webhook",
  "sinkCredential": {
    "credentialType": "PLAIN"
  },
  "source": ""https://xyz.abc.com/"",
  "types": [
    "org.camaraproject.device.v0.roaming-status",
    "org.camaraproject.device.v0.connectivity-status"   
  ],
  "filters": [      
     "any": [
    { "exact": { "type": "org.camaraproject.device.v0.roaming-status" , "status_types": ["ROAMING_ON"] } },
    { "exact": { "type": "org.camaraproject.device.v0.connectivity-status", "status_types": ["CONNECTIVITY_DATA"]  } }
  ]
 ], 
"config": { 
    "subscriptionExpireTime": "2023-01-17T13:18:23.682Z" 
} }

Alternative solution

Additional context

149

bigludo7 commented 4 months ago

Hello @shilpa-padgaonkar As multiple type is managed in another thread I'm not sure to understand how filters can be used.

Let's consider UC as the one we have in Device location about initial event.

In this case should be consider instead the config part?

In order to discuss on an existing case, if we try to realign our subscription model to CloudsEvent one we are going from:

{
  "webhook": {
    "notificationUrl": "https://application-server.com",
    "notificationAuthToken": "c8974e592c2fa383d4a3960714"
  },
  "subscriptionDetail": {
    "device": {
      "phoneNumber": "123456789"
      }
    },
    "area": {
       "areaType": "CIRCLE",
      "center": {
        "latitude": 50.735851,
        "longitude": 7.10066
    },
    "type": "org.camaraproject.geofencing.v0.area-entered"
  },
  "subscriptionExpireTime": "2024-06-08T09:42:23.807Z",
  "subscriptionMaxEvents ": "1",
  "initalEvent ": true,
  "subscriptionId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "startsAt": "2024-03-08T09:42:23.807Z",
  "expiresAt": "2024-06-08T09:42:23.807Z"
}
}

to

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", 
  "protocol": "HTTP",   **Only HTTP
  "protocolSettings": {},
  "sink": "https://application-server.com",
  "sinkCredential": {  **To be studied
    "credentialType": "OauthToken"
    "credential": "c8974e592c2fa383d4a3960714"
  },
  "types": [  **depending on other discussion if 1 or *
    "org.camaraproject.geofencing.v0.area-entered"
 ], 
"config": { 
    "subscriptionDetail": {
      "device": {
        "phoneNumber": "123456789"
      },
    },
    "area": {
       "areaType": "CIRCLE",
      "center": {
        "latitude": 50.735851,
        "longitude": 7.10066
    },
    "type": "org.camaraproject.geofencing.v0.area-entered"
  },
    "subscriptionExpireTime": "2024-06-08T09:42:23.807Z",
    "subscriptionMaxEvents ": "1",
    "initalEvent ": true,
     "startsAt": "2024-03-08T09:42:23.807Z",
    "expiresAt": "2024-06-08T09:42:23.807Z"
} }

Is it the approach that you looking for?

But even with this approach we need to 'standardise' key word as intialEvent right?

shilpa-padgaonkar commented 4 months ago

@bigludo7 Sorry, I didn't realize that you did not want an example with multiple types. If you have already added the initialEvent in config, then you wouldn't need a filter for it again.

May be an example with subject might be useful. Let me see if I can prepare one.

shilpa-padgaonkar commented 2 months ago

decision to not use filters at least for the first meta release