{"action":"created","issue":{"url":"https://api.github.com/repos/embulk/embulk-base-restclient/issues/55","repository_url":"https://api.github.com/repos/embulk/embulk-base-restclient","labels_url":"https://api.github.com/repos/embulk/embulk-base-restclient/issues/55/labels{/name}","comments_url":"https://api.github.com/repos/embulk/embulk-base-restclient/issues/55/comments","events_url":"https://api.github.com/repos/embulk/embulk-base-restclient/issues/55/events","html_url":"https://github.com/embulk/embulk-base-restclient/pull/55","id":207727624,"number":55,"title":"Fix null check for JsonNode value","user":{"login":"sakama","id":155269,"avatar_url":"https://avatars.githubusercontent.com/u/155269?v=3","gravatar_id":"","url":"https://api.github.com/users/sakama","html_url":"https://github.com/sakama","followers_url":"https://api.github.com/users/sakama/followers","following_url":"https://api.github.com/users/sakama/following{/other_user}","gists_url":"https://api.github.com/users/sakama/gists{/gist_id}","starred_url":"https://api.github.com/users/sakama/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sakama/subscriptions","organizations_url":"https://api.github.com/users/sakama/orgs","repos_url":"https://api.github.com/users/sakama/repos","events_url":"https://api.github.com/users/sakama/events{/privacy}","received_events_url":"https://api.github.com/users/sakama/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-02-15T07:30:02Z","updated_at":"2017-02-15T08:12:33Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/embulk/embulk-base-restclient/pulls/55","html_url":"https://github.com/embulk/embulk-base-restclient/pull/55","diff_url":"https://github.com/embulk/embulk-base-restclient/pull/55.diff","patch_url":"https://github.com/embulk/embulk-base-restclient/pull/55.patch"},"body":"I got following failure and fixed it.\r\nThis failure happens because Web API doesn't returns record itself when its value is null.\r\n\r\n### Models\r\n```java\r\nprivate JacksonServiceResponseMapper model = JacksonServiceResponseMapper.builder()\r\n            .add(\"id\", Types.STRING)\r\n            .add(\"column_abcdefg\", Types.BOOLEAN)\r\n            .build();\r\n```\r\n\r\n### API response\r\n```sh\r\n{\r\n  \"id\": \"aaa_1234567\"\r\n   # API doesn't returns 'column_abcdefg' record itself when its value is nul\r\n}\r\n```\r\n\r\n### Stacktrace\r\n\r\n```\r\nCaused by: org.embulk.spi.DataException: Failed to import a value for column: column_abcdefg (boolean)\r\n\tat org.embulk.base.restclient.record.values.BooleanValueImporter.findAndImportValue(BooleanValueImporter.java:40)\r\n\tat org.embulk.base.restclient.record.RecordImporter.importRecord(RecordImporter.java:17)\r\n\tat org.embulk.input.xxxxx.xxxxxInputPluginDelegate.ingestServiceData(xxxxxInputPluginDelegate.java:389)\r\n\tat org.embulk.input.xxxxx.xxxxxInputPluginDelegate.ingestServiceData(xxxxxInputPluginDelegate.java:65)\r\n\tat org.embulk.base.restclient.RestClientInputPluginBaseUnsafe.run(RestClientInputPluginBaseUnsafe.java:125)\r\n\tat org.embulk.base.restclient.RestClientInputPluginBase.run(RestClientInputPluginBase.java:123)\r\n\tat org.embulk.exec.LocalExecutorPlugin$ScatterExecutor.runInputTask(LocalExecutorPlugin.java:294)\r\n\tat org.embulk.exec.LocalExecutorPlugin$ScatterExecutor.access$000(LocalExecutorPlugin.java:212)\r\n\tat org.embulk.exec.LocalExecutorPlugin$ScatterExecutor$1.call(LocalExecutorPlugin.java:257)\r\n\tat org.embulk.exec.LocalExecutorPlugin$ScatterExecutor$1.call(LocalExecutorPlugin.java:253)\r\n\tat java.util.concurrent.FutureTask.run(FutureTask.java:266)\r\n\tat java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)\r\n\tat java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)\r\n\tat java.lang.Thread.run(Thread.java:745)\r\nCaused by: java.lang.NullPointerException\r\n\tat org.embulk.base.restclient.jackson.JacksonServiceValue.isNull(JacksonServiceValue.java:41)\r\n\tat org.embulk.base.restclient.record.values.BooleanValueImporter.findAndImportValue(BooleanValueImporter.java:29)\r\n\t... 13 more\r\n```\r\n\r\nI found that `BooleanValueImport.findAndImportValue()` has null check logic, but always returns `false` and `JacksonServiceValue.isNull() throws NullPointerException.\r\n\r\n```java\r\n// this value type is 'ServiceValue'\r\n// 'value==null' always returns false\r\n// Then 'value.isNull()' throws NullPointerException\r\nif (value == null || value.isNull()) {\r\n    pageBuilder.setNull(getColumnToImport());\r\n}\r\n```\r\n[BooleanValueImport.java](https://github.com/embulk/embulk-base-restclient/blob/master/src/main/java/org/embulk/base/restclient/record/values/BooleanValueImporter.java#L25)\r\n\r\nSo I added additional null check logic to `JacksonServiceValue.isNull()` method."},"comment":{"url":"https://api.github.com/repos/embulk/embulk-base-restclient/issues/comments/279944255","html_url":"https://github.com/embulk/embulk-base-restclient/pull/55#issuecomment-279944255","issue_url":"https://api.github.com/repos/embulk/embulk-base-restclient/issues/55","id":279944255,"user":{"login":"dmikurube","id":723722,"avatar_url":"https://avatars.githubusercontent.com/u/723722?v=3","gravatar_id":"","url":"https://api.github.com/users/dmikurube","html_url":"https://github.com/dmikurube","followers_url":"https://api.github.com/users/dmikurube/followers","following_url":"https://api.github.com/users/dmikurube/following{/other_user}","gists_url":"https://api.github.com/users/dmikurube/gists{/gist_id}","starred_url":"https://api.github.com/users/dmikurube/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dmikurube/subscriptions","organizations_url":"https://api.github.com/users/dmikurube/orgs","repos_url":"https://api.github.com/users/dmikurube/repos","events_url":"https://api.github.com/users/dmikurube/events{/privacy}","received_events_url":"https://api.github.com/users/dmikurube/received_events","type":"User","site_admin":false},"created_at":"2017-02-15T08:12:33Z","updated_at":"2017-02-15T08:12:33Z","body":"@sakama Thanks!\r\n\r\nLooked into that part again, and finally I thought it could be better to guarantee that `JacksonServiceValue` does not contain Java's `null` directly. (Sorry to change my mind.)\r\n\r\nWhat do you think to have the following in the constructor?\r\n\r\n```\r\n        if (value == null) {\r\n            this.value = new NullNode();\r\n        } else {\r\n            this.value = value;\r\n        }\r\n```\r\n\r\nhttps://github.com/embulk/embulk-base-restclient/blob/ac76108004e586608ee9fd98cd53b95e26ee8f20/src/main/java/org/embulk/base/restclient/jackson/JacksonServiceValue.java#L32-L35"}}
{"actor":{"display_login":"dmikurube"}}