@Roshan,

These APIs are tightly coupled with the product. If user wants to migrate
to a newer version, then the user has to use the newer APIs that come with
the new product version. We have started the separate mail thread to
discuss this.

@Harshan

Again *GET /analytics/tables/is-exists?tableName=<table-name> *will
conflict with API #5, since each path parameter is optional. So I changed
the API #3 like this,,
*GET /analytics/table_exists?tableName=<table-name>*

On Fri, Feb 13, 2015 at 11:41 AM, Harshan Liyanage <[email protected]> wrote:

> Hi Gimantha,
>
> I think it's better if you could change the API #3 to something more
> meaningful like *GET /analytics/tables/is-exists?tableName=<table-name>*.
> When you have the following format for that API, it's more like you are
> trying to fetch the table instead of checking for its existence. Anyway
> that's a minor issue and may be not-applicable to your domain.
>
> 3. Check if a table exists
> *GET /analytics/tables?tableName=<table-name>*
> ; table-name - The name of the table being checked.
>
> Thanks,
>
> Lakshitha Harshan
> Software Engineer
> Mobile: *+94724423048*
> Email: [email protected]
> Blog : http://harshanliyanage.blogspot.com/
> *WSO2, Inc. :** wso2.com <http://wso2.com/>*
> lean.enterprise.middleware.
>
> On Fri, Feb 13, 2015 at 9:49 AM, Roshan Wijesena <[email protected]> wrote:
>
>> Hi Gimantha,
>>
>> Don't we need to maintain a version with an API?
>>
>> Regards
>> Roshan
>>
>> On Fri, Feb 13, 2015 at 3:08 AM, Gimantha Bandara <[email protected]>
>> wrote:
>>
>>> Hi all,
>>> I changed the APIs so they follow the convention and i tested if there
>>> are conflicts between some APIs. JAX RS treats *GET
>>> /analytics/tables/{tableName}/{from} *, *GET
>>> /analytics/tables/{tableName}/recordcount *and *GET
>>> /analytics/tables/{tableName}/indices* as different APIs, so there will
>>> not be any conflict.
>>>
>>> Changed APIs :
>>>
>>> 1. Create a table
>>> *POST /analytics/tables*
>>> {
>>>    tableName : "<table-name>"
>>> }
>>>  ; table-name - The name of the table to be created.
>>>
>>> 2. Delete a table.
>>> *DELETE /analytics/tables*/*{tableName}*
>>>
>>> ; tableName - The name of the table to be deleted.
>>>
>>> 3. Check if a table exists
>>> *GET /analytics/tables?tableName=<table-name>*
>>> ; table-name - The name of the table being checked.
>>>
>>> 4. List All the tables
>>> *GET /analytics/tables*
>>> ;Response will be an JSON array of table names. e.g. [ "table1" ,
>>> "table2" , "table3" ]
>>>
>>> 5. Get the records from a table.
>>> *GET /analytics/tables/{tableName}/{from}/{to}/{start}/{count}*
>>> ; tableName - The name of the table from which the records are retrieved.
>>> ; from - The starting time to get records from.
>>> ; to - The ending time to get records to.
>>> ; start - The paginated index from value
>>> ; count - The paginated records count to be read
>>> ; response - takes the format of the request content of No.7
>>>
>>> 7. Create records ( can be created in different tables or in the same )
>>> *POST /analytics/records*
>>> ; Content - A list of records in json format like in below.
>>> [
>>>     {
>>>         "id": "id1", (optional),
>>>         "tableName": "tableName1",
>>>         "timestamp": "<long-value>", (optional)
>>>         "values":
>>>         {
>>>             "columnName1": "value1",
>>>             "columnName2": "value2"
>>>         }
>>>     },
>>>    {
>>>         "tableName": "tableName2",
>>>         "values":
>>>         {
>>>             "columnName1": "value1",
>>>             "columnName2": "value2"
>>>         }
>>>     },
>>> ]
>>>
>>> 8. Delete records
>>> *DELETE /analytics/tables/{tableName}/{timeFrom}/{timeTo}*
>>> ; tableName - Name of the table from which the records are deleted.
>>> ; timeFrom - The starting time to delete records from.
>>> ; timeTo - The end time to delete records to.
>>>
>>> 9. Update a set of records
>>> *PUT /analytics/records* ( PATCH will be more suitable, but jax rs does
>>> not give PATCH method out of the box so we have to implement it)
>>> ; Content - As same as the POST method for creating records
>>>
>>> 10. Get the record count of table
>>> *GET /analytics/tables/{tableName}/recordcount*
>>> ; tableName - The name of the table
>>>
>>> 11. Create Indices for a table
>>> *POST /analytics/tables/{tableName}/indices*
>>> ; tableName - The name of the table of which the indices are set
>>> ; Content - takes the following format. TYPE is one of "INTEGER",
>>> "BOOLEAN", "DOUBLE", "STRING", "FLOAT", "LONG"
>>> {
>>>     "indexColumnName1" : "TYPE1",
>>>     "indexColumnName2" : "TYPE2"
>>> }
>>>
>>> 12. get the indices of a table
>>> *GET /analytics/tables/{tableName}/indices*
>>> ; tableName - The name of the table
>>> ; Response will be of the format of the previous POST request's Content.
>>>
>>> 13. Clear the indices of a table
>>> *DELETE /analytics/tables/{tableName}/indices*
>>> ; tableName - The name of the table
>>>
>>> 14. Search records of a table
>>> *POST /analytics/search*
>>> ; Content - takes the following format
>>> {
>>>     "tableName": "sampleTableName",
>>>     "language": "sampleLanguageName",
>>>     "query": "sampleQuery",
>>>     "start": "start-location-of-the-result",
>>>     "count": "maximum-number-of-entries-to-return"
>>> }
>>>
>>> On Wed, Jan 21, 2015 at 8:38 AM, Anjana Fernando <[email protected]>
>>> wrote:
>>>
>>>> Hi Gimantha,
>>>>
>>>> You haven't really replied to Sinthuja's points there. We have to
>>>> decide if we are going ahead with Sinthuja's suggestions, or not. Lets
>>>> first educate ourselves on the best practices of RESTful API design a bit,
>>>> Googling helps [1]. For example, I'm also not sure if should be
>>>> /analytics/{tableName}/records or /analytics/records/{tableName}, each has
>>>> benefits, like, first approach can have ambiguity issues, specially when
>>>> there other operations with optional fields. And also, I guess we will need
>>>> to have /analytics/tables/{tableName} for creating tables etc.. or else,
>>>> for example when we do a POST for like "/analytics/T1", it may not be that
>>>> informative what we are actually doing there.
>>>>
>>>> [1]
>>>> https://www.google.com/search?q=REST+service+design&gws_rd=ssl#q=REST+api+design
>>>>
>>>> Cheers,
>>>> Anjana.
>>>>
>>>> On Wed, Jan 21, 2015 at 3:35 AM, Gimantha Bandara <[email protected]>
>>>> wrote:
>>>>
>>>>> Hi,
>>>>> Goood point!. Initially the search was implemented such a way that it
>>>>> returns a list of ids of records that match the query. Now the search
>>>>> method is changed, so it returns the records. So +1 for removing the API
>>>>> #6.
>>>>>
>>>>> @Sinduja, @Harshan
>>>>>    Thanks for the reference links and for the feedback.
>>>>>
>>>>> On Tue, Jan 20, 2015 at 6:52 PM, Harshan Liyanage <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> Hi Gimantha,
>>>>>>
>>>>>> Could you please explain the use-case for the API  #6? IMO there
>>>>>> should not be any operation to fetch a list of records by ids. Instead
>>>>>> there could be an API which sends a list of records as the response for a
>>>>>> query.
>>>>>>
>>>>>> For the API #14 you can still use GET method with query strings. I
>>>>>> think you have included start & count parameters to control the 
>>>>>> pagination.
>>>>>> For that you can use the HTTP range-header [1] or link headers as 
>>>>>> mentioned
>>>>>> in [2].
>>>>>>
>>>>>> [1]. http://otac0n.com/blog/2012/11/21/range-header-i-choose-you.html
>>>>>> [2]. https://developer.github.com/v3/#pagination
>>>>>>
>>>>>> Regards,
>>>>>>
>>>>>> Lakshitha Harshan
>>>>>> Software Engineer
>>>>>> Mobile: *+94724423048*
>>>>>> Email: [email protected]
>>>>>> Blog : http://harshanliyanage.blogspot.com/
>>>>>> *WSO2, Inc. :** wso2.com <http://wso2.com/>*
>>>>>> lean.enterprise.middleware.
>>>>>>
>>>>>> On Tue, Jan 20, 2015 at 6:34 PM, Gimantha Bandara <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> Hi Harshan,
>>>>>>>
>>>>>>> Thanks for the feedback. The list of IDs of the records to be
>>>>>>> retrieved can be too long. So setting a list of ids as a query param is 
>>>>>>> not
>>>>>>> convenient. Even for the Search, we have to pass a query, which can be 
>>>>>>> too
>>>>>>> long. Thats why the post method is used for Search.
>>>>>>>
>>>>>>> Thanks,
>>>>>>>
>>>>>>> On Tue, Jan 20, 2015 at 12:52 PM, Sinthuja Ragendran <
>>>>>>> [email protected]> wrote:
>>>>>>>
>>>>>>>> Hi Gimantha,
>>>>>>>>
>>>>>>>> I think following the conventions will be more intuitive to the
>>>>>>>> users, and we should have a proper reason to not follow. And the post
>>>>>>>> request is generally needs to be sent to create the object and the 
>>>>>>>> back end
>>>>>>>> is going to decide where to create the tables resource, therefore it 
>>>>>>>> should
>>>>>>>> be POST to '/analytics/tables' and message body should be having the 
>>>>>>>> table
>>>>>>>> name. If you want to use /analytics/{tableName}, then you should
>>>>>>>> use PUT rather POST [1]. But IMO POST is the most suitable operation 
>>>>>>>> for
>>>>>>>> this context.
>>>>>>>>
>>>>>>>> And through out the below given URL patterns, in order to fetch the
>>>>>>>> records from a table, you have used '/analytics/records/{tableName}' 
>>>>>>>> url
>>>>>>>> pattern where 'records' is in the middle and it is not the correct data
>>>>>>>> hierarchy and again I feel it's not the convention. Basically tables
>>>>>>>> contains records and not records contains tables. Therefore if we use
>>>>>>>> POST to '/analytics/tables' for create table, then you can use
>>>>>>>> simply user 'analytics/{tableName}' to GET/POST for the tables, IMHO 
>>>>>>>> the
>>>>>>>> records is just an additional segment which is not needed to be here.
>>>>>>>>
>>>>>>>> [1] http://restcookbook.com/HTTP%20Methods/put-vs-post
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Sinthuja.
>>>>>>>>
>>>>>>>> On Tue, Jan 20, 2015 at 1:29 AM, Gimantha Bandara <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> Hi Sinduja,
>>>>>>>>>
>>>>>>>>> Thank you for the feedback.
>>>>>>>>>
>>>>>>>>> On Mon, Jan 19, 2015 at 12:04 PM, Sinthuja Ragendran <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> Hi gimantha,
>>>>>>>>>>
>>>>>>>>>> Please see the comments inline.
>>>>>>>>>>
>>>>>>>>>> On Sun, Jan 18, 2015 at 11:24 PM, Gimantha Bandara <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi,
>>>>>>>>>>> Currently, I am working on $subject. Basically the methods in
>>>>>>>>>>> AnalyticsDataService will be exposed through REST APIs. Please 
>>>>>>>>>>> refer to
>>>>>>>>>>> Architecture mail thread "*[Architecture] BAM 3.0 Data Layer
>>>>>>>>>>> Implementation / RDBMS / Distributed Indexing / Search*" for
>>>>>>>>>>> more Details. Following are the supported REST APIs.
>>>>>>>>>>>
>>>>>>>>>>> 1. Create a table
>>>>>>>>>>> *POST /analytics/{tableName}*
>>>>>>>>>>>  ; tableName - The name of the table to be created.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> IMHO the above should be POST to '/analytics/*tables*' and the
>>>>>>>>>> request content should have the table name as given below.
>>>>>>>>>> {
>>>>>>>>>>  "tableName" : "Test"
>>>>>>>>>> }
>>>>>>>>>>
>>>>>>>>> Since the POST takes only the table name, it is straightforward to
>>>>>>>>> use it as a path parameter.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> 2. Delete a table
>>>>>>>>>>> *DELETE /analytics/{tableName} *
>>>>>>>>>>> ; tableName - The name of the table to be deleted.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> 3. Check if a table exists
>>>>>>>>>>> *GET /analytics/{tableName} *
>>>>>>>>>>> ; tableName - The name of the table being checked.
>>>>>>>>>>>
>>>>>>>>>>> 4. List All the tables
>>>>>>>>>>> *GET /analytics/tables*
>>>>>>>>>>> ;Response will be an JSON array of table names. e.g. [ "table1"
>>>>>>>>>>> , "table2" , "table3" ]
>>>>>>>>>>>
>>>>>>>>>>> 5. Get the records from a table.
>>>>>>>>>>> *GET /analytics/records/{tableName}/{from}/{to}/{start}/{count} *
>>>>>>>>>>> ; tableName - The name of the table from which the records are
>>>>>>>>>>> retrieved.
>>>>>>>>>>> ; from - The starting time to get records from.
>>>>>>>>>>> ; to - The ending time to get records to.
>>>>>>>>>>> ; start - The paginated index from value
>>>>>>>>>>> ; count - The paginated records count to be read
>>>>>>>>>>> ; response - takes the format of the request content of No.7
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Do we need to have 'records' in the URL?  I think it's better to
>>>>>>>>>> have  */analytics/{tableName}/{from}/{to}/{start}/{count} *
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> "records" is there to avoid conflicts with other contexts. As an
>>>>>>>>> example, If we remove "records", the URL will take the format
>>>>>>>>> "/analytics/{tableName}", which is already a defined REST API.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> 6. Get the records from a table (By IDs)
>>>>>>>>>>> *POST /analytics/records/{tableName}*
>>>>>>>>>>> ; tableName - The name of the table from which the records are
>>>>>>>>>>> retrieved.
>>>>>>>>>>> ; Content  - A List of IDs of the records to be retrieved in the
>>>>>>>>>>> following format.
>>>>>>>>>>> [ "id1" , "id2" , "id3" ]
>>>>>>>>>>> ; response - takes the format of the request content of No.7
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Similarly can we have this as * /analytics/{tableName}?*
>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> 7. Create records ( can be created in different tables or in the
>>>>>>>>>>> same )
>>>>>>>>>>> *POST /analytics/records*
>>>>>>>>>>> ; Content - A list of records in json format like in below.
>>>>>>>>>>> [
>>>>>>>>>>>     {
>>>>>>>>>>>         "id": "id1",
>>>>>>>>>>>         "tenantId": -1234,
>>>>>>>>>>>         "tableName": "tableName1",
>>>>>>>>>>>         "timestamp": "yyyy-mm-dd hh:mm:ss",
>>>>>>>>>>>         "values":
>>>>>>>>>>>         {
>>>>>>>>>>>             "columnName1": "value1",
>>>>>>>>>>>             "columnName2": "value2"
>>>>>>>>>>>         }
>>>>>>>>>>>     },
>>>>>>>>>>>    {
>>>>>>>>>>>         "id": "id2",
>>>>>>>>>>>         "tenantId": -1234,
>>>>>>>>>>>         "tableName": "tableName2",
>>>>>>>>>>>         "timestamp": "yyyy-mm-dd hh:mm:ss",
>>>>>>>>>>>         "values":
>>>>>>>>>>>         {
>>>>>>>>>>>             "columnName1": "value1",
>>>>>>>>>>>             "columnName2": "value2"
>>>>>>>>>>>         }
>>>>>>>>>>>     },
>>>>>>>>>>> ]
>>>>>>>>>>>
>>>>>>>>>>> 8. Delete records
>>>>>>>>>>> *DELETE /analytics/records/{tableName}/{timeFrom}/{timeTo}*
>>>>>>>>>>> ; tableName - Name of the table from which the records are
>>>>>>>>>>> deleted.
>>>>>>>>>>> ; timeFrom - The starting time to delete records from.
>>>>>>>>>>> ; timeTo - The end time to delete records to.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>> Again do we need to have 'records' in the middle?  IMHO
>>>>>>>>>> /analytics/{tableName}/{timeFrom}/{timeTo} is better.
>>>>>>>>>>
>>>>>>>>>> 9. Update records
>>>>>>>>>>> *PUT /analytics/records*
>>>>>>>>>>> ; Content - As same as the POST method for creating records
>>>>>>>>>>>
>>>>>>>>>>> 10. Get the record count of table
>>>>>>>>>>> *GET /analytics/count/{tableName}*
>>>>>>>>>>> ; tableName - The name of the table
>>>>>>>>>>>
>>>>>>>>>>> 11. Create Indices for a table
>>>>>>>>>>> *POST /analytics/indices/{tableName}*
>>>>>>>>>>> ; tableName - The name of the table of which the indices are set
>>>>>>>>>>> ; Content - takes the following format. TYPE is one of
>>>>>>>>>>> "INTEGER", "BOOLEAN", "DOUBLE", "STRING", "FLOAT", "LONG"
>>>>>>>>>>> {
>>>>>>>>>>>     "indexColumnName1" : "TYPE1",
>>>>>>>>>>>     "indexColumnName2" : "TYPE2"
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> 12. get the indices of a table
>>>>>>>>>>> *GET /analytics/indices/{tableName}*
>>>>>>>>>>> ; tableName - The name of the table
>>>>>>>>>>> ; Response will be of the format of the previous POST request's
>>>>>>>>>>> Content.
>>>>>>>>>>>
>>>>>>>>>>> 13. Clear the indices of a table
>>>>>>>>>>> *DELETE /analytics/indices/{tableName}*
>>>>>>>>>>> ; tableName - The name of the table
>>>>>>>>>>>
>>>>>>>>>>> 14. Search records of a table
>>>>>>>>>>> *POST /analytics/search*
>>>>>>>>>>> ; Content - takes the following format
>>>>>>>>>>> {
>>>>>>>>>>>     "tableName": "sampleTableName",
>>>>>>>>>>>     "language": "sampleLanguageName",
>>>>>>>>>>>     "query": "sampleQuery",
>>>>>>>>>>>     "start": "start-location-of-the-result",
>>>>>>>>>>>     "count": "maximum-number-of-entries-to-return"
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> IMHO this should be a GET request.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Here the problem is, that the search method in
>>>>>>>>> AnalyticsDataService takes few parameters. If we are to implement it 
>>>>>>>>> as a
>>>>>>>>> GET, then we will have to put all the parameters in the URL itself.
>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks,
>>>>>>>>>> Sinthuja.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>> If a method does not have a specific response mentioned above,
>>>>>>>>>>> the response will take the following format.
>>>>>>>>>>>
>>>>>>>>>>> {
>>>>>>>>>>> "status" : "statusValue",
>>>>>>>>>>> "message" : "sampleMessage"
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>> Suggestions and feedbacks are appreciated.
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> Gimanthaa Bandara
>>>>>>>>>>> Software Engineer
>>>>>>>>>>> WSO2. Inc : http://wso2.com
>>>>>>>>>>> Mobile : +94714961919
>>>>>>>>>>>
>>>>>>>>>>> _______________________________________________
>>>>>>>>>>> Architecture mailing list
>>>>>>>>>>> [email protected]
>>>>>>>>>>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> *Sinthuja Rajendran*
>>>>>>>>>> Senior Software Engineer <http://wso2.com/>
>>>>>>>>>> WSO2, Inc.:http://wso2.com
>>>>>>>>>>
>>>>>>>>>> Blog: http://sinthu-rajan.blogspot.com/
>>>>>>>>>> Mobile: +94774273955
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> _______________________________________________
>>>>>>>>>> Architecture mailing list
>>>>>>>>>> [email protected]
>>>>>>>>>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> --
>>>>>>>>> Gimantha Bandara
>>>>>>>>> Software Engineer
>>>>>>>>> WSO2. Inc : http://wso2.com
>>>>>>>>> Mobile : +94714961919
>>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> *Sinthuja Rajendran*
>>>>>>>> Senior Software Engineer <http://wso2.com/>
>>>>>>>> WSO2, Inc.:http://wso2.com
>>>>>>>>
>>>>>>>> Blog: http://sinthu-rajan.blogspot.com/
>>>>>>>> Mobile: +94774273955
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> Gimantha Bandara
>>>>>>> Software Engineer
>>>>>>> WSO2. Inc : http://wso2.com
>>>>>>> Mobile : +94714961919
>>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Gimantha Bandara
>>>>> Software Engineer
>>>>> WSO2. Inc : http://wso2.com
>>>>> Mobile : +94714961919
>>>>>
>>>>> _______________________________________________
>>>>> Architecture mailing list
>>>>> [email protected]
>>>>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>>>>
>>>>>
>>>>
>>>>
>>>> --
>>>> *Anjana Fernando*
>>>> Senior Technical Lead
>>>> WSO2 Inc. | http://wso2.com
>>>> lean . enterprise . middleware
>>>>
>>>> _______________________________________________
>>>> Architecture mailing list
>>>> [email protected]
>>>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>>>
>>>>
>>>
>>>
>>> --
>>> Gimantha Bandara
>>> Software Engineer
>>> WSO2. Inc : http://wso2.com
>>> Mobile : +94714961919
>>>
>>> _______________________________________________
>>> Architecture mailing list
>>> [email protected]
>>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>>
>>>
>>
>>
>> --
>> Roshan Wijesena.
>> Senior Software Engineer-WSO2 Inc.
>> Mobile: *+94719154640 <%2B94719154640>*
>> Email: [email protected]
>> *WSO2, Inc. :** wso2.com <http://wso2.com/>*
>> lean.enterprise.middleware.
>>
>> _______________________________________________
>> Architecture mailing list
>> [email protected]
>> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>>
>>
>
> _______________________________________________
> Architecture mailing list
> [email protected]
> https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture
>
>


-- 
Gimantha Bandara
Software Engineer
WSO2. Inc : http://wso2.com
Mobile : +94714961919
_______________________________________________
Architecture mailing list
[email protected]
https://mail.wso2.org/cgi-bin/mailman/listinfo/architecture

Reply via email to