From 3871509d1ad06a64c6d0ed6f7f4874cd90596cf7 Mon Sep 17 00:00:00 2001 From: Kevin Moore <kevmoo@google.com> Date: Sat, 17 Oct 2015 11:50:04 -0700 Subject: [PATCH] Migrate server-appengine sample to use pkg/shelf --- CHANGELOG.md | 2 +- lib/generators/server_appengine_data.dart | 155 ++++++++---------- templates/server-appengine/.gitignore | 4 - templates/server-appengine/app.yaml | 7 +- templates/server-appengine/bin/server.dart | 130 ++++++++------- .../build/web/{usage.html => index.html} | 0 templates/server-appengine/lib/memcache.dart | 31 ++-- templates/server-appengine/pubspec.yaml | 2 + 8 files changed, 163 insertions(+), 168 deletions(-) rename templates/server-appengine/build/web/{usage.html => index.html} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68a7ab4..492f65d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # CHANGELOG ## 0.2.4 -- Improved layout of `server-appengine` +- Migrated `server-appengine` to use `shelf`. ## 0.2.3+1 - Fixed an issue with the Polymer template diff --git a/lib/generators/server_appengine_data.dart b/lib/generators/server_appengine_data.dart index 62a520b..9bce3bb 100644 --- a/lib/generators/server_appengine_data.dart +++ b/lib/generators/server_appengine_data.dart @@ -5,8 +5,7 @@ const List<String> data = const [ ".gitignore", "text", - """LmJ1aWxkbG9nCi5EU19TdG9yZQouaWRlYQoucGFja2FnZXMKLnB1Yi8KYnVpbGQvCnBhY2thZ2Vz -CnB1YnNwZWMubG9jawo=""", + "LnBhY2thZ2VzCi5wdWIvCnBhY2thZ2VzCnB1YnNwZWMubG9jawo=", "CHANGELOG.md", "text", """IyBDaGFuZ2Vsb2cKCiMjIDAuMC4xCgotIEluaXRpYWwgdmVyc2lvbiwgY3JlYXRlZCBieSBTdGFn @@ -51,63 +50,54 @@ bmQgaG93IHRvIHVzZSB0aGUgcHJlY29uZmlndXJlZCBBcHAgRW5naW5lIG1lbWNhY2hlIEFQSSBz ZXJ2aWNlLgo=""", "app.yaml", "text", - """dmVyc2lvbjogdjEKcnVudGltZTogY3VzdG9tCnZtOiB0cnVlCmFwaV92ZXJzaW9uOiAxCnRocmVh -ZHNhZmU6IHRydWUKCm1hbnVhbF9zY2FsaW5nOgogIGluc3RhbmNlczogMQo=""", + """IyBJbmZvcm1hdGlvbiBvbiBjb25maWd1cmluZyBhcHAueWFtbAojIGh0dHBzOi8vY2xvdWQuZ29v +Z2xlLmNvbS9hcHBlbmdpbmUvZG9jcy9tYW5hZ2VkLXZtcy9jb25maWcKcnVudGltZTogY3VzdG9t +CnZtOiB0cnVlCmFwaV92ZXJzaW9uOiAxCg==""", "bin/server.dart", "text", """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKaW1wb3J0ICdk -YXJ0OmFzeW5jJzsKaW1wb3J0ICdkYXJ0OmlvJzsKCmltcG9ydCAncGFja2FnZTphcHBlbmdpbmUv -YXBwZW5naW5lLmRhcnQnOwppbXBvcnQgJ3BhY2thZ2U6e3twcm9qZWN0TmFtZX19L21lbWNhY2hl -LmRhcnQnIGFzIGNhY2hlOwoKLy8vIEFwcGxpY2F0aW9uIGVudHJ5cG9pbnQgY2FsbGVkIGJ5IEFw -cEVuZ2luZSBhdCBzdGFydHVwLgptYWluKCkgewogIC8vIFNldHVwIEFwcEVuZ2luZSBhbmQgcmVn -aXN0ZXIgYW4gSFRUUCByZXF1ZXN0IGhhbmRsZXIuCiAgcnVuQXBwRW5naW5lKHJlcXVlc3RIYW5k -bGVyKTsKfQoKLy8vIFRoZSBtYWluIEhUVFAgcmVxdWVzdCBoYW5kbGVyLgp2b2lkIHJlcXVlc3RI -YW5kbGVyKEh0dHBSZXF1ZXN0IHJlcXVlc3QpIHsKICAvLyBJbml0aWFsaXplIHRoZSBhcHBsaWNh -dGlvbi4gVGhpcyBpcyBkb25lIGhlcmUgc2luY2Ugd2UgY2FuIG9ubHkgYWNjZXNzCiAgLy8gdGhl -IEFwcEVuZ2luZSBBUElzIHdoZW4gaW4gdGhlIGNvbnRleHQgb2YgYSByZXF1ZXN0LiBUbyBhdm9p -ZCBpbml0aWFsaXppbmcKICAvLyBhbiBhbHJlYWR5IGluaXRpYWxpemVkIGFwcCBpdCBpcyBndWFy -ZGVkIGJ5IHRoZSBbY2FjaGVJbml0aWFsaXplZF0gYm9vbC4KICB2YXIgaW5pdGlhbGl6ZWQgPSBu -ZXcgRnV0dXJlLnN5bmMoY2FjaGUuaW5pdGlhbGl6ZSk7CgogIGluaXRpYWxpemVkLnRoZW4oKF8p -IHsKICAgIC8vIFdlIG9ubHkgaGFuZGxlIEdFVCByZXF1ZXN0cyBpbiB0aGlzIHNpbXBsZSBleGFt -cGxlLgogICAgaWYgKHJlcXVlc3QubWV0aG9kID09ICdHRVQnKSB7CiAgICAgIGhhbmRsZUdldFJl -cXVlc3QocmVxdWVzdCk7CiAgICB9IGVsc2UgewogICAgICByZXF1ZXN0LnJlc3BvbnNlCiAgICAg -ICAgLi5zdGF0dXNDb2RlID0gSHR0cFN0YXR1cy5NRVRIT0RfTk9UX0FMTE9XRUQKICAgICAgICAu -LndyaXRlKCdVbnN1cHBvcnRlZCBIVFRQIHJlcXVlc3QgbWV0aG9kOiAke3JlcXVlc3QubWV0aG9k -fS4nKQogICAgICAgIC4uY2xvc2UoKTsKICAgIH0KICB9KS5jYXRjaEVycm9yKChfKSA9PiByZXF1 -ZXN0LnJlc3BvbnNlCiAgICAuLndyaXRlKCdGYWlsZWQgaGFuZGxpbmcgcmVxdWVzdDogJHtyZXF1 -ZXN0LnRvU3RyaW5nKCl9LicpCiAgICAuLmNsb3NlKCkpOwp9CgovLy8gR0VUIHJlcXVlc3QgaGFu -ZGxlci4KLy8vCi8vLyBQYXJzZXMgdGhlIHVybCB0byBkZXRlcm1pbmUgd2hhdCBjb21tYW5kIHRv -IHJ1biBhbmQgdGhlIGNvcnJlc3BvbmRpbmcKLy8vIGlucHV0IGRhdGEuCmhhbmRsZUdldFJlcXVl -c3QoSHR0cFJlcXVlc3QgcmVxdWVzdCkgewogIEh0dHBSZXNwb25zZSByZXNwb25zZSA9IHJlcXVl -c3QucmVzcG9uc2U7CiAgLy8gRGV0ZXJtaW5lIGNvbW1hbmQuCiAgaWYgKHJlcXVlc3QudXJpLnBh -dGggPT0gJy93cml0ZV9jYWNoZScpIHsKICAgIC8vIEdldCB0aGUgcGFyc2VkIHF1ZXJ5IHN0cmlu -Zy4KICAgIE1hcDxTdHJpbmcsIFN0cmluZz4gcXVlcnlNYXAgPSByZXF1ZXN0LnVyaS5xdWVyeVBh -cmFtZXRlcnM7CiAgICAvLyBVcGRhdGUgdGhlIGNhY2hlIHdpdGggdGhlIGdpdmVuIGtleS92YWx1 -ZSBwYWlycy4KICAgIHJlc3BvbnNlLndyaXRlbG4oJ1VwZGF0aW5nIGNhY2hlIHdpdGggJHtxdWVy -eU1hcC5sZW5ndGh9IHZhbHVlKHMpLicpOwogICAgcmVzcG9uc2Uud3JpdGVsbignJyk7CiAgICBj -YWNoZS53cml0ZShyZXNwb25zZSwgcXVlcnlNYXApOwogIH0gZWxzZSBpZiAocmVxdWVzdC51cmku -cGF0aCA9PSAnL3JlYWRfY2FjaGUnKSB7CiAgICAvLyBJZiBubyBxdWVyeSBzdHJpbmcgaXMgZ2l2 -ZW4gcmV0dXJuIHRoZSBkZWZhdWx0IGtleSdzIHZhbHVlLgogICAgaWYgKCFyZXF1ZXN0LnVyaS5o -YXNRdWVyeSkgewogICAgICByZXNwb25zZS53cml0ZWxuKCdSZWFkaW5nIGRlZmF1bHQgdmFsdWUs -IHNpbmNlIG5vIGtleXMgcHJvdmlkZWQuJyk7CiAgICAgIHJlc3BvbnNlLndyaXRlbG4oJycpOwog -ICAgICBjYWNoZS5yZWFkKHJlc3BvbnNlLCBbY2FjaGUuREVGQVVMVF9LRVldKTsKICAgICAgcmV0 -dXJuOwogICAgfQogICAgLy8gR2V0IHRoZSBwYXJzZWQgcXVlcnkgc3RyaW5nLgogICAgTWFwPFN0 -cmluZywgU3RyaW5nPiBxdWVyeU1hcCA9IHJlcXVlc3QudXJpLnF1ZXJ5UGFyYW1ldGVyczsKICAg -IC8vIFJlYWQgb3V0IHRoZSB2YWx1ZXMgY29ycmVzcG9uZGluZyB0byB0aGUga2V5cyBpbiB0aGUg -cXVlcnkgc3RyaW5nLgogICAgcmVzcG9uc2Uud3JpdGVsbignUmVhZGluZyAke3F1ZXJ5TWFwLmxl -bmd0aH0gdmFsdWUocykgZnJvbSBjYWNoZS4nKTsKICAgIHJlc3BvbnNlLndyaXRlbG4oJycpOwog -ICAgY2FjaGUucmVhZChyZXNwb25zZSwgcXVlcnlNYXAua2V5cyk7CiAgfSBlbHNlIGlmIChyZXF1 -ZXN0LnVyaS5wYXRoID09ICcvY2xlYXJfY2FjaGUnKSB7CiAgICAvLyBSZWludGlhbGl6ZSB0aGUg -Y2FjaGUuIFRoaXMgY2xlYXJzIGFsbCB2YWx1ZXMgYW5kIHJlc2V0cyB0aGUgZGVmYXVsdC4KICAg -IGNhY2hlCiAgICAgICAgLmNsZWFyKCkKICAgICAgICAudGhlbigoXykgPT4gcmVzcG9uc2Uud3Jp -dGVsbignQ2xlYXJlZCBjYWNoZSEnKSkKICAgICAgICAud2hlbkNvbXBsZXRlKHJlc3BvbnNlLmNs -b3NlKTsKICB9IGVsc2UgewogICAgLy8gU2VydmUgc29tZSBzdGF0aWMgY29udGVudC4gVGhpcyBt -dXN0IGJlIGxvY2F0ZWQgaW4gJ2J1aWxkL3dlYicgb3Igc29tZQogICAgLy8gc3ViZGlyZWN0b3J5 -IG9mICdidWlsZC93ZWInLgogICAgY29udGV4dC5hc3NldHMuc2VydmUoJy91c2FnZS5odG1sJyk7 -CiAgfQp9Cg==""", - "build/web/usage.html", +YXJ0OmFzeW5jJzsKCmltcG9ydCAncGFja2FnZTpzaGVsZi9zaGVsZi5kYXJ0JzsKaW1wb3J0ICdw +YWNrYWdlOnNoZWxmX2FwcGVuZ2luZS9zaGVsZl9hcHBlbmdpbmUuZGFydCcgYXMgc2hlbGZfYWU7 +CmltcG9ydCAncGFja2FnZTp7e3Byb2plY3ROYW1lfX0vbWVtY2FjaGUuZGFydCcgYXMgY2FjaGU7 +CgovLy8gQXBwbGljYXRpb24gZW50cnkgcG9pbnQgY2FsbGVkIGJ5IEFwcEVuZ2luZSBhdCBzdGFy +dHVwLgptYWluKExpc3Q8U3RyaW5nPiBhcmdzKSBhc3luYyB7CiAgdmFyIHBvcnRBcmdzID0gYXJn +cy53aGVyZSgoYSkgPT4gYS5zdGFydHNXaXRoKCctLXBvcnQ9JykpLnRvTGlzdCgpOwoKICBpbnQg +cG9ydCA9IDgwODA7CiAgaWYgKHBvcnRBcmdzLmxlbmd0aCA9PSAxKSB7CiAgICB2YXIgcG9ydEFy +ZyA9IHBvcnRBcmdzLnNpbmdsZS5zdWJzdHJpbmcoNyk7CiAgICBwb3J0ID0gaW50LnBhcnNlKHBv +cnRBcmcpOwogIH0KCiAgdmFyIGNhc2NhZGUgPSBuZXcgQ2FzY2FkZSgpLmFkZChfaGFuZGxlciku +YWRkKHNoZWxmX2FlLmFzc2V0SGFuZGxlcigKICAgICAgZGlyZWN0b3J5SW5kZXhTZXJ2ZU1vZGU6 +IHNoZWxmX2FlLkRpcmVjdG9yeUluZGV4U2VydmVNb2RlLlNFUlZFKSk7CgogIGF3YWl0IHNoZWxm +X2FlLnNlcnZlKGNhc2NhZGUuaGFuZGxlciwgcG9ydDogcG9ydCk7Cn0KCkZ1dHVyZTxSZXNwb25z +ZT4gX2hhbmRsZXIoUmVxdWVzdCByZXF1ZXN0KSBhc3luYyB7CiAgYXdhaXQgY2FjaGUuaW5pdGlh +bGl6ZSgpOwoKICBpZiAocmVxdWVzdC5tZXRob2QgIT0gIkdFVCIpIHsKICAgIHJldHVybiBuZXcg +UmVzcG9uc2UuZm9yYmlkZGVuKAogICAgICAgICdVbnN1cHBvcnRlZCBIVFRQIHJlcXVlc3QgbWV0 +aG9kOiAke3JlcXVlc3QubWV0aG9kfScpOwogIH0KCiAgaWYgKHJlcXVlc3QudXJsLnBhdGhTZWdt +ZW50cy5sZW5ndGggPT0gMSkgewogICAgc3dpdGNoIChyZXF1ZXN0LnVybC5wYXRoU2VnbWVudHMu +c2luZ2xlKSB7CiAgICAgIGNhc2UgJ3dyaXRlX2NhY2hlJzoKICAgICAgICByZXR1cm4gX3dyaXRl +Q2FjaGUocmVxdWVzdC51cmwucXVlcnlQYXJhbWV0ZXJzKTsKICAgICAgY2FzZSAncmVhZF9jYWNo +ZSc6CiAgICAgICAgcmV0dXJuIF9yZWFkQ2FjaGUocmVxdWVzdC51cmwucXVlcnlQYXJhbWV0ZXJz +KTsKICAgICAgY2FzZSAnY2xlYXJfY2FjaGUnOgogICAgICAgIHJldHVybiBfY2xlYXIoKTsKICAg +IH0KICB9CgogIHJldHVybiBuZXcgUmVzcG9uc2Uubm90Rm91bmQoJ3NvcnJ5Li4uJyk7Cn0KCkZ1 +dHVyZTxSZXNwb25zZT4gX3JlYWRDYWNoZShNYXA8U3RyaW5nLCBTdHJpbmc+IHBhcmFtZXRlcnMp +IGFzeW5jIHsKICB2YXIga2V5cyA9IHBhcmFtZXRlcnMua2V5cy50b0xpc3QoKTsKCiAgdmFyIG91 +dHB1dCA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKCiAgaWYgKGtleXMuaXNFbXB0eSkgewogICAgb3V0 +cHV0LndyaXRlbG4oCiAgICAgICAgJ1JlYWRpbmcgZGVmYXVsdCBrZXkgKCR7Y2FjaGUuREVGQVVM +VF9LRVl9KSwgc2luY2Ugbm8ga2V5cyBwcm92aWRlZC4nKTsKICAgIG91dHB1dC53cml0ZWxuKCcn +KTsKICAgIGtleXMgPSBjb25zdCBbY2FjaGUuREVGQVVMVF9LRVldOwogIH0gZWxzZSB7CiAgICBv +dXRwdXQud3JpdGVsbignUmVhZGluZyAke3BhcmFtZXRlcnMubGVuZ3RofSB2YWx1ZShzKSBmcm9t +IGNhY2hlLicpOwogICAgb3V0cHV0LndyaXRlbG4oJycpOwogIH0KCiAgYXdhaXQgY2FjaGUucmVh +ZChrZXlzLCBvdXRwdXQpOwoKICByZXR1cm4gbmV3IFJlc3BvbnNlLm9rKG91dHB1dC50b1N0cmlu +ZygpKTsKfQoKRnV0dXJlPFJlc3BvbnNlPiBfd3JpdGVDYWNoZShNYXA8U3RyaW5nLCBTdHJpbmc+ +IHBhcmFtZXRlcnMpIGFzeW5jIHsKICB2YXIgb3V0cHV0ID0gbmV3IFN0cmluZ0J1ZmZlcigpOwoK +ICAvLyBVcGRhdGUgdGhlIGNhY2hlIHdpdGggdGhlIGdpdmVuIGtleS92YWx1ZSBwYWlycy4KICBv +dXRwdXQud3JpdGVsbignVXBkYXRpbmcgY2FjaGUgd2l0aCAke3BhcmFtZXRlcnMubGVuZ3RofSB2 +YWx1ZShzKS4nKTsKICBvdXRwdXQud3JpdGVsbignJyk7CgogIGF3YWl0IGNhY2hlLndyaXRlKHBh +cmFtZXRlcnMsIG91dHB1dCk7CgogIHJldHVybiBuZXcgUmVzcG9uc2Uub2sob3V0cHV0LnRvU3Ry +aW5nKCkpOwp9CgpGdXR1cmU8UmVzcG9uc2U+IF9jbGVhcigpIGFzeW5jIHsKICBhd2FpdCBjYWNo +ZS5jbGVhcigpOwogIHJldHVybiBuZXcgUmVzcG9uc2Uub2soJ0NsZWFyZWQgY2FjaGUhJyk7Cn0K""", + "build/web/index.html", "text", """PCFET0NUWVBFIGh0bWw+Cgo8aHRtbD4KICA8aGVhZD4KICAJPG1ldGEgY2hhcnNldD0idXRmLTgi PgogICAgPHRpdGxlPnt7cHJvamVjdE5hbWV9fTwvdGl0bGU+CiAgPC9oZWFkPgoKICA8Ym9keT4K @@ -126,39 +116,38 @@ aW5pdGlhbCBrZXkvdmFsdWUgcGFpci4KICAgIDwvcHJlPgogIDwvYm9keT4KPC9odG1sPgo=""", """Ly8gQ29weXJpZ2h0IChjKSB7e3llYXJ9fSwge3thdXRob3J9fS4gQWxsIHJpZ2h0cyByZXNlcnZl ZC4gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUKLy8gaXMgZ292ZXJuZWQgYnkgYSBCU0Qtc3R5bGUg bGljZW5zZSB0aGF0IGNhbiBiZSBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlLgoKbGlicmFyeSB7 -e3Byb2plY3ROYW1lfX0ubWVtY2FjaGU7CgppbXBvcnQgJ2RhcnQ6YXN5bmMnOwppbXBvcnQgJ2Rh -cnQ6aW8nOwoKaW1wb3J0ICdwYWNrYWdlOmFwcGVuZ2luZS9hcHBlbmdpbmUuZGFydCc7Cgpjb25z -dCBTdHJpbmcgREVGQVVMVF9LRVkgPSAnaGVsbG8nOwpib29sIGNhY2hlSW5pdGlhbGl6ZWQgPSBm -YWxzZTsKCi8vLyBJbml0aWFsaXplIHRoZSBjYWNoZS4KRnV0dXJlIGluaXRpYWxpemUoKSBhc3lu -YyB7CiAgLy8gSWYgdGhlIGNhY2hlIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQsIGp1c3QgcmV0dXJu -LgogIGlmIChjYWNoZUluaXRpYWxpemVkKSByZXR1cm47CgogIC8vIFRoZSBBcHBFbmdpbmUgZW52 -aXJvbm1lbnQgaGFzIGEgcHJlY29uZmlndXJlZCAnY29udGV4dCcgd2hpY2ggcHJvdmlkZXMKICAv -LyBhdXRob3JpemVkIGFjY2VzcyB0byB0aGUgZGVmYXVsdCBhcGkgc2VydmljZXMuCiAgdmFyIG1l -bWNhY2hlID0gY29udGV4dC5zZXJ2aWNlcy5tZW1jYWNoZTsKCiAgLy8gSW5pdGlhbGl6ZSB0aGUg -Y2FjaGUgYW5kIHNldCB0aGUgZGVmYXVsdCB2YWx1ZS4KICBhd2FpdCBtZW1jYWNoZS5jbGVhcigp -OwogIGF3YWl0IG1lbWNhY2hlLnNldChERUZBVUxUX0tFWSwgJ3RoZXJlIScpOwogIGNhY2hlSW5p -dGlhbGl6ZWQgPSB0cnVlOwp9CgovLy8gQ2xlYXJzIHRoZSBjYWNoZSBhbmQgcmVzZXRzIHRoZSBk -ZWZhdWx0LgpGdXR1cmUgY2xlYXIoKSBhc3luYyB7CiAgY2FjaGVJbml0aWFsaXplZCA9IGZhbHNl -OwogIGF3YWl0IGluaXRpYWxpemUoKTsKfQoKLy8vIEhlbHBlciBtZXRob2QgdG8gd3JpdGUgYSBz -ZXQgb2Yga2V5L3ZhbHVlIHBhaXJzIHRvIHRoZSBtZW1jYWNoZS4Kdm9pZCB3cml0ZShIdHRwUmVz -cG9uc2UgcmVzcG9uc2UsIE1hcDxTdHJpbmcsIFN0cmluZz4gdmFsdWVNYXApIHsKICB2YXIgbWVt -Y2FjaGUgPSBjb250ZXh0LnNlcnZpY2VzLm1lbWNhY2hlOwogIEZ1dHVyZS5mb3JFYWNoKHZhbHVl -TWFwLmtleXMsIChrZXkpIHsKICAgIHZhciB2YWx1ZSA9IHZhbHVlTWFwW2tleV07CiAgICByZXR1 -cm4gbWVtY2FjaGUKICAgICAgICAuc2V0KGtleSwgdmFsdWUpCiAgICAgICAgLnRoZW4oKF8pID0+ -IHJlc3BvbnNlLndyaXRlbG4oJyIke2tleX0iOiAiJHt2YWx1ZX0iJykpOwogIH0pLndoZW5Db21w -bGV0ZShyZXNwb25zZS5jbG9zZSk7Cn0KCi8vLyBIZWxwZXIgbWV0aG9kIHRvIHJlYWQgYSBzZXQg -b2YgdmFsdWVzIGZyb20gdGhlIG1lbWNhY2hlLgp2b2lkIHJlYWQoSHR0cFJlc3BvbnNlIHJlc3Bv -bnNlLCBJdGVyYWJsZTxTdHJpbmc+IGtleXMpIHsKICB2YXIgbWVtY2FjaGUgPSBjb250ZXh0LnNl -cnZpY2VzLm1lbWNhY2hlOwogIHZhciBoYW5kbGVLZXkgPSAoa2V5KSA9PiBtZW1jYWNoZQogICAg -ICAuZ2V0KGtleSkKICAgICAgLnRoZW4oKHZhbHVlKSA9PiByZXNwb25zZS53cml0ZWxuKCciJHtr -ZXl9IjogIiR7dmFsdWV9IicpKQogICAgICAuY2F0Y2hFcnJvcigoXykgPT4gcmVzcG9uc2Uud3Jp -dGVsbignIiR7a2V5fSI6IHZhbHVlIG5vdCBmb3VuZCEnKSk7CiAgRnV0dXJlLmZvckVhY2goa2V5 -cywgaGFuZGxlS2V5KS53aGVuQ29tcGxldGUocmVzcG9uc2UuY2xvc2UpOwp9Cg==""", +e3Byb2plY3ROYW1lfX0ubWVtY2FjaGU7CgppbXBvcnQgJ2RhcnQ6YXN5bmMnOwoKaW1wb3J0ICdw +YWNrYWdlOmFwcGVuZ2luZS9hcHBlbmdpbmUuZGFydCc7Cgpjb25zdCBTdHJpbmcgREVGQVVMVF9L +RVkgPSAnaGVsbG8nOwpib29sIGNhY2hlSW5pdGlhbGl6ZWQgPSBmYWxzZTsKCi8vLyBJbml0aWFs +aXplIHRoZSBjYWNoZS4KRnV0dXJlIGluaXRpYWxpemUoKSBhc3luYyB7CiAgLy8gSWYgdGhlIGNh +Y2hlIGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQsIGp1c3QgcmV0dXJuLgogIGlmIChjYWNoZUluaXRp +YWxpemVkKSByZXR1cm47CgogIC8vIFRoZSBBcHBFbmdpbmUgZW52aXJvbm1lbnQgaGFzIGEgcHJl +Y29uZmlndXJlZCAnY29udGV4dCcgd2hpY2ggcHJvdmlkZXMKICAvLyBhdXRob3JpemVkIGFjY2Vz +cyB0byB0aGUgZGVmYXVsdCBhcGkgc2VydmljZXMuCiAgdmFyIG1lbWNhY2hlID0gY29udGV4dC5z +ZXJ2aWNlcy5tZW1jYWNoZTsKCiAgLy8gSW5pdGlhbGl6ZSB0aGUgY2FjaGUgYW5kIHNldCB0aGUg +ZGVmYXVsdCB2YWx1ZS4KICBhd2FpdCBtZW1jYWNoZS5jbGVhcigpOwogIGF3YWl0IG1lbWNhY2hl +LnNldChERUZBVUxUX0tFWSwgJ3RoZXJlIScpOwogIGNhY2hlSW5pdGlhbGl6ZWQgPSB0cnVlOwp9 +CgovLy8gQ2xlYXJzIHRoZSBjYWNoZSBhbmQgcmVzZXRzIHRoZSBkZWZhdWx0LgpGdXR1cmUgY2xl +YXIoKSBhc3luYyB7CiAgY2FjaGVJbml0aWFsaXplZCA9IGZhbHNlOwogIGF3YWl0IGluaXRpYWxp +emUoKTsKfQoKLy8vIEhlbHBlciBtZXRob2QgdG8gd3JpdGUgYSBzZXQgb2Yga2V5L3ZhbHVlIHBh +aXJzIHRvIHRoZSBtZW1jYWNoZS4KRnV0dXJlIHdyaXRlKE1hcDxTdHJpbmcsIFN0cmluZz4gdmFs +dWVNYXAsIFN0cmluZ1NpbmsgYnVmZmVyKSBhc3luYyB7CiAgdmFyIG1lbWNhY2hlID0gY29udGV4 +dC5zZXJ2aWNlcy5tZW1jYWNoZTsKCiAgZm9yICh2YXIga2V5IGluIHZhbHVlTWFwLmtleXMpIHsK +ICAgIHZhciB2YWx1ZSA9IHZhbHVlTWFwW2tleV07CgogICAgYXdhaXQgbWVtY2FjaGUuc2V0KGtl +eSwgdmFsdWUpOwoKICAgIGJ1ZmZlci53cml0ZWxuKCcke2tleX06ICR7RXJyb3Iuc2FmZVRvU3Ry +aW5nKHZhbHVlKX0nKTsKICB9Cn0KCi8vLyBIZWxwZXIgbWV0aG9kIHRvIHJlYWQgYSBzZXQgb2Yg +dmFsdWVzIGZyb20gdGhlIG1lbWNhY2hlLgpGdXR1cmUgcmVhZChJdGVyYWJsZTxTdHJpbmc+IGtl +eXMsIFN0cmluZ1NpbmsgYnVmZmVyICkgYXN5bmMgewogIHZhciBtZW1jYWNoZSA9IGNvbnRleHQu +c2VydmljZXMubWVtY2FjaGU7CgogIGZvciAodmFyIGtleSBpbiBrZXlzKSB7CiAgICB0cnkgewog +ICAgICB2YXIgdmFsdWUgPSBhd2FpdCBtZW1jYWNoZS5nZXQoa2V5KTsKICAgICAgYnVmZmVyLndy +aXRlbG4oJyR7a2V5fTogJHtFcnJvci5zYWZlVG9TdHJpbmcodmFsdWUpfScpOwogICAgfSBjYXRj +aCAoXykgewogICAgICBidWZmZXIud3JpdGVsbignIiR7a2V5fSI6IGVycm9yIHJlYWRpbmcga2V5 +IScpOwogICAgfQogIH0KfQo=""", "pubspec.yaml", "text", """bmFtZToge3twcm9qZWN0TmFtZX19CnZlcnNpb246IDAuMC4xCmRlc2NyaXB0aW9uOiBBIHNpbXBs ZSBBcHAgRW5naW5lIGFwcGxpY2F0aW9uLgojYXV0aG9yOiB7e2F1dGhvcn19IDxlbWFpbEBleGFt cGxlLmNvbT4KI2hvbWVwYWdlOiBodHRwczovL3d3dy5leGFtcGxlLmNvbQoKZW52aXJvbm1lbnQ6 CiAgc2RrOiAnPj0xLjkuMCA8Mi4wLjAnCgpkZXBlbmRlbmNpZXM6CiAgYXBwZW5naW5lOiAnPj0w -LjMuMCA8MC40LjAnCg==""" +LjMuMCA8MC40LjAnCiAgc2hlbGY6IF4wLjYuMAogIHNoZWxmX2FwcGVuZ2luZTogXjAuMi4zCg==""" ]; diff --git a/templates/server-appengine/.gitignore b/templates/server-appengine/.gitignore index 8afd37e..4232a2f 100644 --- a/templates/server-appengine/.gitignore +++ b/templates/server-appengine/.gitignore @@ -1,8 +1,4 @@ -.buildlog -.DS_Store -.idea .packages .pub/ -build/ packages pubspec.lock diff --git a/templates/server-appengine/app.yaml b/templates/server-appengine/app.yaml index 7c562fb..63f4d16 100644 --- a/templates/server-appengine/app.yaml +++ b/templates/server-appengine/app.yaml @@ -1,8 +1,5 @@ -version: v1 +# Information on configuring app.yaml +# https://cloud.google.com/appengine/docs/managed-vms/config runtime: custom vm: true api_version: 1 -threadsafe: true - -manual_scaling: - instances: 1 diff --git a/templates/server-appengine/bin/server.dart b/templates/server-appengine/bin/server.dart index a2557f2..ebc5908 100644 --- a/templates/server-appengine/bin/server.dart +++ b/templates/server-appengine/bin/server.dart @@ -2,76 +2,82 @@ // is governed by a BSD-style license that can be found in the LICENSE file. import 'dart:async'; -import 'dart:io'; -import 'package:appengine/appengine.dart'; +import 'package:shelf/shelf.dart'; +import 'package:shelf_appengine/shelf_appengine.dart' as shelf_ae; import 'package:{{projectName}}/memcache.dart' as cache; -/// Application entrypoint called by AppEngine at startup. -main() { - // Setup AppEngine and register an HTTP request handler. - runAppEngine(requestHandler); +/// Application entry point called by AppEngine at startup. +main(List<String> args) async { + var portArgs = args.where((a) => a.startsWith('--port=')).toList(); + + int port = 8080; + if (portArgs.length == 1) { + var portArg = portArgs.single.substring(7); + port = int.parse(portArg); + } + + var cascade = new Cascade().add(_handler).add(shelf_ae.assetHandler( + directoryIndexServeMode: shelf_ae.DirectoryIndexServeMode.SERVE)); + + await shelf_ae.serve(cascade.handler, port: port); } -/// The main HTTP request handler. -void requestHandler(HttpRequest request) { - // Initialize the application. This is done here since we can only access - // the AppEngine APIs when in the context of a request. To avoid initializing - // an already initialized app it is guarded by the [cacheInitialized] bool. - var initialized = new Future.sync(cache.initialize); - - initialized.then((_) { - // We only handle GET requests in this simple example. - if (request.method == 'GET') { - handleGetRequest(request); - } else { - request.response - ..statusCode = HttpStatus.METHOD_NOT_ALLOWED - ..write('Unsupported HTTP request method: ${request.method}.') - ..close(); +Future<Response> _handler(Request request) async { + await cache.initialize(); + + if (request.method != "GET") { + return new Response.forbidden( + 'Unsupported HTTP request method: ${request.method}'); + } + + if (request.url.pathSegments.length == 1) { + switch (request.url.pathSegments.single) { + case 'write_cache': + return _writeCache(request.url.queryParameters); + case 'read_cache': + return _readCache(request.url.queryParameters); + case 'clear_cache': + return _clear(); } - }).catchError((_) => request.response - ..write('Failed handling request: ${request.toString()}.') - ..close()); + } + + return new Response.notFound('sorry...'); } -/// GET request handler. -/// -/// Parses the url to determine what command to run and the corresponding -/// input data. -handleGetRequest(HttpRequest request) { - HttpResponse response = request.response; - // Determine command. - if (request.uri.path == '/write_cache') { - // Get the parsed query string. - Map<String, String> queryMap = request.uri.queryParameters; - // Update the cache with the given key/value pairs. - response.writeln('Updating cache with ${queryMap.length} value(s).'); - response.writeln(''); - cache.write(response, queryMap); - } else if (request.uri.path == '/read_cache') { - // If no query string is given return the default key's value. - if (!request.uri.hasQuery) { - response.writeln('Reading default value, since no keys provided.'); - response.writeln(''); - cache.read(response, [cache.DEFAULT_KEY]); - return; - } - // Get the parsed query string. - Map<String, String> queryMap = request.uri.queryParameters; - // Read out the values corresponding to the keys in the query string. - response.writeln('Reading ${queryMap.length} value(s) from cache.'); - response.writeln(''); - cache.read(response, queryMap.keys); - } else if (request.uri.path == '/clear_cache') { - // Reintialize the cache. This clears all values and resets the default. - cache - .clear() - .then((_) => response.writeln('Cleared cache!')) - .whenComplete(response.close); +Future<Response> _readCache(Map<String, String> parameters) async { + var keys = parameters.keys.toList(); + + var output = new StringBuffer(); + + if (keys.isEmpty) { + output.writeln( + 'Reading default key (${cache.DEFAULT_KEY}), since no keys provided.'); + output.writeln(''); + keys = const [cache.DEFAULT_KEY]; } else { - // Serve some static content. This must be located in 'build/web' or some - // subdirectory of 'build/web'. - context.assets.serve('/usage.html'); + output.writeln('Reading ${parameters.length} value(s) from cache.'); + output.writeln(''); } + + await cache.read(keys, output); + + return new Response.ok(output.toString()); +} + +Future<Response> _writeCache(Map<String, String> parameters) async { + var output = new StringBuffer(); + + // Update the cache with the given key/value pairs. + output.writeln('Updating cache with ${parameters.length} value(s).'); + output.writeln(''); + + await cache.write(parameters, output); + + return new Response.ok(output.toString()); +} + +Future<Response> _clear() async { + await cache.clear(); + return new Response.ok('Cleared cache!'); } diff --git a/templates/server-appengine/build/web/usage.html b/templates/server-appengine/build/web/index.html similarity index 100% rename from templates/server-appengine/build/web/usage.html rename to templates/server-appengine/build/web/index.html diff --git a/templates/server-appengine/lib/memcache.dart b/templates/server-appengine/lib/memcache.dart index 4e97eae..e9574d7 100644 --- a/templates/server-appengine/lib/memcache.dart +++ b/templates/server-appengine/lib/memcache.dart @@ -4,7 +4,6 @@ library {{projectName}}.memcache; import 'dart:async'; -import 'dart:io'; import 'package:appengine/appengine.dart'; @@ -33,22 +32,28 @@ Future clear() async { } /// Helper method to write a set of key/value pairs to the memcache. -void write(HttpResponse response, Map<String, String> valueMap) { +Future write(Map<String, String> valueMap, StringSink buffer) async { var memcache = context.services.memcache; - Future.forEach(valueMap.keys, (key) { + + for (var key in valueMap.keys) { var value = valueMap[key]; - return memcache - .set(key, value) - .then((_) => response.writeln('"${key}": "${value}"')); - }).whenComplete(response.close); + + await memcache.set(key, value); + + buffer.writeln('${key}: ${Error.safeToString(value)}'); + } } /// Helper method to read a set of values from the memcache. -void read(HttpResponse response, Iterable<String> keys) { +Future read(Iterable<String> keys, StringSink buffer ) async { var memcache = context.services.memcache; - var handleKey = (key) => memcache - .get(key) - .then((value) => response.writeln('"${key}": "${value}"')) - .catchError((_) => response.writeln('"${key}": value not found!')); - Future.forEach(keys, handleKey).whenComplete(response.close); + + for (var key in keys) { + try { + var value = await memcache.get(key); + buffer.writeln('${key}: ${Error.safeToString(value)}'); + } catch (_) { + buffer.writeln('"${key}": error reading key!'); + } + } } diff --git a/templates/server-appengine/pubspec.yaml b/templates/server-appengine/pubspec.yaml index 260abc4..f8922e1 100644 --- a/templates/server-appengine/pubspec.yaml +++ b/templates/server-appengine/pubspec.yaml @@ -9,3 +9,5 @@ environment: dependencies: appengine: '>=0.3.0 <0.4.0' + shelf: ^0.6.0 + shelf_appengine: ^0.2.3 -- GitLab