Yoji Shidara
null+****@clear*****
Mon Feb 10 13:12:41 JST 2014
Yoji Shidara 2014-02-10 13:12:41 +0900 (Mon, 10 Feb 2014) New Revision: 88828c1b2d47968651c5949b96dd46bc3872bb04 https://github.com/droonga/droonga.org/commit/88828c1b2d47968651c5949b96dd46bc3872bb04 Message: ja: Follow upstream update Added files: _po/ja/tutorial/plugin-development/adapter/index.po Modified files: ja/tutorial/plugin-development/adapter/index.md Added: _po/ja/tutorial/plugin-development/adapter/index.po (+765 -0) 100644 =================================================================== --- /dev/null +++ _po/ja/tutorial/plugin-development/adapter/index.po 2014-02-10 13:12:41 +0900 (b857aca) @@ -0,0 +1,765 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-11-20 22:17+0900\n" +"PO-Revision-Date: 2014-02-10 13:08+0900\n" +"Last-Translator: Droonga Project <droonga �� groonga.org>\n" +"Language-Team: Japanese\n" +"Language: ja\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +msgid "" +"---\n" +"title: \"Plugin: Modify requests and responses\"\n" +"layout: en\n" +"---" +msgstr "" +"---\n" +"title: \"プラグイン: リクエストとレスポンスの変更\"\n" +"layout: ja\n" +"---" + +msgid "" +"* TOC\n" +"{:toc}" +msgstr "" + +msgid "## The goal of this tutorial" +msgstr "" + +msgid "Learning steps to develop a Droonga plugin by yourself." +msgstr "" + +msgid "" +"This page focuses on the adaption phase for Droonga plugins.\n" +"At the last, wraps up them to make a small practical plugin named `store-searc" +"h`, for the adaption phase." +msgstr "" + +msgid "## Precondition" +msgstr "" + +msgid "* You must complete the [basic tutorial][]." +msgstr "" + +msgid "## Adaption for incoming messages" +msgstr "" + +msgid "" +"First, let's study basics with a simple logger plugin named `sample-logger` af" +"fects on the adaption phase." +msgstr "" + +msgid "" +"We sometime need to modify incoming requests from outside to Droonga Engine.\n" +"We can use a plugin for this purpose.\n" +"Let's see how to create a plugin for the adaption phase, in this section." +msgstr "" + +msgid "### Directory Structure" +msgstr "" + +msgid "" +"Assume that we are going to add a new plugin to the system built in the [basic" +" tutorial][].\n" +"In that tutorial, Groonga engine was placed under `engine` directory." +msgstr "" + +msgid "" +"Plugins need to be placed in an appropriate directory. Let's create the direct" +"ory:" +msgstr "" + +msgid "" +"~~~\n" +"# cd engine\n" +"# mkdir -p lib/droonga/plugins\n" +"~~~" +msgstr "" + +msgid "After creating the directory, the directory structure should be like this:" +msgstr "" + +msgid "" +"~~~\n" +"engine\n" +"├── catalog.json\n" +"├── fluentd.conf\n" +"└── lib\n" +" └── droonga\n" +" └── plugins\n" +"~~~" +msgstr "" + +msgid "### Create a plugin" +msgstr "" + +msgid "" +"You must put codes for a plugin into a file which has the name *same to the pl" +"ugin itself*.\n" +"Because the plugin now you creating is `sample-logger`, put codes into a file " +"`sample-logger.rb` in the `droonga/plugins` directory." +msgstr "" + +msgid "lib/droonga/plugins/sample-logger.rb:" +msgstr "" + +msgid "" +"~~~ruby\n" +"require \"droonga/plugin\"" +msgstr "" + +msgid "" +"module Droonga\n" +" module Plugins\n" +" module SampleLoggerPlugin\n" +" Plugin.registry.register(\"sample-logger\", self)" +msgstr "" + +msgid "" +" class Adapter < Droonga::Adapter\n" +" # You'll put codes to modify messages here.\n" +" end\n" +" end\n" +" end\n" +"end\n" +"~~~" +msgstr "" + +msgid "This plugin does nothing except registering itself to Droonga." +msgstr "" + +msgid "" +" * The `sample-logger` is the name of the plugin itself. You'll use it in your" +" `catalog.json`, to activate the plugin.\n" +" * As the example above, you must define your plugin as a module." +msgstr "" + +msgid "### Activate the plugin with `catalog.json`" +msgstr "" + +msgid "" +"You need to update `catalog.json` to activate your plugin.\n" +"Insert the name of the plugin `\"sample-logger\"` to the `\"plugins\"` list under " +"the dataset, like:" +msgstr "" + +msgid "catalog.json:" +msgstr "" + +msgid "" +"~~~\n" +"(snip)\n" +" \"datasets\": {\n" +" \"Starbucks\": {\n" +" (snip)\n" +" \"plugins\": [\"sample-logger\", \"groonga\", \"crud\", \"search\"],\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "" +"Note: you must place `\"sample-logger\"` before `\"search\"`, because the `sample-" +"logger` plugin depends on the `search`. Droonga Engine applies plugins on the " +"adaption phase in the order defined in the `catalog.json`, so you must resolve" +" plugin dependencies by your hand (for now)." +msgstr "" + +msgid "### Run" +msgstr "" + +msgid "" +"Let's Droonga get started.\n" +"Note that you need to specify `./lib` directory in `RUBYLIB` environment varia" +"ble in order to make ruby possible to find your plugin." +msgstr "" + +msgid "" +"~~~\n" +"# kill $(cat fluentd.pid)\n" +"# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluen" +"td.pid\n" +"~~~" +msgstr "" + +msgid "### Test" +msgstr "" + +msgid "" +"In the [basic tutorial][], we have communicated with the Droonga Engine based " +"on `fluent-plugin-droonga`, via the Protocol Adapter built with `expres-droong" +"a`. For plugin development, sending requests directly to the Droonga Engine ca" +"n be more handy way to debug.\n" +"We use `fluent-cat` command for this purpose." +msgstr "" + +msgid "Doing in this way also help us to understand internal structure of Droonga." +msgstr "" + +msgid "" +"In the [basic tutorial][], we have used `fluent-cat` to setup database schema " +"and import data. Do you remember? Sending search request can be done in the si" +"milar way." +msgstr "" + +msgid "First, create a request as a JSON." +msgstr "" + +msgid "search-columbus.json:" +msgstr "" + +msgid "" +"~~~json\n" +"{\n" +" \"id\" : \"search:0\",\n" +" \"dataset\" : \"Starbucks\",\n" +" \"type\" : \"search\",\n" +" \"replyTo\" : \"localhost:24224/output\",\n" +" \"body\" : {\n" +" \"queries\" : {\n" +" \"stores\" : {\n" +" \"source\" : \"Store\",\n" +" \"condition\" : {\n" +" \"query\" : \"Columbus\",\n" +" \"matchTo\" : \"_key\"\n" +" },\n" +" \"output\" : {\n" +" \"elements\" : [\n" +" \"startTime\",\n" +" \"elapsedTime\",\n" +" \"count\",\n" +" \"attributes\",\n" +" \"records\"\n" +" ],\n" +" \"attributes\" : [\"_key\"],\n" +" \"limit\" : -1\n" +" }\n" +" }\n" +" }\n" +" }\n" +"}\n" +"~~~" +msgstr "" + +msgid "" +"This is corresponding to the example to search \"Columbus\" in the [basic tutori" +"al][]. Note that the request for the Protocol Adapter is encapsulated in `\"bod" +"y\"` element." +msgstr "" + +msgid "" +"`fluent-cat` expects one line per one JSON object. So we need to use `tr` comm" +"and to remove line breaks before passing the JSON to `fluent-cat`:" +msgstr "" + +msgid "" +"~~~\n" +"# cat search-columbus.json | tr -d \"\n" +"\" | fluent-cat starbucks.message\n" +"~~~" +msgstr "" + +msgid "This will output something like below to fluentd's log in `fluentd.log`:" +msgstr "" + +msgid "" +"~~~\n" +"2014-02-03 14:22:54 +0900 output.message: {\"inReplyTo\":\"search:0\",\"statusCode\"" +":200,\"type\":\"search.result\",\"body\":{\"stores\":{\"count\":2,\"records\":[[\"2 Columbu" +"s Ave. - New York NY (W)\"],[\"Columbus @ 67th - New York NY (W)\"]]}}}\n" +"~~~" +msgstr "" + +msgid "This is the search result." +msgstr "" + +msgid "If you have [jq][] installed, you can use `jq` instead of `tr`:" +msgstr "" + +msgid "" +"~~~\n" +"# jq -c . search-columbus.json | fluent-cat starbucks.message\n" +"~~~" +msgstr "" + +msgid "### Do something in the plugin: take logs" +msgstr "" + +msgid "" +"The plugin we have created do nothing so far. Let's get the plugin to do some " +"interesting." +msgstr "" + +msgid "First of all, trap `search` request and log it. Update the plugin like below:" +msgstr "" + +msgid "" +"~~~ruby\n" +"(snip)\n" +" module SampleLoggerPlugin\n" +" Plugin.registry.register(\"sample-logger\", self)" +msgstr "" + +msgid "" +" class Adapter < Droonga::Adapter\n" +" message.input_pattern = [\"type\", :equal, \"search\"]" +msgstr "" + +msgid "" +" def adapt_input(input_message)\n" +" $log.info(\"SampleLoggerPlugin::Adapter\", :message => input_message)\n" +" end\n" +" end\n" +" end\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "Restart fluentd:" +msgstr "" + +msgid "Send the request same as the previous:" +msgstr "" + +msgid "You will see something like below fluentd's log in `fluentd.log`:" +msgstr "" + +msgid "" +"~~~\n" +"2014-02-03 16:56:27 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droong" +"a::InputMessage:0x007ff36a38cb28 @raw_message={\"body\"=>{\"queries\"=>{\"stores\"=>" +"{\"output\"=>{\"limit\"=>-1, \"attributes\"=>[\"_key\"], \"elements\"=>[\"startTime\", \"el" +"apsedTime\", \"count\", \"attributes\", \"records\"]}, \"condition\"=>{\"matchTo\"=>\"_key" +"\", \"query\"=>\"Columbus\"}, \"source\"=>\"Store\"}}}, \"replyTo\"=>{\"type\"=>\"search.res" +"ult\", \"to\"=>\"localhost:24224/output\"}, \"type\"=>\"search\", \"dataset\"=>\"Starbucks" +"\", \"id\"=>\"search\"}>\n" +"2014-02-03 16:56:27 +0900 output.message: {\"inReplyTo\":\"search\",\"statusCode\":2" +"00,\"type\":\"search.result\",\"body\":{\"stores\":{\"count\":2,\"records\":[[\"2 Columbus " +"Ave. - New York NY (W)\"],[\"Columbus @ 67th - New York NY (W)\"]]}}}\n" +"~~~" +msgstr "" + +msgid "" +"This shows the message is received by our `SampleLoggerPlugin::Adapter` and th" +"en passed to Droonga. Here we can modify the message before the actual data pr" +"ocessing." +msgstr "" + +msgid "### Modify messages with the plugin" +msgstr "" + +msgid "" +"Suppose that we want to restrict the number of records returned in the respons" +"e, say `1`. What we need to do is set `limit` to be `1` for every request. Upd" +"ate plugin like below:" +msgstr "" + +msgid "" +"~~~ruby\n" +"(snip)\n" +" def adapt_input(input_message)\n" +" $log.info(\"SampleLoggerPlugin::Adapter\", :message => input_message)\n" +" input_message.body[\"queries\"][\"stores\"][\"output\"][\"limit\"] = 1\n" +" end\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "" +"After restart, the response always includes only one record in `records` secti" +"on." +msgstr "" + +msgid "" +"~~~\n" +"2014-02-03 18:47:54 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droong" +"a::InputMessage:0x007f913ca6e918 @raw_message={\"body\"=>{\"queries\"=>{\"stores\"=>" +"{\"output\"=>{\"limit\"=>-1, \"attributes\"=>[\"_key\"], \"elements\"=>[\"startTime\", \"el" +"apsedTime\", \"count\", \"attributes\", \"records\"]}, \"condition\"=>{\"matchTo\"=>\"_key" +"\", \"query\"=>\"Columbus\"}, \"source\"=>\"Store\"}}}, \"replyTo\"=>{\"type\"=>\"search.res" +"ult\", \"to\"=>\"localhost:24224/output\"}, \"type\"=>\"search\", \"dataset\"=>\"Starbucks" +"\", \"id\"=>\"search\"}>\n" +"2014-02-03 18:47:54 +0900 output.message: {\"inReplyTo\":\"search\",\"statusCode\":2" +"00,\"type\":\"search.result\",\"body\":{\"stores\":{\"count\":2,\"records\":[[\"2 Columbus " +"Ave. - New York NY (W)\"]]}}}\n" +"~~~" +msgstr "" + +msgid "" +"Note that `count` is still `2` because `limit` does not affect to `count`. See" +" [search][] for details of the `search` command." +msgstr "" + +msgid "## Adaption for outgoing messages" +msgstr "" + +msgid "" +"In case we need to modify outgoing messages from Droonga Engine, for example, " +"search results, then we can do it simply by another method.\n" +"In this section, we are going to define a method to adapt outgoing messages." +msgstr "" + +msgid "### Add a method to adapt outgoing messages" +msgstr "" + +msgid "" +"Let's take logs of results of `search` command.\n" +"Define the `adapt_output` method to process outgoing messages, like below:" +msgstr "" + +msgid "" +" class Adapter < Droonga::Adapter\n" +" (snip)" +msgstr "" + +msgid "" +" def adapt_output(output_message)\n" +" $log.info(\"SampleLoggerPlugin::Adapter\", :message => output_message)" +"\n" +" end\n" +" end\n" +" end\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "Let's restart fluentd:" +msgstr "" + +msgid "" +"And send search request (Use the same JSON for request as in the previous sect" +"ion):" +msgstr "" + +msgid "The fluentd's log should be like as follows:" +msgstr "" + +msgid "" +"~~~\n" +"2014-02-05 17:37:37 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droong" +"a::OutputMessage:0x007f8da265b698 @raw_message={\"body\"=>{\"stores\"=>{\"count\"=>2" +", \"records\"=>[[\"2 Columbus Ave. - New York NY (W)\"], [\"Columbus @ 67th - New " +"York NY (W)\"]]}}, \"replyTo\"=>{\"type\"=>\"search.result\", \"to\"=>\"localhost:24224" +"/output\"}, \"type\"=>\"search\", \"dataset\"=>\"Starbucks\", \"id\"=>\"search\"}>\n" +"2014-02-05 17:37:37 +0900 output.message: {\"inReplyTo\":\"search\",\"statusCode\":2" +"00,\"type\":\"search.result\",\"body\":{\"stores\":{\"count\":2,\"records\":[[\"2 Columbus " +"Ave. - New York NY (W)\"],[\"Columbus @ 67th - New York NY (W)\"]]}}}\n" +"~~~" +msgstr "" + +msgid "" +"This shows that the result of `search` is passed to the `adapt_output` method " +"(and logged), then outputted." +msgstr "" + +msgid "### Modify results in the adaption phase" +msgstr "" + +msgid "" +"Let's modify the result.\n" +"For example, add `completedAt` attribute that shows the time completed the req" +"uest.\n" +"Update your plugin as follows:" +msgstr "" + +msgid "" +"~~~ruby\n" +"(snip)\n" +" def adapt_output(output_message)\n" +" $log.info(\"SampleLoggerPlugin::Adapter\", :message => output_message)" +"\n" +" output_message.body[\"stores\"][\"completedAt\"] = Time.now\n" +" end\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "Send the same search request:" +msgstr "" + +msgid "The results in `fluentd.log` will be like this:" +msgstr "" + +msgid "" +"~~~\n" +"2014-02-05 17:41:02 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droong" +"a::OutputMessage:0x007fb3c5291fc8 @raw_message={\"body\"=>{\"stores\"=>{\"count\"=>2" +", \"records\"=>[[\"2 Columbus Ave. - New York NY (W)\"], [\"Columbus @ 67th - New " +"York NY (W)\"]]}}, \"replyTo\"=>{\"type\"=>\"search.result\", \"to\"=>\"localhost:24224" +"/output\"}, \"type\"=>\"search\", \"dataset\"=>\"Starbucks\", \"id\"=>\"search\"}>\n" +"2014-02-05 17:41:02 +0900 output.message: {\"inReplyTo\":\"search\",\"statusCode\":2" +"00,\"type\":\"search.result\",\"body\":{\"stores\":{\"count\":2,\"records\":[[\"2 Columbus " +"Ave. - New York NY (W)\"],[\"Columbus @ 67th - New York NY (W)\"]],\"completedAt" +"\":\"2014-02-05T08:41:02.824361Z\"}}}\n" +"~~~" +msgstr "" + +msgid "" +"Now you can see `completedAt` attribute containing the time completed the requ" +"est." +msgstr "" + +msgid "## Translation for both incoming and outgoing messages" +msgstr "" + +msgid "" +"We have learned the basics of plugins for the adaption phase so far.\n" +"Let's try to build more practical plugin." +msgstr "" + +msgid "" +"You may feel the Droonga's `search` command is too flexible for your purpose.\n" +"Here, we're going to add our own `storeSearch` command to wrap the `search` co" +"mmand in order to provide an application-specific and simple interface, with a" +" new plugin named `store-search`." +msgstr "" + +msgid "### Accept simple requests" +msgstr "" + +msgid "" +"First, create the `store-searach` plugin. Remember, you must put codes into a " +"file which has the name same to the plugin now you are creating. So, the file " +"is `store-search.rb` in the `droonga/plugins` directory. Then define your `Sto" +"reSearchPlugin` as follows:" +msgstr "" + +msgid "lib/droonga/plugins/store-search.rb:" +msgstr "" + +msgid "" +"module Droonga\n" +" module Plugins\n" +" module StoreSearchPlugin\n" +" Plugin.registry.register(\"store-search\", self)" +msgstr "" + +msgid "" +" class Adapter < Droonga::Adapter\n" +" message.input_pattern = [\"type\", :equal, \"storeSearch\"]" +msgstr "" + +msgid "" +" def adapt_input(input_message)\n" +" $log.info(\"StoreSearchPlugin::Adapter\", :message => input_message)" +msgstr "" + +msgid "" +" query = input_message.body[\"query\"]\n" +" $log.info(\"storeSearch\", :query => query)" +msgstr "" + +msgid "" +" body = {\n" +" \"queries\" => {\n" +" \"stores\" => {\n" +" \"source\" => \"Store\",\n" +" \"condition\" => {\n" +" \"query\" => query,\n" +" \"matchTo\" => \"_key\",\n" +" },\n" +" \"output\" => {\n" +" \"elements\" => [\n" +" \"startTime\",\n" +" \"elapsedTime\",\n" +" \"count\",\n" +" \"attributes\",\n" +" \"records\",\n" +" ],\n" +" \"attributes\" => [\n" +" \"_key\",\n" +" ],\n" +" \"limit\" => -1,\n" +" }\n" +" }\n" +" }\n" +" }" +msgstr "" + +msgid "" +" input_message.command = \"search\"\n" +" input_message.body = body\n" +" end\n" +" end\n" +" end\n" +" end\n" +"end\n" +"~~~" +msgstr "" + +msgid "" +"Then update catalog.json to activate the plugin. Remove the `sample-logger` pl" +"ugin previously created." +msgstr "" + +msgid "" +"~~~\n" +"(snip)\n" +" \"datasets\": {\n" +" \"Starbucks\": {\n" +" (snip)\n" +" \"plugins\": [\"store-search\", \"groonga\", \"crud\", \"search\"],\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "" +"Remember, you must place your plugin `\"store-search\"` before the `\"search\"` be" +"cause yours depends on it." +msgstr "" + +msgid "Now you can use this new command by the following request:" +msgstr "" + +msgid "store-search-columbus.json:" +msgstr "" + +msgid "" +"~~~json\n" +"{\n" +" \"id\" : \"storeSearch:0\",\n" +" \"dataset\" : \"Starbucks\",\n" +" \"type\" : \"storeSearch\",\n" +" \"replyTo\" : \"localhost:24224/output\",\n" +" \"body\" : {\n" +" \"query\" : \"Columbus\"\n" +" }\n" +"}\n" +"~~~" +msgstr "" + +msgid "In order to issue this request, you need to run:" +msgstr "" + +msgid "" +"~~~\n" +"# cat store-search-columbus.json | tr -d \"\n" +"\" | fluent-cat starbucks.message\n" +"~~~" +msgstr "" + +msgid "And you will see the result on fluentd's log in `fluentd.log`:" +msgstr "" + +msgid "" +"~~~\n" +"2014-02-06 15:20:07 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga" +"::InputMessage:0x00000002a0de38 @raw_message={\"id\"=>\"storeSearch:0\", \"dataset\"" +"=>\"Starbucks\", \"type\"=>\"storeSearch\", \"replyTo\"=>{\"type\"=>\"storeSearch.result\"" +", \"to\"=>\"localhost:24224/output\"}, \"body\"=>{\"query\"=>\"Columbus\"}, \"appliedAdap" +"ters\"=>[]}>\n" +"2014-02-06 15:20:07 +0900 [info]: storeSearch query=\"Columbus\"\n" +"2014-02-06 15:20:07 +0900 output.message: {\"inReplyTo\":\"storeSearch:0\",\"status" +"Code\":200,\"type\":\"storeSearch.result\",\"body\":{\"stores\":{\"count\":2,\"records\":[[" +"\"2 Columbus Ave. - New York NY (W)\"],[\"Columbus @ 67th - New York NY (W)\"]]}" +"}}\n" +"~~~" +msgstr "" + +msgid "Now we can perform store search with simple requests." +msgstr "" + +msgid "" +"Note: look at the `\"type\"` of the response message. Now it became `\"storeSearc" +"h.result\"`, from `\"search.result\"`. Because it is triggered from the incoming " +"message with the type `\"storeSearch\"`, the outgoing message has the type `\"(in" +"coming command).result\"` automatically. In other words, you don't have to chan" +"ge the type of the outgoing messages, like `input_message.command = \"search\"` " +"in the method `adapt_input`." +msgstr "" + +msgid "### Return simple response" +msgstr "" + +msgid "" +"Second, let's return results in more simple way: just an array of the names of" +" stores." +msgstr "" + +msgid "Define the `adapt_output` method as follows." +msgstr "" + +msgid "" +"~~~ruby\n" +"(snip)\n" +" module StoreSearchPlugin\n" +" Plugin.registry.register(\"store-search\", self)" +msgstr "" + +msgid "" +" def adapt_output(output_message)\n" +" $log.info(\"StoreSearchPlugin::Adapter\", :message => output_message)" +msgstr "" + +msgid "" +" records = output_message.body[\"stores\"][\"records\"]\n" +" simplified_results = records.flatten" +msgstr "" + +msgid "" +" output_message.body = simplified_results\n" +" end\n" +" end\n" +" end\n" +"(snip)\n" +"~~~" +msgstr "" + +msgid "" +"The `adapt_output` method receives outgoing messages only corresponding to the" +" incoming messages processed by the `adapt_input` method." +msgstr "" + +msgid "Send the request:" +msgstr "" + +msgid "The log in `fluentd.log` will be like this:" +msgstr "" + +msgid "" +"~~~\n" +"2014-02-06 16:04:45 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga" +"::InputMessage:0x00000002a0de38 @raw_message={\"id\"=>\"storeSearch:0\", \"dataset\"" +"=>\"Starbucks\", \"type\"=>\"storeSearch\", \"replyTo\"=>{\"type\"=>\"storeSearch.result\"" +", \"to\"=>\"localhost:24224/output\"}, \"body\"=>{\"query\"=>\"Columbus\"}, \"appliedAdap" +"ters\"=>[]}>\n" +"2014-02-06 16:04:45 +0900 [info]: storeSearch query=\"Columbus\"\n" +"2014-02-06 16:04:45 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga" +"::OutputMessage:0x00000002a34a88 @raw_message={\"id\"=>\"storeSearch:0\", \"dataset" +"\"=>\"Starbucks\", \"type\"=>\"search\", \"replyTo\"=>{\"type\"=>\"storeSearch.result\", \"t" +"o\"=>\"localhost:24224/output\"}, \"body\"=>{\"stores\"=>{\"count\"=>2, \"records\"=>[[\"2" +" Columbus Ave. - New York NY (W)\"], [\"Columbus @ 67th - New York NY (W)\"]]}}" +", \"appliedAdapters\"=>[\"Droonga::Plugins::StoreSearchPlugin::Adapter\", \"Droonga" +"::Plugins::Error::Adapter\"], \"originalTypes\"=>[\"storeSearch\"]}>\n" +"2014-02-06 16:04:45 +0900 output.message: {\"inReplyTo\":\"storeSearch:0\",\"status" +"Code\":200,\"type\":\"storeSearch.result\",\"body\":[\"2 Columbus Ave. - New York NY " +"(W)\",\"Columbus @ 67th - New York NY (W)\"]}\n" +"~~~" +msgstr "" + +msgid "Now you've got the simplified response." +msgstr "" + +msgid "" +"In the way just described, we can use adapter to implement the application spe" +"cific search logic." +msgstr "" + +msgid "## Conclusion" +msgstr "" + +msgid "" +"We have learned how to create an addon working around the adaption phase, how " +"to receive and modify messages, both of incoming and outgoing." +msgstr "" + +msgid "" +" [basic tutorial]: ../../basic/\n" +" [overview]: ../../../overview/\n" +" [jq]: http://stedolan.github.io/jq/\n" +" [search]: ../../../reference/commands/select/" +msgstr "" Modified: ja/tutorial/plugin-development/adapter/index.md (+89 -19) =================================================================== --- ja/tutorial/plugin-development/adapter/index.md 2014-02-10 12:31:14 +0900 (0c288ef) +++ ja/tutorial/plugin-development/adapter/index.md 2014-02-10 13:12:41 +0900 (1960b79) @@ -1,5 +1,5 @@ --- -title: "Plugin: Modify requests and responses" +title: "プラグイン: リクエストとレスポンスの変更" layout: ja --- @@ -42,8 +42,10 @@ In that tutorial, Groonga engine was placed under `engine` directory. Plugins need to be placed in an appropriate directory. Let's create the directory: - # cd engine - # mkdir -p lib/droonga/plugins +~~~ +# cd engine +# mkdir -p lib/droonga/plugins +~~~ After creating the directory, the directory structure should be like this: @@ -110,7 +112,8 @@ Let's Droonga get started. Note that you need to specify `./lib` directory in `RUBYLIB` environment variable in order to make ruby possible to find your plugin. ~~~ -RUBYLIB=./lib fluentd --config fluentd.conf +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid ~~~ ### Test @@ -161,17 +164,23 @@ This is corresponding to the example to search "Columbus" in the [basic tutorial `fluent-cat` expects one line per one JSON object. So we need to use `tr` command to remove line breaks before passing the JSON to `fluent-cat`: - cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ +# cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ -This will output something like below to fluentd's log: +This will output something like below to fluentd's log in `fluentd.log`: - 2014-02-03 14:22:54 +0900 output.message: {"inReplyTo":"search:0","statusCode":200,"type":"search.result","body":{"stores":{"count":2,"records":[["2 Columbus Ave. - New York NY (W)"],["Columbus @ 67th - New York NY (W)"]]}}} +~~~ +2014-02-03 14:22:54 +0900 output.message: {"inReplyTo":"search:0","statusCode":200,"type":"search.result","body":{"stores":{"count":2,"records":[["2 Columbus Ave. - New York NY (W)"],["Columbus @ 67th - New York NY (W)"]]}}} +~~~ This is the search result. If you have [jq][] installed, you can use `jq` instead of `tr`: - jq -c . search-columbus.json | fluent-cat starbucks.message +~~~ +# jq -c . search-columbus.json | fluent-cat starbucks.message +~~~ ### Do something in the plugin: take logs @@ -197,7 +206,20 @@ lib/droonga/plugins/sample-logger.rb: (snip) ~~~ -And restart fluentd, then send the request same as the previous. You will see something like below fluentd's log: +Restart fluentd: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +Send the request same as the previous: + +~~~ +# cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ + +You will see something like below fluentd's log in `fluentd.log`: ~~~ 2014-02-03 16:56:27 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::InputMessage:0x007ff36a38cb28 @raw_message={"body"=>{"queries"=>{"stores"=>{"output"=>{"limit"=>-1, "attributes"=>["_key"], "elements"=>["startTime", "elapsedTime", "count", "attributes", "records"]}, "condition"=>{"matchTo"=>"_key", "query"=>"Columbus"}, "source"=>"Store"}}}, "replyTo"=>{"type"=>"search.result", "to"=>"localhost:24224/output"}, "type"=>"search", "dataset"=>"Starbucks", "id"=>"search"}> @@ -221,7 +243,22 @@ lib/droonga/plugins/sample-logger.rb: (snip) ~~~ -And restart fluentd. After restart, the response always includes only one record in `records` section: +Restart fluentd: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +After restart, the response always includes only one record in `records` section. + +Send the request same as the previous: + +~~~ +# cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ + +You will see something like below fluentd's log in `fluentd.log`: ~~~ 2014-02-03 18:47:54 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::InputMessage:0x007f913ca6e918 @raw_message={"body"=>{"queries"=>{"stores"=>{"output"=>{"limit"=>-1, "attributes"=>["_key"], "elements"=>["startTime", "elapsedTime", "count", "attributes", "records"]}, "condition"=>{"matchTo"=>"_key", "query"=>"Columbus"}, "source"=>"Store"}}}, "replyTo"=>{"type"=>"search.result", "to"=>"localhost:24224/output"}, "type"=>"search", "dataset"=>"Starbucks", "id"=>"search"}> @@ -266,12 +303,15 @@ lib/droonga/plugins/sample-logger.rb: Let's restart fluentd: ~~~ -RUBYLIB=./lib fluentd --config fluentd.conf +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid ~~~ And send search request (Use the same JSON for request as in the previous section): - cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ +# cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ The fluentd's log should be like as follows: @@ -300,8 +340,20 @@ lib/droonga/plugins/sample-logger.rb: (snip) ~~~ -Then restart fluentd and send the same search request. -The results will be like this: +Restart fluentd: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +Send the same search request: + +~~~ +# cat search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ + +The results in `fluentd.log` will be like this: ~~~ 2014-02-05 17:41:02 +0900 [info]: SampleLoggerPlugin::Adapter message=#<Droonga::OutputMessage:0x007fb3c5291fc8 @raw_message={"body"=>{"stores"=>{"count"=>2, "records"=>[["2 Columbus Ave. - New York NY (W)"], ["Columbus @ 67th - New York NY (W)"]]}}, "replyTo"=>{"type"=>"search.result", "to"=>"localhost:24224/output"}, "type"=>"search", "dataset"=>"Starbucks", "id"=>"search"}> @@ -390,6 +442,13 @@ catalog.json: Remember, you must place your plugin `"store-search"` before the `"search"` because yours depends on it. +Restart fluentd: + +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + Now you can use this new command by the following request: store-search-columbus.json: @@ -408,9 +467,11 @@ store-search-columbus.json: In order to issue this request, you need to run: - cat store-search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ +# cat store-search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ -And you will see the result on fluentd's log: +And you will see the result on fluentd's log in `fluentd.log`: ~~~ 2014-02-06 15:20:07 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga::InputMessage:0x00000002a0de38 @raw_message={"id"=>"storeSearch:0", "dataset"=>"Starbucks", "type"=>"storeSearch", "replyTo"=>{"type"=>"storeSearch.result", "to"=>"localhost:24224/output"}, "body"=>{"query"=>"Columbus"}, "appliedAdapters"=>[]}> @@ -453,11 +514,20 @@ lib/droonga/plugins/store-search.rb: The `adapt_output` method receives outgoing messages only corresponding to the incoming messages processed by the `adapt_input` method. -Then restart fluentd. Send the request: +Restart fluentd: - cat store-search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ +# kill $(cat fluentd.pid) +# RUBYLIB=./lib fluentd --config fluentd.conf --log fluentd.log --daemon fluentd.pid +~~~ + +Send the request: + +~~~ +# cat store-search-columbus.json | tr -d "\n" | fluent-cat starbucks.message +~~~ -The log will be like this: +The log in `fluentd.log` will be like this: ~~~ 2014-02-06 16:04:45 +0900 [info]: StoreSearchPlugin::Adapter message=#<Droonga::InputMessage:0x00000002a0de38 @raw_message={"id"=>"storeSearch:0", "dataset"=>"Starbucks", "type"=>"storeSearch", "replyTo"=>{"type"=>"storeSearch.result", "to"=>"localhost:24224/output"}, "body"=>{"query"=>"Columbus"}, "appliedAdapters"=>[]}> -------------- next part -------------- HTML����������������������������...Download