{"action":"created","issue":{"url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/issues/10","repository_url":"https://api.github.com/repos/aerogear/aerogear-metrics-api","labels_url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/issues/10/labels{/name}","comments_url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/issues/10/comments","events_url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/issues/10/events","html_url":"https://github.com/aerogear/aerogear-metrics-api/pull/10","id":298336887,"number":10,"title":"Database Integration","user":{"login":"darahayes","id":8656188,"avatar_url":"https://avatars1.githubusercontent.com/u/8656188?v=4","gravatar_id":"","url":"https://api.github.com/users/darahayes","html_url":"https://github.com/darahayes","followers_url":"https://api.github.com/users/darahayes/followers","following_url":"https://api.github.com/users/darahayes/following{/other_user}","gists_url":"https://api.github.com/users/darahayes/gists{/gist_id}","starred_url":"https://api.github.com/users/darahayes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/darahayes/subscriptions","organizations_url":"https://api.github.com/users/darahayes/orgs","repos_url":"https://api.github.com/users/darahayes/repos","events_url":"https://api.github.com/users/darahayes/events{/privacy}","received_events_url":"https://api.github.com/users/darahayes/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":{"login":"david-martin","id":878251,"avatar_url":"https://avatars1.githubusercontent.com/u/878251?v=4","gravatar_id":"","url":"https://api.github.com/users/david-martin","html_url":"https://github.com/david-martin","followers_url":"https://api.github.com/users/david-martin/followers","following_url":"https://api.github.com/users/david-martin/following{/other_user}","gists_url":"https://api.github.com/users/david-martin/gists{/gist_id}","starred_url":"https://api.github.com/users/david-martin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/david-martin/subscriptions","organizations_url":"https://api.github.com/users/david-martin/orgs","repos_url":"https://api.github.com/users/david-martin/repos","events_url":"https://api.github.com/users/david-martin/events{/privacy}","received_events_url":"https://api.github.com/users/david-martin/received_events","type":"User","site_admin":false},"assignees":[{"login":"david-martin","id":878251,"avatar_url":"https://avatars1.githubusercontent.com/u/878251?v=4","gravatar_id":"","url":"https://api.github.com/users/david-martin","html_url":"https://github.com/david-martin","followers_url":"https://api.github.com/users/david-martin/followers","following_url":"https://api.github.com/users/david-martin/following{/other_user}","gists_url":"https://api.github.com/users/david-martin/gists{/gist_id}","starred_url":"https://api.github.com/users/david-martin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/david-martin/subscriptions","organizations_url":"https://api.github.com/users/david-martin/orgs","repos_url":"https://api.github.com/users/david-martin/repos","events_url":"https://api.github.com/users/david-martin/events{/privacy}","received_events_url":"https://api.github.com/users/david-martin/received_events","type":"User","site_admin":false}],"milestone":null,"comments":9,"created_at":"2018-02-19T16:32:58Z","updated_at":"2018-02-26T11:01:38Z","closed_at":"2018-02-23T11:15:51Z","author_association":"CONTRIBUTOR","pull_request":{"url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/pulls/10","html_url":"https://github.com/aerogear/aerogear-metrics-api/pull/10","diff_url":"https://github.com/aerogear/aerogear-metrics-api/pull/10.diff","patch_url":"https://github.com/aerogear/aerogear-metrics-api/pull/10.patch"},"body":"- [x] initial connection and setup logic\r\n- [x] Business logic for inserting records\r\n- [x] Unit/Integration tests\r\n\r\n## Update\r\n\r\nThis PR ended up turning into a mega PR but this is the initial implementation that allows us to store mobile metrics in the database. There are a number of things to be aware of:\r\n\r\n\r\n* There is a small amount of validation. The incoming data is parsed into a struct which filters out unnecessary fields. additionally, there are some small checks at the DB layer. ClientId cannot be an empty string and by data field will not accept invalid json. There is no other validation (right now).\r\n* Right now, the client timestamp is being parsed but not being saved. The `event_time` field is populated by Postgres at the time of insert.\r\n* The db_test.go and dao_test.go are actually integration tests. However by default they will not run because of the `// +build integration` build tag added at the top of those files. You can run integration + unit tests using the standard test command, but also passing the flag `tags=integration` @maleck13 Not sure how you feel about this. I found this solution in this [stackoverflow answer](https://stackoverflow.com/questions/25965584/separating-unit-tests-and-integration-tests-in-go). I know it's not as clear as integration tests having their own folder but it's still fairly obvious by looking at the file that the test is an integration test.\r\n* Removed references to timescaledb for now (as suggested by @david-martin )\r\n* Still need to implement some standardised logging approach\r\n* Docs need updating\r\n* Code Coverage at a fairly good 87.6%\r\n\r\nThe original estimate was 4d and I've spent about 3 days on this so far so there's still time to do some housekeeping around docs, build process, release, etc etc.\r\n\r\n## How to verify\r\n\r\nfetch this branch and start the database using docker-compose.\r\n\r\nNow start the server using `go run cmd/metrics-api/metrics-api.go`\r\n\r\nYou should see a message like\r\n\r\n```\r\n2018/02/22 17:28:30 Starting application... going to listen on :3000\r\n```\r\n\r\nNow you can try out the `/metrics` endpoint with the following curl request:\r\n\r\n```\r\ncurl -X POST \\\r\n  http://localhost:3000/metrics \\\r\n  -H 'Cache-Control: no-cache' \\\r\n  -H 'Content-Type: application/json' \\\r\n  -H 'Postman-Token: 76a14738-976f-f0ea-4039-12efeebf4f1e' \\\r\n  -d '{\r\n  \"clientId\": \"12345\",\r\n  \"data\": {\r\n  \t\"app\": {\r\n    \"id\": \"com.example.someApp\",\r\n    \"sdkVersion\": \"2.4.6\",\r\n    \"appVersion\": \"256\"\r\n\t},\r\n\t\"device\": {\r\n    \t\"platform\": \"android\",\r\n    \t\"platformVersion\": \"27\"\r\n\t}\r\n  }\r\n}'\r\n```\r\n\r\nYou should get a the following response:\r\n\r\n```\r\n{\"timestamp\":0,\"clientId\":\"12345\",\"data\":{\"app\":{\"id\":\"com.example.someApp\",\"sdkVersion\":\"2.4.6\",\"appVersion\":\"256\"},\"device\":{\"platform\":\"android\",\"platformVersion\":\"27\"}}}\r\n```\r\n\r\nNote the `timestamp` field in the response corresponds to the client timestamp which is currently not being handled or saved.\r\n\r\nYou can log into the database and verify that the record was created:\r\n\r\n```\r\npsql -U postgres --host localhost\r\npassword: postgres\r\n\r\n\\c aerogear_mobile_metrics\r\nselect * from mobileappmetrics;\r\n\r\n           clientid           |          event_time           |                                                                      data\r\n------------------------------+-------------------------------+------------------------------------------------------------------------------------------------------------------------------------------------\r\n org.aerogear.metrics.testing | 2018-02-22 15:14:03.859053+00 | {\"app\": {\"id\": \"com.example.someApp\", \"appVersion\": \"256\", \"sdkVersion\": \"2.4.6\"}, \"device\": {\"platform\": \"android\", \"platformVersion\": \"27\"}}\r\n```\r\n\r\nI'd love to get your reviews @maleck13 @david-martin @wtrocki "},"comment":{"url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/issues/comments/368464726","html_url":"https://github.com/aerogear/aerogear-metrics-api/pull/10#issuecomment-368464726","issue_url":"https://api.github.com/repos/aerogear/aerogear-metrics-api/issues/10","id":368464726,"user":{"login":"darahayes","id":8656188,"avatar_url":"https://avatars1.githubusercontent.com/u/8656188?v=4","gravatar_id":"","url":"https://api.github.com/users/darahayes","html_url":"https://github.com/darahayes","followers_url":"https://api.github.com/users/darahayes/followers","following_url":"https://api.github.com/users/darahayes/following{/other_user}","gists_url":"https://api.github.com/users/darahayes/gists{/gist_id}","starred_url":"https://api.github.com/users/darahayes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/darahayes/subscriptions","organizations_url":"https://api.github.com/users/darahayes/orgs","repos_url":"https://api.github.com/users/darahayes/repos","events_url":"https://api.github.com/users/darahayes/events{/privacy}","received_events_url":"https://api.github.com/users/darahayes/received_events","type":"User","site_admin":false},"created_at":"2018-02-26T11:01:38Z","updated_at":"2018-02-26T11:01:38Z","author_association":"CONTRIBUTOR","body":"@psturc Thanks so much for noticing this. The reason for the failing tests is simple. Now the reason why the exit code was still 0 is a little more unclear. Will fix this very soon."}}
{"actor":{"display_login":"darahayes"}}